Fixed Lyric Wiki downloader and ShowLyricsPage Flickable contentHeight
[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 "LyricWikiDownloader.h"
22 #include "AZLyricsDownloader.h"
23 #include <curl/curl.h>
24 #include <QDebug>
25 #include <iostream>
26 #include <QFile>
27 #include <QSettings>
28 #include <QtNetwork/QtNetwork>
29 #include <iostream>
30
31 using namespace std;
32
33 /////////////////////////////////////////////////////////////////////////////
34
35 short lyricsDownloader::perform(const string& a, const string& t)
36 {
37     CURLcode dlret; // return value
38     dlret = download(a, t); // it doesn't fail yet to recognize
39
40     if (dlret == -2) return -1; // no internet
41     else if (dlret != 0) return 1; // error downloading
42     //else continues!
43
44     if ( parse() == false)
45     {
46         qDebug() << "Error while parsing lyrics\n";
47         return 2;
48     }
49
50     return 0; // ok
51 }
52
53 CURLcode lyricsDownloader::download(const string& a, const string& t)
54 {
55     QNetworkConfigurationManager manager;
56     QNetworkConfiguration cfg = manager.defaultConfiguration();
57     /*QNetworkSession* session = new QNetworkSession(cfg);
58     session->setSessionProperty("ConnectInBackground", true);
59     session->open();*/
60
61     CURL * handle;
62     CURLcode err;
63     handle = curl_easy_init();
64     if (! handle) return static_cast<CURLcode>(-1);
65     // set verbose if debug on
66     curl_easy_setopt( handle, CURLOPT_VERBOSE, DEBUG );
67     curl_easy_setopt( handle, CURLOPT_URL, toProviderCode(a, t).c_str() ); // set the download url to the generated one
68     curl_easy_setopt(handle, CURLOPT_WRITEDATA, &buff);
69     curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &lyricsDownloader::write_data_to_var); // set the function writing to ostringstream
70     curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); // curl needs to follow redirects with this provider
71     curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1);
72     if (manager.isOnline() == false) return static_cast<CURLcode>(-2);
73     err = curl_easy_perform(handle);
74     curl_easy_cleanup(handle);
75     return err;
76 }
77
78 size_t lyricsDownloader::write_data_to_var(char *ptr, size_t size, size_t nmemb, void *userdata)
79 {
80     ostringstream * stream = (ostringstream*) userdata;
81     size_t count = size * nmemb;
82     stream->write(ptr, count);
83     return count;
84 }
85
86 /////////////////////////////////////////////////////////////////////////
87
88 Settings LyricsDownloaderManager::progSettings;
89 const QString LyricsDownloaderManager::OMPLyricsRoot("/home/user/.lyrics/");
90
91 LyricsDownloaderManager::LyricsDownloaderManager(LyricsDownloaderClass lyricsDownloaderName)
92 {
93     connect(this, SIGNAL(dataChanged()), this, SLOT(cleanTitle()));
94     connect(this, SIGNAL(dataChanged()), this, SLOT(findSavedLyricsKey())); // recalculate the key, so that it's always up-to-date
95
96     currentClass = lyricsDownloaderName;
97     downloader = newDownloader(lyricsDownloaderName);
98 }
99
100 LyricsDownloaderManager::~LyricsDownloaderManager()
101 {
102     delete downloader;
103 }
104
105 void LyricsDownloaderManager::changeLyricsDownloader(LyricsDownloaderClass lyricsDownloaderName)
106 {
107     qDebug() << "Changing lyricsDownloader to " << lyricsDownloaderName << "\n";
108     if (lyricsDownloaderName != currentClass) // we don't need to do the same again if it's the same downloader
109     {
110         lyricsDownloader * oldDownloader = downloader;
111         downloader = newDownloader(lyricsDownloaderName);
112         delete oldDownloader;
113     }
114 }
115
116 lyricsDownloader * LyricsDownloaderManager::newDownloader(LyricsDownloaderClass & name)
117 {
118     switch (name)
119     {
120     case AZLyricsDownloaderClass:
121         return new AZLyricsDownloader;
122         break;
123     case LyricWikiDownloaderClass:
124         return new LyricWikiDownloader;
125         break;
126     }
127 }
128
129 short LyricsDownloaderManager::perform()
130 {
131     short ret = downloader -> perform(artist, track);
132     lyrics = downloader -> lyrics_qstr; // clean it too!
133     downloader -> lyrics_qstr.clear();
134     emit lyricsChanged(lyrics);
135     return ret;
136 }
137
138 void LyricsDownloaderManager::cleanTitle()
139 {
140     cleanedTitle = cleanQString( QString::fromStdString(artist));
141     cleanedTitle += "-";
142     cleanedTitle += cleanQString(QString::fromStdString(track));
143 }
144
145 QString LyricsDownloaderManager::cleanQString(const QString qstr)
146 {
147     return qstr.toLower().replace("&", "and").remove(QRegExp("\\([^)]*\\)")).remove(QRegExp("[\\W_]"));
148 }
149
150 bool LyricsDownloaderManager::lyricsExistOMP()
151 {
152     lyricsUrlOMP = OMPLyricsRoot + cleanedTitle + ".txt";
153     return QFile(lyricsUrlOMP).exists();
154 }
155
156 void LyricsDownloaderManager::saveLyricsMaeLyrica()
157 {
158     Settings().setValue("lyrics/" + cleanedTitle, lyrics);
159 }
160
161 bool LyricsDownloaderManager::saveLyricsOMP()
162 {
163     qDebug() << "Saving to " << lyricsUrlOMP << "\n";
164     QFile lyricsFile(lyricsUrlOMP);
165     if (!lyricsFile.open(QIODevice::WriteOnly | QIODevice::Text)) return false;
166     QTextStream lyricsFileStream(&lyricsFile);
167     lyricsFileStream << lyrics;
168     lyricsFile.close();
169     if (lyricsFile.error() != QFile::NoError) return false;
170     else return true;
171 }
172