File indexing completed on 2021-12-21 13:27:55
0001 /** 0002 * Copyright (C) 2012 Martin Sandsmark <martin.sandsmark@kde.org> 0003 * 0004 * This program is free software; you can redistribute it and/or modify it under 0005 * the terms of the GNU General Public License as published by the Free Software 0006 * Foundation; either version 2 of the License, or (at your option) any later 0007 * version. 0008 * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. 0012 * 0013 * You should have received a copy of the GNU General Public License along with 0014 * this program. If not, see <http://www.gnu.org/licenses/>. 0015 */ 0016 0017 #include "lyricswidget.h" 0018 0019 #include <QDomDocument> 0020 #include <QNetworkAccessManager> 0021 #include <QNetworkReply> 0022 #include <QIcon> 0023 #include <QAction> 0024 #include <QUrlQuery> 0025 #include <KLocalizedString> 0026 #include <KActionCollection> 0027 #include <KToggleAction> 0028 #include <KConfigGroup> 0029 #include <KSharedConfig> 0030 0031 #include "actioncollection.h" 0032 #include "iconsupport.h" 0033 #include "juk_debug.h" 0034 #include "juktag.h" 0035 0036 static const QUrl BASE_LYRICS_URL = QUrl("https://lyrics.fandom.com/"); 0037 0038 using namespace IconSupport; // ""_icon 0039 using namespace ActionCollection; // ""_act 0040 0041 LyricsWidget::LyricsWidget(QWidget* parent) 0042 : QTextBrowser(parent) 0043 , m_networkAccessManager(new QNetworkAccessManager) 0044 , m_lyricsCurrent(false) 0045 { 0046 setMinimumWidth(200); 0047 setReadOnly(true); 0048 setWordWrapMode(QTextOption::WordWrap); 0049 setOpenExternalLinks(true); 0050 0051 KToggleAction *show = new KToggleAction("view-media-lyrics"_icon, 0052 i18n("Show &Lyrics"), this); 0053 ActionCollection::actions()->addAction("showLyrics", show); 0054 connect(show, SIGNAL(toggled(bool)), this, SLOT(setVisible(bool))); 0055 0056 KConfigGroup config(KSharedConfig::openConfig(), "LyricsWidget"); 0057 bool shown = config.readEntry("Show", true); 0058 show->setChecked(shown); 0059 setVisible(shown); 0060 } 0061 0062 LyricsWidget::~LyricsWidget() 0063 { 0064 delete m_networkAccessManager; 0065 saveConfig(); 0066 } 0067 0068 void LyricsWidget::saveConfig() 0069 { 0070 KConfigGroup config(KSharedConfig::openConfig(), "LyricsWidget"); 0071 config.writeEntry("Show", "showLyrics"_act->isChecked()); 0072 } 0073 0074 void LyricsWidget::makeLyricsRequest() 0075 { 0076 m_lyricsCurrent = true; 0077 0078 if(m_playingFile.isNull()) { 0079 setHtml(i18n("<i>No file playing.</i>")); 0080 return; 0081 } 0082 0083 m_title = m_playingFile.tag()->artist() + " – " + m_playingFile.tag()->title(); 0084 setHtml(i18n("<i>Loading...</i>")); 0085 0086 // lyrics.fandom.com seems to be unavailable as well now so give a better error message 0087 // and stop pinging the server 0088 if(1) { 0089 setHtml(i18n("<i>Lyrics are currently unavailable for %1 (no available lyrics provider)</i>").arg(m_title)); 0090 return; 0091 } 0092 0093 QUrl listUrl = BASE_LYRICS_URL; 0094 listUrl.setPath("/api.php"); 0095 0096 QUrlQuery listUrlQuery; 0097 listUrlQuery.addQueryItem("action", "lyrics"); 0098 listUrlQuery.addQueryItem("func", "getSong"); 0099 listUrlQuery.addQueryItem("fmt", "xml"); 0100 listUrlQuery.addQueryItem("artist", m_playingFile.tag()->artist()); 0101 listUrlQuery.addQueryItem("song", m_playingFile.tag()->title()); 0102 listUrl.setQuery(listUrlQuery); 0103 0104 connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveListReply(QNetworkReply*))); 0105 m_networkAccessManager->get(QNetworkRequest(listUrl)); 0106 } 0107 0108 void LyricsWidget::playing(const FileHandle &file) 0109 { 0110 m_playingFile = file; 0111 m_lyricsCurrent = false; 0112 0113 if(isVisible()) { 0114 makeLyricsRequest(); 0115 } 0116 } 0117 0118 void LyricsWidget::showEvent(QShowEvent *) 0119 { 0120 if(!m_lyricsCurrent) { 0121 makeLyricsRequest(); 0122 } 0123 } 0124 0125 void LyricsWidget::receiveListReply(QNetworkReply* reply) 0126 { 0127 disconnect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveListReply(QNetworkReply*))); 0128 if (reply->error() != QNetworkReply::NoError) { 0129 qCWarning(JUK_LOG) << "Error while fetching lyrics: " << reply->errorString(); 0130 setHtml(i18n("<span style='color:red'>Error while retrieving lyrics!</span>")); 0131 return; 0132 } 0133 0134 QDomDocument document; 0135 document.setContent(reply); 0136 QString artist = document.elementsByTagName("artist").at(0).toElement().text(); 0137 QString title = document.elementsByTagName("song").at(0).toElement().text(); 0138 0139 QUrl url = BASE_LYRICS_URL; 0140 url.setPath("/api.php"); 0141 0142 QUrlQuery urlQuery; 0143 urlQuery.addQueryItem("action", "query"); 0144 urlQuery.addQueryItem("prop", "revisions"); 0145 urlQuery.addQueryItem("rvprop", "content"); 0146 urlQuery.addQueryItem("format", "xml"); 0147 urlQuery.addQueryItem("titles", artist + ':' + title); 0148 url.setQuery(urlQuery); 0149 0150 connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveLyricsReply(QNetworkReply*))); 0151 m_networkAccessManager->get(QNetworkRequest(url)); 0152 } 0153 0154 void LyricsWidget::receiveLyricsReply(QNetworkReply* reply) 0155 { 0156 disconnect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveLyricsReply(QNetworkReply*))); 0157 if (reply->error() != QNetworkReply::NoError) { 0158 qCWarning(JUK_LOG) << "Error while fetching lyrics: " << reply->errorString(); 0159 setHtml(i18n("<span style='color:red'>Error while retrieving lyrics!</span>")); 0160 return; 0161 } 0162 const QUrlQuery replyUrlQuery(reply->url()); 0163 QString titlesUrlPart = replyUrlQuery.queryItemValue(QStringLiteral("titles"), QUrl::FullyEncoded); 0164 if (titlesUrlPart.isEmpty()) { 0165 // default homepage, but this code path should never happen at this point. 0166 titlesUrlPart = QStringLiteral("Lyrics_Wiki"); 0167 } 0168 const QString lyricsUrl = BASE_LYRICS_URL.toString() + QStringLiteral("wiki/") + titlesUrlPart; 0169 0170 QString content = QString::fromUtf8(reply->readAll()); 0171 int lIndex = content.indexOf("<lyrics>"); 0172 int rIndex = content.indexOf("</lyrics>"); 0173 if (lIndex == -1 || rIndex == -1) { 0174 qCWarning(JUK_LOG) << Q_FUNC_INFO << "Unable to find lyrics in text"; 0175 setText(i18n("No lyrics available.")); 0176 return; 0177 } 0178 lIndex += 15; // We skip the tag 0179 content = content.mid(lIndex, rIndex - lIndex).trimmed(); 0180 content.replace('\n', "<br />"); 0181 //setText(content); 0182 setHtml("<h1>" + m_title + "</h1>" + 0183 content + 0184 i18n("<br /><br /><i>Lyrics provided by <a href='%1'>LyricWiki</a></i>", lyricsUrl)); 0185 }