Cleaning up QNetworkSession stuff which isn't working0
[maelyrica:maelyrica.git] / lyricsDownloader.cpp
1 /* File: lyricsDownloader.cpp
2  *
3  * This file is part of MaeLyrica.
4  *
5  * Copyright (C) 2012 Marcin Mielniczuk.
6  *
7  * MaeLyrica is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, version 3 of the License.
10  *
11  * MaeLyrica is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  *  along with MaeLyrica.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "lyricsDownloader.h"
21 #include <curl/curl.h>
22 #include <QDebug>
23 #include <iostream>
24 #include <QFile>
25 #include <QSettings>
26 #include <QtNetwork/QtNetwork>
27
28 using namespace std;
29
30 #define DEBUG 1
31
32 /////////////////////////////////////////////////////////////////////////////
33
34 const QString lyricsDownloader::OMPLyricsRoot("/home/user/.lyrics/");
35
36 Settings lyricsDownloader::progSettings;
37
38 inline void lyricsDownloader::setData(const string &a, const string &t)
39 {
40     artist = a;
41     track = t;
42 }
43
44 size_t lyricsDownloader::write_data_to_var(char *ptr, size_t size, size_t nmemb, void *userdata)
45 {
46     ostringstream * stream = (ostringstream*) userdata;
47     size_t count = size * nmemb;
48     stream->write(ptr, count);
49     return count;
50 }
51
52 QString lyricsDownloader::cleanQString(const QString qstr)
53 {
54     return qstr.toLower().replace("&", "and").remove(QRegExp("\\([^)]*\\)")).remove(QRegExp("[\\W_]"));
55 }
56
57 void lyricsDownloader::cleanTitle()
58 {
59     cleanedTitle = cleanQString( QString::fromStdString(artist));
60     cleanedTitle += "-";
61     cleanedTitle += cleanQString(QString::fromStdString(track));
62 }
63
64
65 bool lyricsDownloader::lyricsExistOMP()
66 {
67     lyricsUrlOMP = OMPLyricsRoot + cleanedTitle + ".txt";
68     return QFile(lyricsUrlOMP).exists();
69 }
70
71 void lyricsDownloader::saveLyricsMaeLyrica()
72 {
73     QSettings("Marcin Mielniczuk", "MaeLyrica").setValue("lyrics/" + cleanedTitle, lyrics);
74 }
75
76 bool lyricsDownloader::saveLyricsOMP()
77 {
78     qDebug() << "Saving to " << lyricsUrlOMP << "\n";
79     QFile lyricsFile(lyricsUrlOMP);
80     if (!lyricsFile.open(QIODevice::WriteOnly | QIODevice::Text)) return false;
81     QTextStream lyricsFileStream(&lyricsFile);
82     lyricsFileStream << lyrics;
83     lyricsFile.close();
84     if (lyricsFile.error() != QFile::NoError) return false;
85     else return true;
86 }
87
88 ///////////////////////////////////////////////////////////////////////////////
89
90 const QString AZLyricsDownloader::rooturl("http://azlyrics.com/lyrics");
91 const QRegExp AZLyricsDownloader::endcomment("<!-- end of lyrics -->");
92 const QRegExp AZLyricsDownloader::startcomment("<!-- start of lyrics -->");
93
94
95
96 short AZLyricsDownloader::perform()
97 {
98     CURLcode dlret; // return value from QtNetwork
99     dlret = download(); // it doesn't fail yet to recognize
100
101     if (dlret == -2) return -1;
102
103     if ( parse() == false)
104     {
105         if ( dlret != 0 ) // Error while downloading and parsing means that the lyrics are just not there
106         {
107             qDebug() << "The lyrics are not present in AZLyrics.com database\n";
108             return 3;
109         }
110         qDebug() << "Error while parsing lyrics\n";
111         return 2;
112     }
113     else if (dlret != 0) // just error while downloading
114     {
115         qDebug() << "Error while downloading lyrics\n";
116         return 1;
117     }
118
119     //qDebug() << lyrics();
120     emit lyricsChanged(lyrics);
121     return 0;
122 }
123
124 string AZLyricsDownloader::toProviderCode() const
125 {
126     QString artist_www, track_www;
127     artist_www = QString::fromStdString(artist).toLower().remove(QRegExp("^the")).remove(QRegExp("\\W"));
128     track_www = QString::fromStdString(track).toLower().remove(QRegExp("\\W"));
129
130     return (rooturl + "/" + artist_www + "/" + track_www + ".html").toStdString();
131
132 }
133
134 CURLcode AZLyricsDownloader::download()
135 {
136     QNetworkConfigurationManager manager;
137     QNetworkConfiguration cfg = manager.defaultConfiguration();
138     /*QNetworkSession* session = new QNetworkSession(cfg);
139     session->setSessionProperty("ConnectInBackground", true);
140     session->open();*/
141
142     CURL * handle;
143     CURLcode err;
144     ostringstream buff;
145     handle = curl_easy_init();
146     if (! handle) return static_cast<CURLcode>(-1);
147     // set verbose if debug on
148     curl_easy_setopt( handle, CURLOPT_VERBOSE, DEBUG );
149     curl_easy_setopt( handle, CURLOPT_URL, toProviderCode().c_str() ); // set the download url to the generated one
150     curl_easy_setopt(handle, CURLOPT_WRITEDATA, &buff);
151     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &AZLyricsDownloader::write_data_to_var); // set the function writing to ostringstream
152     curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); // curl needs to follow redirects with this provider
153     curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);
154     if (manager.isOnline() == false) return static_cast<CURLcode>(-2);
155     err = curl_easy_perform(handle);
156     curl_easy_cleanup(handle);
157
158     // copy the contents to text variable
159     lyrics = QString::fromStdString(buff.str());
160     return err;
161
162     /*QNetworkAccessManager * nam = new QNetworkAccessManager(this);
163     qDebug() << "Downloading from " << toProviderCode() << "\n";
164     QNetworkReply * reply = nam->get(QNetworkRequest(toProviderCode().resolved()));
165     QEventLoop loop;
166     QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
167     loop.exec();
168     lyrics = reply->readAll();
169     qDebug() << "read all \n";
170     qDebug() << "reply->readAll = " << reply->readAll();
171     qDebug() << "\n\nlyrics = " << lyrics << "\n";
172     return reply->error();*/
173 }
174
175 bool AZLyricsDownloader::parse()
176 {
177     istringstream temp(lyrics.toStdString());
178     string line;
179     QString lyrics_QStr, line_QStr;
180     while ( temp.good() ) // looking for comment about starting lyrics
181     {
182         getline(temp, line);
183         if (QString::fromStdString(line).contains(startcomment)) break;
184     }
185     if ( !temp.good() ) return false; // something went wrong, returning blank string
186     // get every line until endcomment
187     while ( temp.good() )
188     {
189         getline(temp, line);
190         if (( line_QStr = QString::fromStdString(line) ).contains(endcomment)) break;
191         lyrics_QStr += line_QStr;
192         //lyrics_QStr += line_QStr.remove(QRegExp("<br[ ]{0,1}[/]{0,1}>"));
193         //lyrics_QStr += " \n";
194     }
195     if ( !temp.good() ) return false; // something went wrong, returning blank string
196
197     lyrics = lyrics_QStr; // after parsing all the work will be done using QStrings
198     return true;
199
200     /*qDebug () << "parsing\n";
201     QTextStream temp(&lyrics);
202     QString line;
203
204     lyrics = ""; // clear them
205
206     while(temp.status() == QTextStream::Ok)
207     {
208         line = temp.readLine();
209         //if (line.isNull()) return false;
210         if (temp.status() == QTextStream::ReadPastEnd) return false;
211         qDebug() << "line is: " << line << "\n line.contains(startcomment) = " << line.contains(startcomment) << "\n";
212         if (line.contains(startcomment)) break;
213     }
214     qDebug() << "read start comment\n";
215     if (temp.status() != QTextStream::Ok) return false; // too early eof or corrupt
216
217     while (temp.status() == QTextStream::Ok)
218     {
219         line = temp.readLine();
220         //if (line.isNull()) return false;
221         if (line.contains(endcomment)) break;
222         //lyrics += line.remove(QRegExp("<br[ ]{0,1}[/]{0,1}>"));
223         //lyrics += "\n";
224     }
225     qDebug() << "read end comment\n";
226     if (temp.status() != QTextStream::ReadPastEnd) return false; // too early eof or corrupt
227     return true;*/
228 }