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