diff --git a/CMakeLists.txt b/CMakeLists.txt index c84fc9b55..d71e0c347 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,8 +160,7 @@ SET( CANTATA_SRCS lyrics/lyricspage.cpp lyrics/lyricsettings.cpp lyrics/ultimatelyricsprovider.cpp - lyrics/ultimatelyricsreader.cpp - lyrics/songinfoprovider.cpp + lyrics/ultimatelyrics.cpp lyrics/lyricsdialog.cpp network/networkaccessmanager.cpp online/onlineservicespage.cpp @@ -229,8 +228,8 @@ SET( CANTATA_MOC_HDRS widgets/toolbar.h lyrics/lyricspage.h lyrics/lyricsettings.h + lyrics/ultimatelyrics.h lyrics/ultimatelyricsprovider.h - lyrics/songinfoprovider.h lyrics/lyricsdialog.h network/networkaccessmanager.h online/onlineservice.h diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 2a66bc35d..c52010c97 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -961,7 +961,7 @@ void MainWindow::mpdConnectionStateChanged(bool connected) emit playListInfo(); emit outputs(); if (CS_Init!=connectedState) { - loaded=loaded&TAB_STREAMS ? TAB_STREAMS : 0; + loaded=(loaded&TAB_STREAMS); currentTabChanged(tabWidget->current_index()); } connectedState=CS_Connected; @@ -971,7 +971,7 @@ void MainWindow::mpdConnectionStateChanged(bool connected) updateWindowTitle(); } } else { - loaded=loaded&TAB_STREAMS ? TAB_STREAMS : 0; + loaded=(loaded&TAB_STREAMS); libraryPage->clear(); albumsPage->clear(); folderPage->clear(); @@ -1101,7 +1101,7 @@ void MainWindow::showPreferencesDialog() } #endif - PreferencesDialog *pref=new PreferencesDialog(this, lyricsPage); + PreferencesDialog *pref=new PreferencesDialog(this); controlConnectionsMenu(false); connect(pref, SIGNAL(settingsSaved()), this, SLOT(updateSettings())); connect(pref, SIGNAL(connectTo(const MPDConnectionDetails &)), this, SLOT(connectToMpd(const MPDConnectionDetails &))); @@ -1270,7 +1270,6 @@ void MainWindow::readSettings() #ifdef ENABLE_DEVICES_SUPPORT StdActions::self()->deleteSongsAction->setVisible(Settings::self()->showDeleteAction()); #endif - lyricsPage->setEnabledProviders(Settings::self()->lyricProviders()); MPDParseUtils::setGroupSingle(Settings::self()->groupSingle()); MPDParseUtils::setGroupMultiple(Settings::self()->groupMultiple()); albumsPage->setView(Settings::self()->albumsView()); diff --git a/gui/preferencesdialog.cpp b/gui/preferencesdialog.cpp index 21c61c0b5..af9cb9b91 100644 --- a/gui/preferencesdialog.cpp +++ b/gui/preferencesdialog.cpp @@ -34,7 +34,6 @@ #include "httpserversettings.h" #endif #include "lyricsettings.h" -#include "lyricspage.h" #include "cachesettings.h" #include "localize.h" #include "mpdconnection.h" @@ -55,7 +54,7 @@ int PreferencesDialog::instanceCount() return iCount; } -PreferencesDialog::PreferencesDialog(QWidget *parent, LyricsPage *lp) +PreferencesDialog::PreferencesDialog(QWidget *parent) : Dialog(parent) { iCount++; @@ -74,8 +73,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, LyricsPage *lp) playback->load(); files->load(); interface->load(); - const QList &lprov=lp->getProviders(); - lyrics->Load(lprov); + lyrics->load(); widget->addPage(server, i18n("Connection"), Icons::libraryIcon, i18n("Connection Settings")); widget->addPage(serverplayback, i18n("Output"), Icons::speakerIcon, i18n("Output Settings")); widget->addPage(playback, i18n("Playback"), Icon("media-playback-start"), i18n("Playback Settings")); @@ -134,7 +132,7 @@ void PreferencesDialog::writeSettings() #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND audiocd->save(); #endif - Settings::self()->saveLyricProviders(lyrics->EnabledProviders()); + lyrics->save(); Settings::self()->save(); emit settingsSaved(); } diff --git a/gui/preferencesdialog.h b/gui/preferencesdialog.h index a2f80bb99..e192ac440 100644 --- a/gui/preferencesdialog.h +++ b/gui/preferencesdialog.h @@ -37,7 +37,6 @@ class PlaybackSettings; class FileSettings; class InterfaceSettings; class LyricSettings; -class LyricsPage; #ifdef TAGLIB_FOUND class HttpServerSettings; #endif @@ -54,7 +53,7 @@ class PreferencesDialog : public Dialog public: static int instanceCount(); - PreferencesDialog(QWidget *parent, LyricsPage *lp); + PreferencesDialog(QWidget *parent); virtual ~PreferencesDialog(); private: diff --git a/lyrics/lyricsettings.cpp b/lyrics/lyricsettings.cpp index 4134474b3..fc1bc0b5e 100644 --- a/lyrics/lyricsettings.cpp +++ b/lyrics/lyricsettings.cpp @@ -22,86 +22,80 @@ */ #include "lyricsettings.h" -//#include "songinfoview.h" #include "ultimatelyricsprovider.h" +#include "ultimatelyrics.h" #include "ui_lyricsettings.h" #include "localize.h" #include "icon.h" #include "config.h" +#include "settings.h" -LyricSettings::LyricSettings(QWidget *parent) - : QWidget(parent), - ui_(new Ui_LyricSettings) +LyricSettings::LyricSettings(QWidget *p) + : QWidget(p) { - ui_->setupUi(this); - - connect(ui_->up, SIGNAL(clicked()), SLOT(MoveUp())); - connect(ui_->down, SIGNAL(clicked()), SLOT(MoveDown())); - connect(ui_->providers, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - SLOT(CurrentItemChanged(QListWidgetItem*))); -// connect(ui_->providers, SIGNAL(itemChanged(QListWidgetItem*)), -// SLOT(ItemChanged(QListWidgetItem*))); - ui_->up->setIcon(Icon("arrow-up")); - ui_->down->setIcon(Icon("arrow-down")); + setupUi(this); + connect(up, SIGNAL(clicked()), SLOT(moveUp())); + connect(down, SIGNAL(clicked()), SLOT(moveDown())); + connect(providers, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + SLOT(currentItemChanged(QListWidgetItem*))); + up->setIcon(Icon("arrow-up")); + down->setIcon(Icon("arrow-down")); } -LyricSettings::~LyricSettings() { - delete ui_; +void LyricSettings::load() +{ + const QList &lprov=UltimateLyrics::self()->getProviders(); + + providers->clear(); + foreach (const UltimateLyricsProvider *provider, lprov) { + QListWidgetItem *item = new QListWidgetItem(providers); + QString name(provider->getName()); + name.replace("(POLISH)", i18n("(Polish Translations)")); + name.replace("(PORTUGUESE)", i18n("(Portuguese Translations)")); + item->setText(name); + item->setData(Qt::UserRole, provider->getName()); + item->setCheckState(provider->isEnabled() ? Qt::Checked : Qt::Unchecked); + } } -void LyricSettings::Load(const QList &providers) { - ui_->providers->clear(); - foreach (const UltimateLyricsProvider* provider, providers) { - QListWidgetItem* item = new QListWidgetItem(ui_->providers); - QString name(provider->name()); - name.replace("(POLISH)", i18n("(Polish Translations)")); - name.replace("(PORTUGUESE)", i18n("(Portuguese Translations)")); - item->setText(name); - item->setData(Qt::UserRole, provider->name()); - item->setCheckState(provider->is_enabled() ? Qt::Checked : Qt::Unchecked); -// item->setForeground(provider->is_enabled() ? palette().color(QPalette::Active, QPalette::Text) -// : palette().color(QPalette::Disabled, QPalette::Text)); - } +void LyricSettings::save() +{ + QStringList enabled; + for (int i=0 ; icount() ; ++i) { + const QListWidgetItem* item = providers->item(i); + if (Qt::Checked==item->checkState()) { + enabled << item->data(Qt::UserRole).toString(); + } + } + UltimateLyrics::self()->setEnabled(enabled); } -QStringList LyricSettings::EnabledProviders() { - QStringList providers; - for (int i=0 ; iproviders->count() ; ++i) { - const QListWidgetItem* item = ui_->providers->item(i); - if (item->checkState() == Qt::Checked) - providers << item->data(Qt::UserRole).toString(); - } - return providers; +void LyricSettings::currentItemChanged(QListWidgetItem *item) +{ + if (!item) { + up->setEnabled(false); + down->setEnabled(false); + } else { + const int row = providers->row(item); + up->setEnabled(row != 0); + down->setEnabled(row != providers->count() - 1); + } } -void LyricSettings::CurrentItemChanged(QListWidgetItem* item) { - if (!item) { - ui_->up->setEnabled(false); - ui_->down->setEnabled(false); - } else { - const int row = ui_->providers->row(item); - ui_->up->setEnabled(row != 0); - ui_->down->setEnabled(row != ui_->providers->count() - 1); - } +void LyricSettings::moveUp() +{ + move(-1); } -void LyricSettings::MoveUp() { - Move(-1); +void LyricSettings::moveDown() +{ + move(+1); } -void LyricSettings::MoveDown() { - Move(+1); +void LyricSettings::move(int d) +{ + const int row = providers->currentRow(); + QListWidgetItem* item = providers->takeItem(row); + providers->insertItem(row + d, item); + providers->setCurrentRow(row + d); } - -void LyricSettings::Move(int d) { - const int row = ui_->providers->currentRow(); - QListWidgetItem* item = ui_->providers->takeItem(row); - ui_->providers->insertItem(row + d, item); - ui_->providers->setCurrentRow(row + d); -} - -// void LyricSettings::ItemChanged(QListWidgetItem* item) { -// const bool checked = item->checkState() == Qt::Checked; -// item->setForeground(checked ? palette().color(QPalette::Active, QPalette::Text) -// : palette().color(QPalette::Disabled, QPalette::Text)); -// } diff --git a/lyrics/lyricsettings.h b/lyrics/lyricsettings.h index 123add664..f859c429b 100644 --- a/lyrics/lyricsettings.h +++ b/lyrics/lyricsettings.h @@ -27,34 +27,27 @@ #include #include #include +#include "ui_lyricsettings.h" -class Ui_LyricSettings; class QListWidgetItem; class UltimateLyricsProvider; -class LyricSettings : public QWidget +class LyricSettings : public QWidget, private Ui::LyricSettings { Q_OBJECT public: - LyricSettings(QWidget *parent = 0); - ~LyricSettings(); + LyricSettings(QWidget *p); + virtual ~LyricSettings() { } - QStringList EnabledProviders(); - -public Q_SLOTS: - void Load(const QList &providers); + void load(); + void save(); private Q_SLOTS: - void MoveUp(); - void MoveDown(); - void Move(int d); - - void CurrentItemChanged(QListWidgetItem* item); -// void ItemChanged(QListWidgetItem* item); - -private: - Ui_LyricSettings* ui_; + void moveUp(); + void moveDown(); + void move(int d); + void currentItemChanged(QListWidgetItem *item); }; #endif // LYRICSETTINGS_H diff --git a/lyrics/lyricspage.cpp b/lyrics/lyricspage.cpp index b2e8238d7..767e24f6d 100644 --- a/lyrics/lyricspage.cpp +++ b/lyrics/lyricspage.cpp @@ -21,11 +21,10 @@ * Boston, MA 02110-1301, USA. */ -#include "songinfoprovider.h" #include "lyricspage.h" #include "lyricsdialog.h" #include "ultimatelyricsprovider.h" -#include "ultimatelyricsreader.h" +#include "ultimatelyrics.h" #include "settings.h" #include "squeezedtextlabel.h" #include "utils.h" @@ -62,32 +61,14 @@ static QString cacheFile(QString artist, QString title, bool createDir=false) return QDir::toNativeSeparators(Utils::cacheDir(LyricsPage::constLyricsDir+artist+'/', createDir))+title+LyricsPage::constExtension; } -typedef QList ProviderList; - -bool CompareLyricProviders(const UltimateLyricsProvider* a, const UltimateLyricsProvider* b) { - return a->relevance() < b->relevance(); -} - LyricsPage::LyricsPage(QWidget *p) : QWidget(p) -// , reader(new UltimateLyricsReader(this)) + , currentProvider(-1) , currentRequest(0) , mode(Mode_Display) , job(0) { setupUi(this); - - providers=UltimateLyricsReader().Parse(QString(":lyrics.xml")); - foreach (UltimateLyricsProvider* provider, providers) { - connect(provider, SIGNAL(InfoReady(int, const QString &)), SLOT(resultReady(int, const QString &))); - } - - // Parse the ultimate lyrics xml file in the background -// QFuture future = QtConcurrent::run(reader.data(), &UltimateLyricsReader::Parse, -// QString(":lyrics.xml")); -// QFutureWatcher *watcher = new QFutureWatcher(this); -// watcher->setFuture(future); -// connect(watcher, SIGNAL(finished()), SLOT(ultimateLyricsParsed())); refreshAction = ActionCollection::get()->createAction("refreshlyrics", i18n("Refresh"), "view-refresh"); searchAction = ActionCollection::get()->createAction("searchlyrics", i18n("Search For Lyrics"), "edit-find"); editAction = ActionCollection::get()->createAction("editlyrics", i18n("Edit Lyrics"), Icons::editIcon); @@ -101,6 +82,7 @@ LyricsPage::LyricsPage(QWidget *p) connect(saveAction, SIGNAL(triggered()), SLOT(save())); connect(cancelAction, SIGNAL(triggered()), SLOT(cancel())); connect(delAction, SIGNAL(triggered()), SLOT(del())); + connect(UltimateLyrics::self(), SIGNAL(lyricsReady(int, const QString &)), SLOT(lyricsReady(int, const QString &))); Icon::init(refreshBtn); Icon::init(searchBtn); Icon::init(editBtn); @@ -120,9 +102,7 @@ LyricsPage::LyricsPage(QWidget *p) LyricsPage::~LyricsPage() { - foreach (UltimateLyricsProvider* provider, providers) { - delete provider; - } + UltimateLyrics::self()->release(); } void LyricsPage::saveSettings() @@ -130,25 +110,6 @@ void LyricsPage::saveSettings() Settings::self()->saveLyricsZoom(text->zoom()); } -void LyricsPage::setEnabledProviders(const QStringList &providerList) -{ - foreach (UltimateLyricsProvider* provider, providers) { - provider->set_enabled(false); - provider->set_relevance(0xFFFF); - } - - int relevance=0; - foreach (const QString &p, providerList) { - UltimateLyricsProvider *provider=providerByName(p); - if (provider) { - provider->set_enabled(true); - provider->set_relevance(relevance++); - } - } - - qSort(providers.begin(), providers.end(), CompareLyricProviders); -} - void LyricsPage::update() { QString mpdName=mpdFileName(); @@ -367,7 +328,7 @@ void LyricsPage::downloadFinished() getLyrics(); } -void LyricsPage::resultReady(int id, const QString &lyrics) +void LyricsPage::lyricsReady(int id, const QString &lyrics) { if (id != currentRequest) return; @@ -412,38 +373,21 @@ QString LyricsPage::cacheFileName() const return currentSong.artist.isEmpty() || currentSong.title.isEmpty() ? QString() : cacheFile(currentSong.artist, currentSong.title); } -UltimateLyricsProvider* LyricsPage::providerByName(const QString &name) const -{ - foreach (UltimateLyricsProvider* provider, providers) { - if (provider->name() == name) { - return provider; - } - } - return 0; -} - void LyricsPage::getLyrics() { - for(;;) { - currentProvider++; - if (currentProvideris_enabled()) { - text->setText(i18nc(" by <artist>\nFetching lyrics via <url>", "%1 by %2\nFetching lyrics via %3") - .arg(currentSong.title).arg(currentSong.artist, prov->name())); - prov->FetchInfo(currentRequest, currentSong); - return; - } - } else { - text->setText(i18nc("<title> by <artist>\nFailed\n", "%1 by %2\nFailed to fetch lyrics").arg(currentSong.title).arg(currentSong.artist)); - currentProvider=-1; - // Set lyrics file anyway - so that editing is enabled! - lyricsFile=Settings::self()->storeLyricsInMpdDir() - ? Utils::changeExtension(MPDConnection::self()->getDetails().dir+currentSong.file, constExtension) - : cacheFile(currentSong.artist, currentSong.title); - setMode(Mode_Display); - return; - } + UltimateLyricsProvider *prov=UltimateLyrics::self()->getNext(currentProvider); + if (prov) { + text->setText(i18nc("<title> by <artist>\nFetching lyrics via <url>", "%1 by %2\nFetching lyrics via %3") + .arg(currentSong.title).arg(currentSong.artist, prov->getName())); + prov->fetchInfo(currentRequest, currentSong); + } else { + text->setText(i18nc("<title> by <artist>\nFailed\n", "%1 by %2\nFailed to fetch lyrics").arg(currentSong.title).arg(currentSong.artist)); + currentProvider=-1; + // Set lyrics file anyway - so that editing is enabled! + lyricsFile=Settings::self()->storeLyricsInMpdDir() + ? Utils::changeExtension(MPDConnection::self()->getDetails().dir+currentSong.file, constExtension) + : cacheFile(currentSong.artist, currentSong.title); + setMode(Mode_Display); } } @@ -482,18 +426,3 @@ bool LyricsPage::setLyricsFromFile(const QString &filePath) const return success; } - -// void LyricsPage::ultimateLyricsParsed() -// { -// QFutureWatcher<ProviderList>* watcher = static_cast<QFutureWatcher<ProviderList>*>(sender()); -// QStringList names; -// -// foreach (UltimateLyricsProvider* provider, watcher->result()) { -// providers.append(provider); -// connect(provider, SIGNAL(InfoReady(int, const QString &)), SLOT(resultReady(int, const QString &))); -// } -// -// watcher->deleteLater(); -// reader.reset(); -// emit providersUpdated(); -// } diff --git a/lyrics/lyricspage.h b/lyrics/lyricspage.h index 3c362d442..962b72297 100644 --- a/lyrics/lyricspage.h +++ b/lyrics/lyricspage.h @@ -25,13 +25,11 @@ #define LYRICSPAGE_H #include <QWidget> -// #include <QScopedPointer> #include "song.h" #include "ui_lyricspage.h" #include "textbrowser.h" class UltimateLyricsProvider; -// class UltimateLyricsReader; class UltimateLyricsProvider; class QImage; class Action; @@ -55,9 +53,7 @@ public: ~LyricsPage(); void saveSettings(); - void setEnabledProviders(const QStringList &providerList); void update(const Song &song, bool force=false); - const QList<UltimateLyricsProvider *> & getProviders() { return providers; } void setBgndImageEnabled(bool e) { text->enableImage(e); } bool bgndImageEnabled() { return text->imageEnabled(); } @@ -69,7 +65,7 @@ public Q_SLOTS: protected Q_SLOTS: void downloadFinished(); - void resultReady(int id, const QString &lyrics); + void lyricsReady(int, const QString &lyrics); void update(); void search(); void edit(); @@ -80,7 +76,6 @@ protected Q_SLOTS: private: QString mpdFileName() const; QString cacheFileName() const; - UltimateLyricsProvider * providerByName(const QString &name) const; void getLyrics(); void setMode(Mode m); bool saveFile(const QString &fileName); @@ -95,12 +90,7 @@ private: */ bool setLyricsFromFile(const QString &filePath) const; -// private Q_SLOTS: -// void ultimateLyricsParsed(); - private: -// QScopedPointer<UltimateLyricsReader> reader; - QList<UltimateLyricsProvider *> providers; int currentProvider; int currentRequest; Song currentSong; diff --git a/lyrics/songinfoprovider.cpp b/lyrics/songinfoprovider.cpp deleted file mode 100644 index 87b1b7c1e..000000000 --- a/lyrics/songinfoprovider.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Cantata - * - * Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com> - * - */ -/* This file is part of Clementine. - Copyright 2010, David Sansome <me@davidsansome.com> - - Clementine is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Clementine is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Clementine. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "songinfoprovider.h" - -SongInfoProvider::SongInfoProvider() - : enabled_(true) -{ -} - -QString SongInfoProvider::name() const { - return metaObject()->className(); -} diff --git a/lyrics/ultimatelyrics.cpp b/lyrics/ultimatelyrics.cpp new file mode 100644 index 000000000..452f0bdd5 --- /dev/null +++ b/lyrics/ultimatelyrics.cpp @@ -0,0 +1,202 @@ +/* + * Cantata + * + * Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com> + * + */ +/* This file is part of Clementine. + Copyright 2010, David Sansome <me@davidsansome.com> + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "ultimatelyrics.h" +#include "ultimatelyricsprovider.h" +#include "settings.h" +#include <QCoreApplication> +#include <QFile> +#include <QXmlStreamReader> +#ifdef ENABLE_KDE_SUPPORT +#include <KDE/KGlobal> +K_GLOBAL_STATIC(UltimateLyrics, instance) +#endif + +static bool compareLyricProviders(const UltimateLyricsProvider *a, const UltimateLyricsProvider *b) +{ + return a->getRelevance() < b->getRelevance(); +} + +static QString parseInvalidIndicator(QXmlStreamReader *reader) +{ + QString ret = reader->attributes().value("value").toString(); + reader->skipCurrentElement(); + return ret; +} + +static UltimateLyricsProvider::Rule parseRule(QXmlStreamReader *reader) +{ + UltimateLyricsProvider::Rule ret; + + while (!reader->atEnd()) { + reader->readNext(); + + if (QXmlStreamReader::EndElement==reader->tokenType()) { + break; + } + + if (QXmlStreamReader::StartElement==reader->tokenType()) { + if (QLatin1String("item")==reader->name()) { + QXmlStreamAttributes attr = reader->attributes(); + if (attr.hasAttribute("tag")) { + ret << UltimateLyricsProvider::RuleItem(attr.value("tag").toString(), QString()); + } else if (attr.hasAttribute("begin")) { + ret << UltimateLyricsProvider::RuleItem(attr.value("begin").toString(), attr.value("end").toString()); + } + } + reader->skipCurrentElement(); + } + } + return ret; +} + +static UltimateLyricsProvider * parseProvider(QXmlStreamReader *reader) +{ + QXmlStreamAttributes attributes = reader->attributes(); + + UltimateLyricsProvider* scraper = new UltimateLyricsProvider; + scraper->setName(attributes.value("name").toString()); + scraper->setTitle(attributes.value("title").toString()); + scraper->setCharset(attributes.value("charset").toString()); + scraper->setUrl(attributes.value("url").toString()); + + while (!reader->atEnd()) { + reader->readNext(); + + if (QXmlStreamReader::EndElement==reader->tokenType()) { + break; + } + + if (QXmlStreamReader::StartElement==reader->tokenType()) { + if (QLatin1String("extract")==reader->name()) { + scraper->addExtractRule(parseRule(reader)); + } else if (QLatin1String("exclude")==reader->name()) { + scraper->addExcludeRule(parseRule(reader)); + } else if (QLatin1String("invalidIndicator")==reader->name()) { + scraper->addInvalidIndicator(parseInvalidIndicator(reader)); + } else if (QLatin1String("urlFormat")==reader->name()) { + scraper->addUrlFormat(reader->attributes().value("replace").toString(), reader->attributes().value("with").toString()); + reader->skipCurrentElement(); + } else { + reader->skipCurrentElement(); + } + } + } + return scraper; +} + +UltimateLyrics * UltimateLyrics::self() +{ + #ifdef ENABLE_KDE_SUPPORT + return instance; + #else + static UltimateLyrics *instance=0; + if(!instance) { + instance=new UltimateLyrics; + } + return instance; + #endif +} + +void UltimateLyrics::release() +{ + foreach (UltimateLyricsProvider *provider, providers) { + delete provider; + } + providers.clear(); +} + +const QList<UltimateLyricsProvider *> UltimateLyrics::getProviders() +{ + load(); + return providers; +} + +UltimateLyricsProvider * UltimateLyrics::providerByName(const QString &name) const +{ + foreach (UltimateLyricsProvider *provider, providers) { + if (provider->getName() == name) { + return provider; + } + } + return 0; +} + +UltimateLyricsProvider * UltimateLyrics::getNext(int &index) +{ + load(); + index++; + if (index>-1 && index<providers.count()) { + for (int i=index; i<providers.count(); ++i) { + if (providers.at(i)->isEnabled()) { + index=i; + return providers.at(i); + } + } + } + return 0; +} + +void UltimateLyrics::load() +{ + if (!providers.isEmpty()) { + return; + } + + QFile file(":lyrics.xml"); + if (file.open(QIODevice::ReadOnly)) { + QXmlStreamReader reader(&file); + while (!reader.atEnd()) { + reader.readNext(); + + if (QLatin1String("provider")==reader.name()) { + UltimateLyricsProvider *provider = parseProvider(&reader); + if (provider) { + providers << provider; + connect(provider, SIGNAL(lyricsReady(int,QString)), this, SIGNAL(lyricsReady(int,QString))); + } + } + } + } + + setEnabled(Settings::self()->lyricProviders()); +} + +void UltimateLyrics::setEnabled(const QStringList &enabled) +{ + foreach (UltimateLyricsProvider *provider, providers) { + provider->setEnabled(false); + provider->setRelevance(0xFFFF); + } + + int relevance=0; + foreach (const QString &p, enabled) { + UltimateLyricsProvider *provider=providerByName(p); + if (provider) { + provider->setEnabled(true); + provider->setRelevance(relevance++); + } + } + qSort(providers.begin(), providers.end(), compareLyricProviders); + Settings::self()->saveLyricProviders(enabled); +} diff --git a/lyrics/songinfoprovider.h b/lyrics/ultimatelyrics.h similarity index 58% rename from lyrics/songinfoprovider.h rename to lyrics/ultimatelyrics.h index 7009e1f40..4ad3941d7 100644 --- a/lyrics/songinfoprovider.h +++ b/lyrics/ultimatelyrics.h @@ -21,38 +21,35 @@ along with Clementine. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SONGINFOPROVIDER_H -#define SONGINFOPROVIDER_H +#ifndef ULTIMATELYRICS_H +#define ULTIMATELYRICS_H #include <QObject> -#include <QUrl> -//#include "collapsibleinfopane.h" -//#include "core/song.h" +class UltimateLyricsProvider; -class Song; - -class SongInfoProvider : public QObject { - Q_OBJECT +class UltimateLyrics : public QObject +{ + Q_OBJECT public: - SongInfoProvider(); + static UltimateLyrics * self(); + UltimateLyrics() { } - virtual void FetchInfo(int id, const Song& metadata) = 0; -// virtual void Cancel(int id) {} + UltimateLyricsProvider * getNext(int &index); + const QList<UltimateLyricsProvider *> getProviders(); + void release(); + void setEnabled(const QStringList &enabled); - virtual QString name() const; - - bool is_enabled() const { return enabled_; } - void set_enabled(bool enabled) { enabled_ = enabled; } - -signals: - void ImageReady(int id, const QUrl& url); - void InfoReady(int id, const QString& data); - void Finished(int id); +Q_SIGNALS: + void lyricsReady(int id, const QString &data); private: - bool enabled_; + UltimateLyricsProvider * providerByName(const QString &name) const; + void load(); + +private: + QList<UltimateLyricsProvider *> providers; }; -#endif // SONGINFOPROVIDER_H +#endif // ULTIMATELYRICS_H diff --git a/lyrics/ultimatelyricsprovider.cpp b/lyrics/ultimatelyricsprovider.cpp index de3864139..a336242a2 100644 --- a/lyrics/ultimatelyricsprovider.cpp +++ b/lyrics/ultimatelyricsprovider.cpp @@ -21,37 +21,121 @@ along with Clementine. If not, see <http://www.gnu.org/licenses/>. */ -//#include "songinfotextview.h" #include "ultimatelyricsprovider.h" #include "networkaccessmanager.h" -//#include "core/network.h" #include "song.h" #include <QNetworkReply> #include <QTextCodec> -//#include <boost/scoped_ptr.hpp> -const int UltimateLyricsProvider::kRedirectLimit = 5; +static const int constRedirectLimit=5; +static QString extract(const QString &source, const QString &begin, const QString &end) +{ + int beginIdx = source.indexOf(begin); + if (-1==beginIdx) { + return QString(); + } + beginIdx += begin.length(); + + int endIdx = source.indexOf(end, beginIdx); + if (-1==endIdx) { + return QString(); + } + + return source.mid(beginIdx, endIdx - beginIdx - 1); +} + +static QString extractXmlTag(const QString &source, const QString &tag) +{ + QRegExp re("<(\\w+).*>"); // ಠ_ಠ + if (-1==re.indexIn(tag)) { + return QString(); + } + + return extract(source, tag, "</" + re.cap(1) + ">"); +} + +static QString exclude(const QString &source, const QString &begin, const QString &end) +{ + int beginIdx = source.indexOf(begin); + if (-1==beginIdx) { + return source; + } + + int endIdx = source.indexOf(end, beginIdx + begin.length()); + if (-1==endIdx) { + return source; + } + + return source.left(beginIdx) + source.right(source.length() - endIdx - end.length()); +} + +static QString excludeXmlTag(const QString &source, const QString &tag) +{ + QRegExp re("<(\\w+).*>"); // ಠ_ಠ + if (-1==re.indexIn(tag)) { + return source; + } + + return exclude(source, tag, "</" + re.cap(1) + ">"); +} + +static void applyExtractRule(const UltimateLyricsProvider::Rule &rule, QString *content) +{ + foreach (const UltimateLyricsProvider::RuleItem& item, rule) { + if (item.second.isNull()) { + *content = extractXmlTag(*content, item.first); + } else { + *content = extract(*content, item.first, item.second); + } + } +} + +static void applyExcludeRule(const UltimateLyricsProvider::Rule &rule, QString *content) +{ + foreach (const UltimateLyricsProvider::RuleItem& item, rule) { + if (item.second.isNull()) { + *content = excludeXmlTag(*content, item.first); + } else { + *content = exclude(*content, item.first, item.second); + } + } +} + +static QString firstChar(const QString &text) +{ + return text.isEmpty() ? text : text[0].toLower(); +} + +static QString titleCase(const QString &text) +{ + if (0==text.length()) { + return QString(); + } + if (1==text.length()) { + return text[0].toUpper(); + } + return text[0].toUpper() + text.right(text.length() - 1).toLower(); +} UltimateLyricsProvider::UltimateLyricsProvider() - : relevance_(0), - redirect_count_(0) + : enabled(true) + , relevance(0) + , redirectCount(0) { } -void UltimateLyricsProvider::FetchInfo(int id, const Song& metadata) { - // Get the text codec - #if QT_VERSION < 0x050000 - const QTextCodec* codec = QTextCodec::codecForName(charset_.toAscii().constData()); - #else - const QTextCodec* codec = QTextCodec::codecForName(charset_.toLatin1().constData()); - #endif - if (!codec) { - //qWarning() << "Invalid codec" << charset_; - //emit Finished(id); - emit InfoReady(id, QString()); - return; - } +void UltimateLyricsProvider::fetchInfo(int id, const Song &metadata) +{ + #if QT_VERSION < 0x050000 + const QTextCodec *codec = QTextCodec::codecForName(charset.toAscii().constData()); + #else + const QTextCodec *codec = QTextCodec::codecForName(charset.toLatin1().constData()); + #endif + if (!codec) { + emit lyricsReady(id, QString()); + return; + } // strip "featuring <someone else>" from the song.artist QString artistFixed=metadata.artist; @@ -59,207 +143,116 @@ void UltimateLyricsProvider::FetchInfo(int id, const Song& metadata) { toStrip << QLatin1String(" ft. ") << QLatin1String(" feat. ") << QLatin1String(" featuring "); foreach (const QString s, toStrip) { int strip = artistFixed.toLower().indexOf( " ft. "); - if ( strip != -1 ) { + if (-1!=strip) { artistFixed = artistFixed.mid( 0, strip ); } } - // Fill in fields in the URL - QString url_text(url_); - DoUrlReplace("{artist}", artistFixed.toLower(), &url_text); - DoUrlReplace("{album}", metadata.album.toLower(), &url_text); - DoUrlReplace("{title}", metadata.title.toLower(), &url_text); - DoUrlReplace("{Artist}", artistFixed, &url_text); - DoUrlReplace("{Album}", metadata.album, &url_text); - DoUrlReplace("{Title}", metadata.title, &url_text); - DoUrlReplace("{Title2}", TitleCase(metadata.title), &url_text); - DoUrlReplace("{a}", FirstChar(artistFixed), &url_text); + // Fill in fields in the URL + QString urlText(url); + doUrlReplace("{artist}", artistFixed.toLower(), &urlText); + doUrlReplace("{album}", metadata.album.toLower(), &urlText); + doUrlReplace("{title}", metadata.title.toLower(), &urlText); + doUrlReplace("{Artist}", artistFixed, &urlText); + doUrlReplace("{Album}", metadata.album, &urlText); + doUrlReplace("{Title}", metadata.title, &urlText); + doUrlReplace("{Title2}", titleCase(metadata.title), &urlText); + doUrlReplace("{a}", firstChar(artistFixed), &urlText); - QUrl url(url_text); - - // Fetch the URL, follow redirects - redirect_count_ = 0; - QNetworkReply* reply = NetworkAccessManager::self()->get(QNetworkRequest(url)); - requests_[reply] = id; - connect(reply, SIGNAL(finished()), SLOT(LyricsFetched())); + // Fetch the URL, follow redirects + redirectCount = 0; + QNetworkReply *reply = NetworkAccessManager::self()->get(QNetworkRequest(QUrl(urlText))); + requests[reply] = id; + connect(reply, SIGNAL(finished()), SLOT(lyricsFetched())); } -void UltimateLyricsProvider::LyricsFetched() { - QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); - if (!reply) - return; +void UltimateLyricsProvider::lyricsFetched() +{ + QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender()); + if (!reply) + return; - int id = requests_.take(reply); - reply->deleteLater(); + int id = requests.take(reply); + reply->deleteLater(); - if (reply->error() != QNetworkReply::NoError) { - //emit Finished(id); - emit InfoReady(id, QString()); - return; - } - - // Handle redirects - QVariant redirect_target = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); - if (redirect_target.isValid()) { - if (redirect_count_ >= kRedirectLimit) { - //emit Finished(id); - emit InfoReady(id, QString()); - return; + if (QNetworkReply::NoError!=reply->error()) { + //emit Finished(id); + emit lyricsReady(id, QString()); + return; } - QUrl target = redirect_target.toUrl(); - if (target.scheme().isEmpty() || target.host().isEmpty()) { - QString path = target.path(); - target = reply->url(); - target.setPath(path); + // Handle redirects + QVariant redirect_target = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirect_target.isValid()) { + if (redirectCount >= constRedirectLimit) { + //emit Finished(id); + emit lyricsReady(id, QString()); + return; + } + + QUrl target = redirect_target.toUrl(); + if (target.scheme().isEmpty() || target.host().isEmpty()) { + QString path = target.path(); + target = reply->url(); + target.setPath(path); + } + + redirectCount ++; + QNetworkReply* reply = NetworkAccessManager::self()->get(QNetworkRequest(target)); + requests[reply] = id; + connect(reply, SIGNAL(finished()), SLOT(lyricsFetched())); + return; } - redirect_count_ ++; - QNetworkReply* reply = NetworkAccessManager::self()->get(QNetworkRequest(target)); - requests_[reply] = id; - connect(reply, SIGNAL(finished()), SLOT(LyricsFetched())); - return; - } + #if QT_VERSION < 0x050000 + const QTextCodec *codec = QTextCodec::codecForName(charset.toAscii().constData()); + #else + const QTextCodec *codec = QTextCodec::codecForName(charset.toLatin1().constData()); + #endif + const QString original_content = codec->toUnicode(reply->readAll()); - #if QT_VERSION < 0x050000 - const QTextCodec* codec = QTextCodec::codecForName(charset_.toAscii().constData()); - #else - const QTextCodec* codec = QTextCodec::codecForName(charset_.toLatin1().constData()); - #endif - const QString original_content = codec->toUnicode(reply->readAll()); - - // Check for invalid indicators - foreach (const QString& indicator, invalid_indicators_) { - if (original_content.contains(indicator)) { - //emit Finished(id); - emit InfoReady(id, QString()); - return; + // Check for invalid indicators + foreach (const QString &indicator, invalidIndicators) { + if (original_content.contains(indicator)) { + //emit Finished(id); + emit lyricsReady(id, QString()); + return; + } } - } - QString lyrics; + QString lyrics; - // Apply extract rules - foreach (const Rule& rule, extract_rules_) { - QString content = original_content; - ApplyExtractRule(rule, &content); + // Apply extract rules + foreach (const Rule& rule, extractRules) { + QString content = original_content; + applyExtractRule(rule, &content); - if (!content.isEmpty()) - lyrics = content; - } - - // Apply exclude rules - foreach (const Rule& rule, exclude_rules_) { - ApplyExcludeRule(rule, &lyrics); - } - -#if 0 - if (!lyrics.isEmpty()) { - CollapsibleInfoPane::Data data; - data.id_ = "ultimatelyrics/" + name_; - data.title_ = tr("Lyrics from %1").arg(name_); - data.type_ = CollapsibleInfoPane::Data::Type_Lyrics; - data.relevance_ = relevance(); - - SongInfoTextView* editor = new SongInfoTextView; - editor->SetHtml(lyrics); - data.contents_ = editor; - - emit InfoReady(id, data); - } - emit Finished(id); -#endif - - lyrics=lyrics.trimmed(); - emit InfoReady(id, lyrics); -} - -void UltimateLyricsProvider::ApplyExtractRule(const Rule& rule, QString* content) const { - foreach (const RuleItem& item, rule) { - if (item.second.isNull()) { - *content = ExtractXmlTag(*content, item.first); - } else { - *content = Extract(*content, item.first, item.second); + if (!content.isEmpty()) { + lyrics = content; + } } - } -} -QString UltimateLyricsProvider::ExtractXmlTag(const QString& source, const QString& tag) { - QRegExp re("<(\\w+).*>"); // ಠ_ಠ - if (re.indexIn(tag) == -1) - return QString(); - - return Extract(source, tag, "</" + re.cap(1) + ">"); -} - -QString UltimateLyricsProvider::Extract(const QString& source, const QString& begin, const QString& end) { - int begin_idx = source.indexOf(begin); - if (begin_idx == -1) - return QString(); - begin_idx += begin.length(); - - int end_idx = source.indexOf(end, begin_idx); - if (end_idx == -1) - return QString(); - - return source.mid(begin_idx, end_idx - begin_idx - 1); -} - -void UltimateLyricsProvider::ApplyExcludeRule(const Rule& rule, QString* content) const { - foreach (const RuleItem& item, rule) { - if (item.second.isNull()) { - *content = ExcludeXmlTag(*content, item.first); - } else { - *content = Exclude(*content, item.first, item.second); + // Apply exclude rules + foreach (const Rule& rule, excludeRules) { + applyExcludeRule(rule, &lyrics); } - } + + lyrics=lyrics.trimmed(); + emit lyricsReady(id, lyrics); } -QString UltimateLyricsProvider::ExcludeXmlTag(const QString& source, const QString& tag) { - QRegExp re("<(\\w+).*>"); // ಠ_ಠ - if (re.indexIn(tag) == -1) - return source; +void UltimateLyricsProvider::doUrlReplace(const QString &tag, const QString &value, QString *u) const +{ + if (!u->contains(tag)) { + return; + } - return Exclude(source, tag, "</" + re.cap(1) + ">"); -} - -QString UltimateLyricsProvider::Exclude(const QString& source, const QString& begin, const QString& end) { - int begin_idx = source.indexOf(begin); - if (begin_idx == -1) - return source; - - int end_idx = source.indexOf(end, begin_idx + begin.length()); - if (end_idx == -1) - return source; - - return source.left(begin_idx) + source.right(source.length() - end_idx - end.length()); -} - -QString UltimateLyricsProvider::FirstChar(const QString& text) { - if (text.isEmpty()) - return QString(); - return text[0].toLower(); -} - -QString UltimateLyricsProvider::TitleCase(const QString& text) { - if (text.length() == 0) - return QString(); - if (text.length() == 1) - return text[0].toUpper(); - return text[0].toUpper() + text.right(text.length() - 1).toLower(); -} - -void UltimateLyricsProvider::DoUrlReplace(const QString& tag, const QString& value, - QString* url) const { - if (!url->contains(tag)) - return; - - // Apply URL character replacement - QString value_copy(value); - foreach (const UrlFormat& format, url_formats_) { - QRegExp re("[" + QRegExp::escape(format.first) + "]"); - value_copy.replace(re, format.second); - } - - url->replace(tag, value_copy, Qt::CaseInsensitive); + // Apply URL character replacement + QString valueCopy(value); + foreach (const UltimateLyricsProvider::UrlFormat& format, urlFormats) { + QRegExp re("[" + QRegExp::escape(format.first) + "]"); + valueCopy.replace(re, format.second); + } + + u->replace(tag, valueCopy, Qt::CaseInsensitive); } diff --git a/lyrics/ultimatelyricsprovider.h b/lyrics/ultimatelyricsprovider.h index 0b69ebd06..198aed00c 100644 --- a/lyrics/ultimatelyricsprovider.h +++ b/lyrics/ultimatelyricsprovider.h @@ -28,71 +28,57 @@ #include <QPair> #include <QStringList> #include <QHash> -#include "songinfoprovider.h" class Song; class QNetworkReply; -class UltimateLyricsProvider : public SongInfoProvider { - Q_OBJECT +class UltimateLyricsProvider : public QObject { + Q_OBJECT public: - UltimateLyricsProvider(); + UltimateLyricsProvider(); - static const int kRedirectLimit; + typedef QPair<QString, QString> RuleItem; + typedef QList<RuleItem> Rule; + typedef QPair<QString, QString> UrlFormat; - typedef QPair<QString, QString> RuleItem; - typedef QList<RuleItem> Rule; - typedef QPair<QString, QString> UrlFormat; + void setName(const QString &n) { name = n; } + void setTitle(const QString &t) { title = t; } + void setUrl(const QString &u) { url = u; } + void setCharset(const QString &c) { charset = c; } + void setRelevance(int r) { relevance = r; } + void addUrlFormat(const QString &replace, const QString &with) { urlFormats << UrlFormat(replace, with); } + void addExtractRule(const Rule &rule) { extractRules << rule; } + void addExcludeRule(const Rule &rule) { excludeRules << rule; } + void addInvalidIndicator(const QString &indicator) { invalidIndicators << indicator; } + QString getName() const { return name; } + int getRelevance() const { return relevance; } + void fetchInfo(int id, const Song &metadata); + bool isEnabled() const { return enabled; } + void setEnabled(bool e) { enabled = e; } - void set_name(const QString& name) { name_ = name; } - void set_title(const QString& title) { title_ = title; } - void set_url(const QString& url) { url_ = url; } - void set_charset(const QString& charset) { charset_ = charset; } - void set_relevance(int relevance) { relevance_ = relevance; } +Q_SIGNALS: + void lyricsReady(int id, const QString &data); - void add_url_format(const QString& replace, const QString& with) { - url_formats_ << UrlFormat(replace, with); } - - void add_extract_rule(const Rule& rule) { extract_rules_ << rule; } - void add_exclude_rule(const Rule& rule) { exclude_rules_ << rule; } - void add_invalid_indicator(const QString& indicator) { invalid_indicators_ << indicator; } - - QString name() const { return name_; } - int relevance() const { return relevance_; } - - void FetchInfo(int id, const Song& metadata); - -private slots: - void LyricsFetched(); +private Q_SLOTS: + void lyricsFetched(); private: - void ApplyExtractRule(const Rule& rule, QString* content) const; - void ApplyExcludeRule(const Rule& rule, QString* content) const; - - static QString ExtractXmlTag(const QString& source, const QString& tag); - static QString Extract(const QString& source, const QString& begin, const QString& end); - static QString ExcludeXmlTag(const QString& source, const QString& tag); - static QString Exclude(const QString& source, const QString& begin, const QString& end); - static QString FirstChar(const QString& text); - static QString TitleCase(const QString& text); - void DoUrlReplace(const QString& tag, const QString& value, QString* url) const; + void doUrlReplace(const QString &tag, const QString &value, QString *u) const; private: - QHash<QNetworkReply*, int> requests_; - - QString name_; - QString title_; - QString url_; - QString charset_; - int relevance_; - - QList<UrlFormat> url_formats_; - QList<Rule> extract_rules_; - QList<Rule> exclude_rules_; - QStringList invalid_indicators_; - - int redirect_count_; + bool enabled; + QHash<QNetworkReply*, int> requests; + QString name; + QString title; + QString url; + QString charset; + int relevance; + QList<UrlFormat> urlFormats; + QList<Rule> extractRules; + QList<Rule> excludeRules; + QStringList invalidIndicators; + int redirectCount; }; #endif // ULTIMATELYRICSPROVIDER_H diff --git a/lyrics/ultimatelyricsreader.cpp b/lyrics/ultimatelyricsreader.cpp deleted file mode 100644 index 5178cb0e7..000000000 --- a/lyrics/ultimatelyricsreader.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cantata - * - * Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com> - * - */ -/* This file is part of Clementine. - Copyright 2010, David Sansome <me@davidsansome.com> - - Clementine is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Clementine is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Clementine. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "ultimatelyricsprovider.h" -#include "ultimatelyricsreader.h" - -#include <QCoreApplication> -#include <QFile> -#include <QXmlStreamReader> - -UltimateLyricsReader::UltimateLyricsReader(/*QObject* parent*/) -// : QObject(parent) -{ -} - -QList<UltimateLyricsProvider*> UltimateLyricsReader::Parse(const QString& filename) const { - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) { -// qWarning() << "Error opening" << filename; - return QList<UltimateLyricsProvider*>(); - } - - return ParseDevice(&file); -} - -QList<UltimateLyricsProvider*> UltimateLyricsReader::ParseDevice(QIODevice* device) const { - QList<UltimateLyricsProvider*> ret; - - QXmlStreamReader reader(device); - while (!reader.atEnd()) { - reader.readNext(); - - if (reader.name() == "provider") { - UltimateLyricsProvider* provider = ParseProvider(&reader); - if (provider) { - provider->moveToThread(qApp->thread()); - ret << provider; - } - } - } - - return ret; -} - -UltimateLyricsProvider* UltimateLyricsReader::ParseProvider(QXmlStreamReader* reader) const { - QXmlStreamAttributes attributes = reader->attributes(); - - UltimateLyricsProvider* scraper = new UltimateLyricsProvider; - scraper->set_name(attributes.value("name").toString()); - scraper->set_title(attributes.value("title").toString()); - scraper->set_charset(attributes.value("charset").toString()); - scraper->set_url(attributes.value("url").toString()); - - while (!reader->atEnd()) { - reader->readNext(); - - if (reader->tokenType() == QXmlStreamReader::EndElement) - break; - - if (reader->tokenType() == QXmlStreamReader::StartElement) { - if (reader->name() == "extract") - scraper->add_extract_rule(ParseRule(reader)); - else if (reader->name() == "exclude") - scraper->add_exclude_rule(ParseRule(reader)); - else if (reader->name() == "invalidIndicator") - scraper->add_invalid_indicator(ParseInvalidIndicator(reader)); - else if (reader->name() == "urlFormat") { - scraper->add_url_format(reader->attributes().value("replace").toString(), - reader->attributes().value("with").toString()); - reader->skipCurrentElement(); - } - else - reader->skipCurrentElement(); - } - } - return scraper; -} - -UltimateLyricsProvider::Rule UltimateLyricsReader::ParseRule(QXmlStreamReader* reader) const { - UltimateLyricsProvider::Rule ret; - - while (!reader->atEnd()) { - reader->readNext(); - - if (reader->tokenType() == QXmlStreamReader::EndElement) - break; - - if (reader->tokenType() == QXmlStreamReader::StartElement) { - if (reader->name() == "item") { - QXmlStreamAttributes attr = reader->attributes(); - if (attr.hasAttribute("tag")) - ret << UltimateLyricsProvider::RuleItem(attr.value("tag").toString(), QString()); - else if (attr.hasAttribute("begin")) - ret << UltimateLyricsProvider::RuleItem(attr.value("begin").toString(), - attr.value("end").toString()); - } - reader->skipCurrentElement(); - } - } - return ret; -} - -QString UltimateLyricsReader::ParseInvalidIndicator(QXmlStreamReader* reader) const { - QString ret = reader->attributes().value("value").toString(); - reader->skipCurrentElement(); - return ret; -} - diff --git a/lyrics/ultimatelyricsreader.h b/lyrics/ultimatelyricsreader.h deleted file mode 100644 index ec00d80ad..000000000 --- a/lyrics/ultimatelyricsreader.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Cantata - * - * Copyright (c) 2011-2013 Craig Drummond <craig.p.drummond@gmail.com> - * - */ -/* This file is part of Clementine. - Copyright 2010, David Sansome <me@davidsansome.com> - - Clementine is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Clementine is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Clementine. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef ULTIMATELYRICSREADER_H -#define ULTIMATELYRICSREADER_H - -#include "ultimatelyricsprovider.h" - -// #include <QObject> -#include <QXmlStreamReader> - -class QIODevice; - -class UltimateLyricsReader/* : public QObject*/ { -// Q_OBJECT - -public: - UltimateLyricsReader(/*QObject* parent = 0*/); - - QList<UltimateLyricsProvider*> Parse(const QString& filename) const; - QList<UltimateLyricsProvider*> ParseDevice(QIODevice* device) const; - -private: - UltimateLyricsProvider* ParseProvider(QXmlStreamReader* reader) const; - UltimateLyricsProvider::Rule ParseRule(QXmlStreamReader* reader) const; - QString ParseInvalidIndicator(QXmlStreamReader* reader) const; -}; - -#endif // ULTIMATELYRICSREADER_H