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