1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-18 04:19:55 +01:00

Add an Encyclopaedia Metallum lyrics provider. Fixes issue 3568

This commit is contained in:
Paweł Szymański 2013-12-03 20:21:52 +11:00 committed by David Sansome
parent 5207af6f93
commit 6e8cfc7762
4 changed files with 78 additions and 26 deletions

View File

@ -43,6 +43,14 @@
</exclude>
<invalidIndicator value="Page not Found"/>
</provider>
<provider name="Encyclopaedia Metallum" title="{title Lyrics - {artist}" charset="utf-8" url="http://www.metal-archives.com/search/ajax-advanced/searching/songs/?songTitle={title}&amp;bandName={artist}&amp;ExactBandMatch=1">
<extract>
<item url="http://www.metal-archives.com/release/ajax-view-lyrics/id/{id}"/>
<item begin="id=\&quot;lyricsLink_" end="&quot;"/>
</extract>
<invalidIndicator value="&quot;iTotalRecords&quot;: 0"/>
<invalidIndicator value="lyrics not available"/>
</provider>
<provider name="letras.mus.br" title="" charset="iso-8859-1" url="http://letras.terra.com.br/winamp.php?musica={title}&amp;artista={artist}">
<urlFormat replace="_@,;&amp;\/&quot;" with="_"/>
<urlFormat replace=" " with="+"/>

View File

@ -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<QNetworkReply*>(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,11 +110,13 @@ 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;
}
}
if (!url_hop_) {
// Apply extract rules
foreach (const Rule& rule, extract_rules_) {
// Modify the rule for this request's metadata
@ -119,18 +126,28 @@ void UltimateLyricsProvider::LyricsFetched() {
}
QString content = original_content;
ApplyExtractRule(rule_copy, &content);
qLog(Debug) << "Extract rule" << rule_copy << "matched" << content.length();
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;
}
}
// 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()) {
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) {

View File

@ -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

View File

@ -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());