Merge branch 'master' of https://vcs.maemo.org/git/groove
[groove] / playlist.cpp
1 #include "playlist.h"
2
3 playlist::playlist(QObject *parent) :
4     QObject(parent)
5 {
6    manager = new QNetworkAccessManager();
7    this->currentdownloaditem = -1;
8    pList = new QList<songElement *>;
9    this->currentplayingitem = -1;
10    this->currentSkeyItem = -1;
11    this->reply = NULL;
12 }
13 QList<playlist::songElement *>* playlist::getList()
14 {
15     return pList;
16 }
17
18 void playlist::markPlayed(int position)
19 {
20     if(0 <= position && position < pList->size())
21     {
22         pList->at(position)->played = true;
23         this->freeMemory(position);
24     }
25 }
26 void playlist::freeMemory(int position)
27 {
28    pList->at(position)->downloaded = false;
29    pList->at(position)->bufferready = false;
30    delete pList->at(position)->buffer;
31    pList->at(position)->buffer = new QBuffer();
32 }
33 bool playlist::existAt(int position)
34 {
35     if(position < 0)
36         return false;
37     return (pList->size() > position);
38 }
39
40 int playlist::currentplaying()
41 {
42     return this->currentplayingitem;
43 }
44 bool playlist::bReady(int b)
45 {
46     if(pList->size() > b)
47         return pList->at(b)->bufferready;
48     else
49         return false;
50 }
51 void playlist::setBufferRdy(int b)
52 {
53     pList->at(b)->bufferready = true;
54 }
55 void playlist::setCurrentPlaying(int position)
56 {
57     if(this->existAt(position))
58     {
59         this->currentplayingitem = position;
60         if(!pList->at(position)->downloaded && this->currentdownloaditem != this->currentplayingitem)
61             this->beginDownload(position);
62         /*if(pList->at(position)->bufferready == false &&)
63         {
64             if(!pList->at(position)->downloaded)
65                 this->beginDownload(position);
66         }
67         else
68             emit this->bufferReady(position);
69         */
70         return;
71     }
72     else
73     {
74     if(position == -1)
75         {
76         this->currentplayingitem = -1;
77     }
78     else
79         return;
80     }
81 }
82 QIODevice * playlist::getBuffer(int position)
83 {
84     return pList->at(position)->buffer;
85 }
86
87 void playlist::beginDownload(int position)
88 {
89     this->currentdownloaditem = position;
90     qDebug() << "StartDownlaod:" << pList->at(position)->songId;
91     QNetworkRequest req;
92     req.setUrl(*pList->at(currentdownloaditem)->server);
93     qDebug() << pList->at(currentdownloaditem)->server;
94     req.setHeader(req.ContentTypeHeader,QVariant("application/x-www-form-urlencoded"));
95     if(reply)
96     {
97         reply->disconnect();
98         reply->deleteLater();
99     }
100     reply = manager->post(req,QString("streamKey=" + pList->at(this->currentdownloaditem)->streamkey->toAscii()).toAscii());
101     pList->at(this->currentdownloaditem)->buffer->open(QBuffer::ReadWrite | QBuffer::Truncate);
102     connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadSlot(qint64,qint64)));
103     connect(reply,SIGNAL(finished()),this,SLOT(networkReplyFinish()));
104     connect(this,SIGNAL(downloadComplete(int)),this,SLOT(downloadDone(int)));
105     connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(getNError(QNetworkReply::NetworkError)));
106     startStreamT = QTime::currentTime();
107 }
108 void playlist::getNError(QNetworkReply::NetworkError error)
109 {
110     qDebug() << "Network Error (if this is 99 then it will retry" << error;
111     if(error == QNetworkReply::UnknownNetworkError && this->currentdownloaditem != -1)
112         beginDownload(this->currentdownloaditem);
113
114 }
115
116 void playlist::setGscom(gscom *comm)
117 {
118     gs = comm;
119     connect(gs,SIGNAL(sKeyFound()),this,SLOT(skeyFound()));
120 }
121 void playlist::skeyFound()
122 {
123     emit this->freeze(false);
124     pList->at(this->currentSkeyItem)->streamkey = new QString(gs->streamID);
125     pList->at(this->currentSkeyItem)->server = new QUrl(gs->sku);
126     if(this->currentdownloaditem == -1)
127         this->beginDownload(this->currentSkeyItem);
128     else
129         if(this->currentplaying() == this->currentSkeyItem)
130             this->beginDownload(this->currentSkeyItem);
131     this->currentSkeyItem = -1;
132 }
133
134 int playlist::addSong(QStandardItem *item)
135 {
136     playlist::songElement *newelement = new playlist::songElement;
137     newelement->buffer = new QBuffer();
138     newelement->downloaded =false;
139     newelement->songId = new QString(item->text());
140     newelement->played = false;
141     newelement->server = new QUrl();
142     newelement->streamkey = new QString("noneatm");
143     newelement->bufferready = false;
144     newelement->type = playlist::EStream;
145     pList->append(newelement);
146     gs->getSong(item->text());
147
148     this->currentSkeyItem = pList->size()-1;
149     emit this->freeze(true);
150     return pList->size()-1;
151 }
152
153 void playlist::downloadDone(int position)
154 {
155     if(this->existAt(position+1) && this->currentSkeyItem == -1 && !pList->at(position+1)->downloaded && this->currentdownloaditem != position+1)
156         beginDownload(position+1);
157     else
158         this->currentdownloaditem = -1;
159     pList->at(position)->downloaded = true;
160 }
161 void playlist::networkReplyFinish()
162 {
163     qDebug() << "finish";
164     QVariant url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
165     if(url.toUrl().isValid())
166     {
167         QNetworkRequest req;
168         req.setUrl(url.toUrl());
169         qDebug() << url;
170         if(reply)
171         {
172             reply->disconnect();
173             reply->deleteLater();
174         }
175         reply = manager->get(req);
176         startStreamT = QTime::currentTime();
177         //connect(reply,SIGNAL(finished()),this,SLOT(start()));
178         connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadSlot(qint64,qint64)));
179         connect(reply,SIGNAL(finished()),this,SLOT(networkReplyFinish()));
180         connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(getNError(QNetworkReply::NetworkError)));
181     }
182 }
183
184 void playlist::downloadSlot(qint64 b, qint64 t)
185 {
186     //qDebug() << "Download: " << b << "Total: " << t;
187     if(t != 0)
188     {
189         emit this->downloadProgress(this->currentdownloaditem,b,t);
190         if(existAt(this->currentdownloaditem))
191         {
192             pList->at(this->currentdownloaditem)->buffer->buffer().append(reply->readAll());
193             //qDebug() << !pList->at(this->currentdownloaditem)->bufferready << this->currentdownloaditem;
194             if ( b >= t*0.05 && !pList->at(this->currentdownloaditem)->bufferready)
195                 //if(!pList->at(currentdownloaditem)->bufferready && b/(startStreamT.msecsTo(QTime::currentTime()) + 1)*100/1024 >= 10)
196             {
197                 this->setBufferRdy(this->currentdownloaditem);
198                 emit this->bufferReady(this->currentdownloaditem);
199
200                 qDebug() << "Buffer Ready";
201             }
202             if (b==t)
203             {
204             emit this->downloadComplete(this->currentdownloaditem);
205             //emit this->bufferReady(this->currentdownloaditem);
206             }
207         }
208     }
209 }