Start adding support for playlist and progress on downloading songs
[groove] / gscom.cpp
1 #include "gscom.h"
2 #include <parser.h>
3 #include <serializer.h>
4 #include <QCryptographicHash>
5 //#include <QApplication>
6
7 gscom::gscom()
8 {
9     manager = new QNetworkAccessManager(this);
10     connect(manager, SIGNAL(finished(QNetworkReply*)),
11             this, SLOT(replyFinished(QNetworkReply*)));
12     cookies = manager->cookieJar();
13     currentaction = getPHP;
14     manager->get(QNetworkRequest(QUrl(QString("http://") + GS_LISTEN)));
15     phpSession = new QString("none");
16     sessionKey = new QString("none");
17     firstR = true;
18     model = new QStandardItemModel();
19     model->setHorizontalHeaderLabels(
20         QStringList() << "Online");
21     addDebugMsg("You may now search for a song");
22     addProgressbar("test");
23     //getSessionKey();
24 }
25
26 QStandardItemModel* gscom::getSongModel(QString song)
27 {
28     model = new QStandardItemModel();
29     model->setHorizontalHeaderLabels(
30         QStringList() << "Searching..");
31     addDebugMsg("Fetching Song List...");
32
33     if(currentaction != none)
34     {
35         addDebugMsg("Error: communication is busy Try again later");
36         return model;
37     }
38     else
39     {
40         QString *token = getToken(getSearchResults);
41         qDebug() << token->toAscii();
42         QNetworkRequest request;
43         request.setUrl(QUrl("http://cowbell.grooveshark.com/more.php?getSearchResults"));
44         request.setHeader(request.ContentTypeHeader,QVariant("application/json"));
45         QVariantMap jlist;
46         QVariantMap header;
47         //header.insert("uuid","DEA8E133-2080-F666-4B38-9465187B20A9");
48         header.insert("session",phpSession->toUtf8());
49         header.insert("client","gslite");
50         header.insert("clientRevision","20100412.09");
51         header.insert("token",token->toAscii());
52         jlist.insert("method","getSearchResults");
53         jlist.insertMulti("header",header);
54         QVariantMap param;
55         param.insert("type","Songs");
56         param.insert("query",song.toAscii());
57         jlist.insertMulti("parameters",param);
58         QJson::Serializer *serializer = new QJson::Serializer();
59         //qDebug() << serializer->serialize(jlist);
60         manager->post(request,serializer->serialize(jlist));
61         currentaction = getSearchResults;
62     }
63
64     return model;
65 }
66 QStandardItemModel* gscom::getArtistModel(QString song)
67 {
68     model = new QStandardItemModel();
69     model->setHorizontalHeaderLabels(
70         QStringList() << "Searching..");
71     addDebugMsg("Fetching Song List...");
72
73     if(currentaction != none)
74     {
75         addDebugMsg("Error: communication is busy Try again later");
76         return model;
77     }
78     else
79     {
80         QString *token = getToken(getSearchResults);
81         qDebug() << token->toAscii();
82         QNetworkRequest request;
83         request.setUrl(QUrl("http://cowbell.grooveshark.com/more.php?getSearchResults"));
84         request.setHeader(request.ContentTypeHeader,QVariant("application/json"));
85         QVariantMap jlist;
86         QVariantMap header;
87         //header.insert("uuid","DEA8E133-2080-F666-4B38-9465187B20A9");
88         header.insert("session",phpSession->toUtf8());
89         header.insert("client","gslite");
90         header.insert("clientRevision","20100412.09");
91         header.insert("token",token->toAscii());
92         jlist.insert("method","getSearchResults");
93         jlist.insertMulti("header",header);
94         QVariantMap param;
95         param.insert("type","Artists");
96         param.insert("query",song.toAscii());
97         jlist.insertMulti("parameters",param);
98         QJson::Serializer *serializer = new QJson::Serializer();
99         //qDebug() << serializer->serialize(jlist);
100         manager->post(request,serializer->serialize(jlist));
101         currentaction = getSearchResults;
102     }
103
104     return model;
105 }
106 QStandardItemModel* gscom::getAlbumModel(QString song)
107 {
108     model = new QStandardItemModel();
109     model->setHorizontalHeaderLabels(
110         QStringList() << "Searching..");
111     addDebugMsg("Fetching Song List...");
112
113     if(currentaction != none)
114     {
115         addDebugMsg("Error: communication is busy Try again later");
116         return model;
117     }
118     else
119     {
120         QString *token = getToken(getSearchResults);
121         qDebug() << token->toAscii();
122         QNetworkRequest request;
123         request.setUrl(QUrl("http://cowbell.grooveshark.com/more.php?getSearchResults"));
124         request.setHeader(request.ContentTypeHeader,QVariant("application/json"));
125         QVariantMap jlist;
126         QVariantMap header;
127         //header.insert("uuid","DEA8E133-2080-F666-4B38-9465187B20A9");
128         header.insert("session",phpSession->toUtf8());
129         header.insert("client","gslite");
130         header.insert("clientRevision","20100412.09");
131         header.insert("token",token->toAscii());
132         jlist.insert("method","getSearchResults");
133         jlist.insertMulti("header",header);
134         QVariantMap param;
135         param.insert("type","Albums");
136         param.insert("query",song.toAscii());
137         jlist.insertMulti("parameters",param);
138         QJson::Serializer *serializer = new QJson::Serializer();
139         //qDebug() << serializer->serialize(jlist);
140         manager->post(request,serializer->serialize(jlist));
141         currentaction = getSearchResults;
142     }
143
144     return model;
145 }
146 void gscom::replyFinished(QNetworkReply *reply)
147 {
148     switch (currentaction)
149     {
150     case getStreamKeyFromSongIDEx:
151         {
152             qDebug() << "tester";
153             QJson::Parser parser;
154             bool ok;
155             QVariantMap result = parser.parse (reply->readAll(), &ok).toMap();
156             if (!ok) {
157               qFatal("An error occurred during parsing");
158               return;
159             }
160             QVariantMap results = result["result"].toMap();
161             this->streamID = results["streamKey"].toString();
162             this->sku = QUrl(QString("http://") + results["ip"].toString() + "/stream.php");
163             qDebug() << sku;
164             currentaction = none;
165             reply->close();
166             emit sKeyFound();
167         }
168         break;
169     case getPHP:
170         {
171             QList<QNetworkCookie> cookieList = cookies->cookiesForUrl(QUrl(QString("http://") + GS_LISTEN));
172             foreach(QNetworkCookie cookie, cookieList)
173             {
174                 if(cookie.name() == "PHPSESSID")
175                 {
176                     phpSession = new QString(cookie.value());
177                 }
178             }
179             reply->readAll();
180             reply->close();
181             qDebug() << phpSession->toAscii();
182             firstR = false;
183             currentaction = getCommunicationToken;
184             getSessionKey();
185
186         }
187         break;
188     case getCommunicationToken:
189         {
190             bool ok;
191             QJson::Parser parser;
192             QVariantMap result = parser.parse(reply->readAll(),&ok).toMap();
193             if(!ok)
194                 qDebug("Error parsing request");
195             else
196             {
197                 sessionKey = new QString(result["result"].toString());
198                 qDebug() << sessionKey->toAscii();
199             }
200             currentaction = none;
201             reply->close();
202             emit finishedSearch();
203         }
204         break;
205     case(getSearchResults):
206         {
207             QJson::Parser parser;
208             bool ok;
209             QVariantMap result = parser.parse (reply->readAll(), &ok).toMap();
210             if (!ok) {
211               qFatal("An error occurred during parsing");
212               return;
213             }
214             if(result.contains("fault"))
215             {
216                 currentaction = getPHP;
217                 manager->get(QNetworkRequest(QUrl(QString("http://") + GS_LISTEN)));
218                 qDebug() << reply->readAll();
219                 reply->close();
220                 return;
221             }
222             model->clear();
223             model->setHorizontalHeaderLabels(
224                 QStringList() << "Song"
225                               << "Artist"
226                               << "Song Id");
227
228
229             foreach (QVariant plugin, result["result"].toList()) {
230               QList<QStandardItem *> items;
231               QVariantMap nestedMap = plugin.toMap();
232               items.append(new QStandardItem(nestedMap["Name"].toString()));
233               items.append(new QStandardItem(nestedMap["ArtistName"].toString()));
234               items.append(new QStandardItem(nestedMap["SongID"].toString()));
235               model->appendRow(items);
236             }
237             currentaction = none;
238             reply->close();
239             emit finishedSearch();
240         }
241         break;
242     default:
243         qDebug() << reply->readAll();
244         reply->close();
245         currentaction=none;
246     }
247
248 }
249 QStandardItemModel* gscom::getModel()
250 {
251     return model;
252 }
253 void gscom::addDebugMsg(QString debug)
254 {
255     QList<QStringList> rows = QList<QStringList>()
256         << (QStringList() << debug);
257     foreach (QStringList row, rows) {
258         QList<QStandardItem *> items;
259         foreach (QString text, row)
260             items.append(new QStandardItem(text));
261         model->appendRow(items);
262     }
263     return;
264 }
265 void gscom::addProgressbar(QString debug)
266 {
267     QList<QStringList> rows = QList<QStringList>()
268         << (QStringList() << debug);
269     foreach (QStringList row, rows) {
270         QList<QStandardItem *> items;
271         foreach (QString text, row)
272         {
273             QLinearGradient gradient(0,0,250,0);
274             gradient.setColorAt(0, QColor::fromRgbF(0, 1, 0, 1));
275             gradient.setColorAt(0.9, QColor::fromRgbF(0, 1, 0, 1));
276             gradient.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0));
277             QBrush brush(gradient);
278             QStandardItem *pBar = new QStandardItem(text);
279             pBar->setBackground(brush);
280             pBar->setSelectable(false);
281             items.append(pBar);
282         }
283         model->appendRow(items);
284     }
285     return;
286 }
287 QString* gscom::getToken(gMETHOD meth)
288 {
289     QCryptographicHash *hasher = new QCryptographicHash(QCryptographicHash::Sha1);
290     //generate six random numbers
291     QString rnum =  QString(qrand() %9 + 48)
292                     + QString(qrand() %9 + 48)
293                     + QString(qrand() %9 + 48)
294                     + QString(qrand() %9 + 48)
295                     + QString(qrand() %9 + 48)
296                     + QString(qrand() %9 + 48);
297     QString *data = new QString();
298     QString *string = new QString();
299     switch(meth)
300     {
301     case(getSearchResults):
302         data->append("getSearchResults");
303         break;
304     case(getStreamKeyFromSongIDEx):
305         data->append("getStreamKeyFromSongIDEx");
306         break;
307     default:
308         data->append("getSearchResults");
309     }
310     string->append(data);
311     string->append(":");
312     string->append(sessionKey->toAscii());
313     string->append(":quitStealinMahShit:");
314     string->append(rnum);
315     hasher->addData(string->toAscii());
316     QString *rs = new QString();
317     rs->append(rnum);
318     rs->append(hasher->result().toHex());
319     return rs;
320 }
321 void gscom::getSong(QString songid)
322 {
323     if(currentaction != none)
324     {
325         return;
326     }
327     else
328     {
329         QString *token = getToken(getStreamKeyFromSongIDEx);
330         qDebug() << token->toAscii();
331         QNetworkRequest request;
332         request.setUrl(QUrl("http://cowbell.grooveshark.com/more.php?getStreamKeyFromSongIdEx"));
333         request.setHeader(request.ContentTypeHeader,QVariant("application/json"));
334         QVariantMap jlist;
335         QVariantMap header;
336         //header.insert("uuid","DEA8E133-2080-F666-4B38-9465187B20A9");
337         header.insert("session",phpSession->toUtf8());
338         header.insert("client","gslite");
339         header.insert("clientRevision","20100412.09");
340         header.insert("token",token->toAscii());
341         jlist.insert("method","getStreamKeyFromSongIDEx");
342         jlist.insertMulti("header",header);
343         QVariantMap param;
344         QVariantMap country;
345         country.insert("CC1","0");
346         country.insert("CC3","0");
347         country.insert("ID","223");
348         country.insert("CC2","0");
349         country.insert("CC4","1073741824");
350         param.insertMulti("country",country);
351         param.insert("mobile",false);
352         param.insert("songID",songid.toAscii());
353         param.insert("prefetch",false);
354         jlist.insertMulti("parameters",param);
355         QJson::Serializer *serializer = new QJson::Serializer();
356         //qDebug() << serializer->serialize(jlist);
357         manager->post(request,serializer->serialize(jlist));
358         currentaction = getStreamKeyFromSongIDEx;
359     }
360     return;
361 }
362
363 void gscom::getSessionKey()
364 {
365     QNetworkRequest request; // = new QNetworkRequest(QUrl("https://cowbell.grooveshark.com/service.php"));
366     request.setUrl(QUrl("https://cowbell.grooveshark.com/service.php"));
367     request.setHeader(request.ContentTypeHeader,QVariant("application/json"));
368     QVariantMap jlist;
369     QVariantMap header;
370     //header.insert("uuid","DEA8E133-2080-F666-4B38-9465187B20A9");
371     //header.insert("session",phpSession->toUtf8());
372     header.insert("client","gslite");
373     header.insert("clientRevision","20100412.09");
374     jlist.insert("method","getCommunicationToken");
375     jlist.insertMulti("header",header);
376     QVariantMap param;
377     QCryptographicHash *hasher = new QCryptographicHash(QCryptographicHash::Md5);
378     hasher->addData(phpSession->toUtf8());
379     param.insert("secretKey",hasher->result().toHex());
380     jlist.insertMulti("parameters",param);
381     QJson::Serializer *serializer = new QJson::Serializer();
382     manager->post(request,serializer->serialize(jlist));
383 }