From 6e8cfc7762301def6c19a082e02e69e08b8ded35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szyma=C5=84ski?= Date: Tue, 3 Dec 2013 20:21:52 +1100 Subject: [PATCH] Add an Encyclopaedia Metallum lyrics provider. Fixes issue 3568 --- data/lyrics/ultimate_providers.xml | 10 ++- src/songinfo/ultimatelyricsprovider.cpp | 88 ++++++++++++++++++------- src/songinfo/ultimatelyricsprovider.h | 4 +- src/songinfo/ultimatelyricsreader.cpp | 2 + 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/data/lyrics/ultimate_providers.xml b/data/lyrics/ultimate_providers.xml index e88da7efe..da2ebb18a 100644 --- a/data/lyrics/ultimate_providers.xml +++ b/data/lyrics/ultimate_providers.xml @@ -17,7 +17,7 @@ - + @@ -43,6 +43,14 @@ + + + + + + + + diff --git a/src/songinfo/ultimatelyricsprovider.cpp b/src/songinfo/ultimatelyricsprovider.cpp index ccab2ce4c..2d38bd6f7 100644 --- a/src/songinfo/ultimatelyricsprovider.cpp +++ b/src/songinfo/ultimatelyricsprovider.cpp @@ -34,7 +34,8 @@ const int UltimateLyricsProvider::kRedirectLimit = 5; UltimateLyricsProvider::UltimateLyricsProvider() : network_(new NetworkAccessManager(this)), relevance_(0), - redirect_count_(0) + redirect_count_(0), + url_hop_(false) { } @@ -64,13 +65,16 @@ void UltimateLyricsProvider::FetchInfo(int id, const Song& metadata) { void UltimateLyricsProvider::LyricsFetched() { QNetworkReply* reply = qobject_cast(sender()); - if (!reply) + if (!reply) { + url_hop_ = false; return; + } int id = requests_.take(reply); reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) { + url_hop_ = false; emit Finished(id); return; } @@ -79,6 +83,7 @@ void UltimateLyricsProvider::LyricsFetched() { QVariant redirect_target = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (redirect_target.isValid()) { if (redirect_count_ >= kRedirectLimit) { + url_hop_ = false; emit Finished(id); return; } @@ -105,32 +110,44 @@ void UltimateLyricsProvider::LyricsFetched() { foreach (const QString& indicator, invalid_indicators_) { if (original_content.contains(indicator)) { qLog(Debug) << "Found invalid indicator" << indicator; + url_hop_ = false; emit Finished(id); return; } } - // Apply extract rules - foreach (const Rule& rule, extract_rules_) { - // Modify the rule for this request's metadata - Rule rule_copy(rule); - for (Rule::iterator it = rule_copy.begin() ; it != rule_copy.end() ; ++it) { - ReplaceFields(metadata_, &it->first); + if (!url_hop_) { + // Apply extract rules + foreach (const Rule& rule, extract_rules_) { + // Modify the rule for this request's metadata + Rule rule_copy(rule); + for (Rule::iterator it = rule_copy.begin() ; it != rule_copy.end() ; ++it) { + ReplaceFields(metadata_, &it->first); + } + + QString content = original_content; + if (ApplyExtractRule(rule_copy, &content)) { + url_hop_ = true; + QUrl url(content); + qLog(Debug) << "Next url hop: " << url; + QNetworkReply* reply = network_->get(QNetworkRequest(url)); + requests_[reply] = id; + connect(reply, SIGNAL(finished()), SLOT(LyricsFetched())); + return; + } + + // Apply exclude rules + foreach (const Rule& rule, exclude_rules_) { + ApplyExcludeRule(rule, &lyrics); + } + + if (!content.isEmpty()) { + lyrics = content; + break; + } } - - QString content = original_content; - ApplyExtractRule(rule_copy, &content); - qLog(Debug) << "Extract rule" << rule_copy << "matched" << content.length(); - - if (!content.isEmpty()) { - lyrics = content; - break; - } - } - - // Apply exclude rules - foreach (const Rule& rule, exclude_rules_) { - ApplyExcludeRule(rule, &lyrics); + } else { + lyrics = original_content; } if (!lyrics.isEmpty()) { @@ -152,17 +169,40 @@ void UltimateLyricsProvider::LyricsFetched() { emit InfoReady(id, data); } + url_hop_ = false; emit Finished(id); } -void UltimateLyricsProvider::ApplyExtractRule(const Rule& rule, QString* content) const { +bool UltimateLyricsProvider::ApplyExtractRule(const Rule& rule, QString* content) const { foreach (const RuleItem& item, rule) { if (item.second.isNull()) { - *content = ExtractXmlTag(*content, item.first); + if (item.first.startsWith("http://") && item.second.isNull()) { + *content = ExtractUrl(*content, rule); + return true; + } else { + *content = ExtractXmlTag(*content, item.first); + } } else { *content = Extract(*content, item.first, item.second); } } + return false; +} + +QString UltimateLyricsProvider::ExtractUrl(const QString& source, const Rule& rule) { + QString url; + QString id; + + foreach(const RuleItem& item, rule) { + if (item.first.startsWith("http://") && item.second.isNull()) + url = item.first; + else + id = Extract(source, item.first,item.second); + } + + url.replace("{id}", id); + + return url; } QString UltimateLyricsProvider::ExtractXmlTag(const QString& source, const QString& tag) { diff --git a/src/songinfo/ultimatelyricsprovider.h b/src/songinfo/ultimatelyricsprovider.h index 81573d928..aec4f7218 100644 --- a/src/songinfo/ultimatelyricsprovider.h +++ b/src/songinfo/ultimatelyricsprovider.h @@ -62,9 +62,10 @@ private slots: void LyricsFetched(); private: - void ApplyExtractRule(const Rule& rule, QString* content) const; + bool ApplyExtractRule(const Rule& rule, QString* content) const; void ApplyExcludeRule(const Rule& rule, QString* content) const; + static QString ExtractUrl(const QString& source, const Rule& rule); 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); @@ -93,6 +94,7 @@ private: Song metadata_; int redirect_count_; + bool url_hop_; }; #endif // ULTIMATELYRICSPROVIDER_H diff --git a/src/songinfo/ultimatelyricsreader.cpp b/src/songinfo/ultimatelyricsreader.cpp index 4862e5de3..91850adda 100644 --- a/src/songinfo/ultimatelyricsreader.cpp +++ b/src/songinfo/ultimatelyricsreader.cpp @@ -110,6 +110,8 @@ UltimateLyricsProvider::Rule UltimateLyricsReader::ParseRule(QXmlStreamReader* r QXmlStreamAttributes attr = reader->attributes(); if (attr.hasAttribute("tag")) ret << UltimateLyricsProvider::RuleItem(attr.value("tag").toString(), QString()); + else if (attr.hasAttribute("url")) + ret << UltimateLyricsProvider::RuleItem(attr.value("url").toString(), QString()); else if (attr.hasAttribute("begin")) ret << UltimateLyricsProvider::RuleItem(attr.value("begin").toString(), attr.value("end").toString());