206 lines
6.5 KiB
C++
206 lines
6.5 KiB
C++
/*
|
|
* Cantata
|
|
*
|
|
* Copyright (c) 2011-2017 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 "gui/settings.h"
|
|
#include "support/globalstatic.h"
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QFileInfoList>
|
|
#include <QXmlStreamReader>
|
|
#include <QSet>
|
|
|
|
GLOBAL_STATIC(UltimateLyrics, instance)
|
|
|
|
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->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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
QStringList dirs=QStringList() << Utils::dataDir() << CANTATA_SYS_CONFIG_DIR;
|
|
|
|
QSet<QString> providerNames;
|
|
foreach (const QString &d, dirs) {
|
|
if (d.isEmpty()) {
|
|
continue;
|
|
}
|
|
QFileInfoList files=QDir(d).entryInfoList(QStringList() << QLatin1String("lyrics_*.xml"), QDir::NoDotAndDotDot|QDir::Files);
|
|
foreach (const QFileInfo &f, files) {
|
|
QFile file(f.absoluteFilePath());
|
|
if (file.open(QIODevice::ReadOnly)) {
|
|
QXmlStreamReader reader(&file);
|
|
while (!reader.atEnd()) {
|
|
reader.readNext();
|
|
|
|
if (QLatin1String("provider")==reader.name()) {
|
|
QString name=reader.attributes().value("name").toString();
|
|
|
|
if (!providerNames.contains(name)) {
|
|
UltimateLyricsProvider *provider = parseProvider(&reader);
|
|
if (provider) {
|
|
providers << provider;
|
|
connect(provider, SIGNAL(lyricsReady(int,QString)), this, SIGNAL(lyricsReady(int,QString)));
|
|
providerNames.insert(name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|