File indexing completed on 2023-05-30 11:30:47
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 <KActionCollection> 0020 #include <KConfigGroup> 0021 #include <KLocalizedString> 0022 #include <KSharedConfig> 0023 #include <KToggleAction> 0024 #include <QAction> 0025 #include <QDomDocument> 0026 #include <QNetworkAccessManager> 0027 #include <QNetworkReply> 0028 #include <QUrlQuery> 0029 0030 #include "actioncollection.h" 0031 #include "iconsupport.h" 0032 #include "juk_debug.h" 0033 #include "juktag.h" 0034 0035 static const QUrl BASE_LYRICS_URL = QUrl("https://lyrics.fandom.com/"); 0036 0037 using namespace IconSupport; // ""_icon 0038 using namespace ActionCollection; // ""_act 0039 0040 LyricsWidget::LyricsWidget(QWidget* parent) 0041 : QTextBrowser(parent) 0042 , m_networkAccessManager(new QNetworkAccessManager) 0043 , m_lyricsCurrent(false) 0044 { 0045 setMinimumWidth(200); 0046 setReadOnly(true); 0047 setWordWrapMode(QTextOption::WordWrap); 0048 setOpenExternalLinks(true); 0049 0050 KToggleAction *show = new KToggleAction("view-media-lyrics"_icon, 0051 i18n("Show &Lyrics"), this); 0052 ActionCollection::actions()->addAction("showLyrics", show); 0053 connect(show, SIGNAL(toggled(bool)), this, SLOT(setVisible(bool))); 0054 0055 KConfigGroup config(KSharedConfig::openConfig(), "LyricsWidget"); 0056 bool shown = config.readEntry("Show", true); 0057 show->setChecked(shown); 0058 setVisible(shown); 0059 } 0060 0061 LyricsWidget::~LyricsWidget() 0062 { 0063 delete m_networkAccessManager; 0064 saveConfig(); 0065 } 0066 0067 void LyricsWidget::saveConfig() 0068 { 0069 KConfigGroup config(KSharedConfig::openConfig(), "LyricsWidget"); 0070 config.writeEntry("Show", "showLyrics"_act->isChecked()); 0071 } 0072 0073 void LyricsWidget::makeLyricsRequest() 0074 { 0075 m_lyricsCurrent = true; 0076 0077 if(m_playingFile.isNull()) { 0078 setHtml(i18n("<i>No file playing.</i>")); 0079 return; 0080 } 0081 0082 m_title = m_playingFile.tag()->artist() + " – " + m_playingFile.tag()->title(); 0083 setHtml(i18n("<i>Loading...</i>")); 0084 0085 // lyrics.fandom.com seems to be unavailable as well now so give a better error message 0086 // and stop pinging the server 0087 if(1) { 0088 setHtml(i18n("<i>Lyrics are currently unavailable for %1 (no available lyrics provider)</i>").arg(m_title)); 0089 return; 0090 } 0091 0092 QUrl listUrl = BASE_LYRICS_URL; 0093 listUrl.setPath("/api.php"); 0094 0095 QUrlQuery listUrlQuery; 0096 listUrlQuery.addQueryItem("action", "lyrics"); 0097 listUrlQuery.addQueryItem("func", "getSong"); 0098 listUrlQuery.addQueryItem("fmt", "xml"); 0099 listUrlQuery.addQueryItem("artist", m_playingFile.tag()->artist()); 0100 listUrlQuery.addQueryItem("song", m_playingFile.tag()->title()); 0101 listUrl.setQuery(listUrlQuery); 0102 0103 connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveListReply(QNetworkReply*))); 0104 m_networkAccessManager->get(QNetworkRequest(listUrl)); 0105 } 0106 0107 void LyricsWidget::playing(const FileHandle &file) 0108 { 0109 m_playingFile = file; 0110 m_lyricsCurrent = false; 0111 0112 if(isVisible()) { 0113 makeLyricsRequest(); 0114 } 0115 } 0116 0117 void LyricsWidget::showEvent(QShowEvent *) 0118 { 0119 if(!m_lyricsCurrent) { 0120 makeLyricsRequest(); 0121 } 0122 } 0123 0124 void LyricsWidget::receiveListReply(QNetworkReply* reply) 0125 { 0126 disconnect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveListReply(QNetworkReply*))); 0127 if (reply->error() != QNetworkReply::NoError) { 0128 qCWarning(JUK_LOG) << "Error while fetching lyrics: " << reply->errorString(); 0129 setHtml(i18n("<span style='color:red'>Error while retrieving lyrics!</span>")); 0130 return; 0131 } 0132 0133 QDomDocument document; 0134 document.setContent(reply); 0135 QString artist = document.elementsByTagName("artist").at(0).toElement().text(); 0136 QString title = document.elementsByTagName("song").at(0).toElement().text(); 0137 0138 QUrl url = BASE_LYRICS_URL; 0139 url.setPath("/api.php"); 0140 0141 QUrlQuery urlQuery; 0142 urlQuery.addQueryItem("action", "query"); 0143 urlQuery.addQueryItem("prop", "revisions"); 0144 urlQuery.addQueryItem("rvprop", "content"); 0145 urlQuery.addQueryItem("format", "xml"); 0146 urlQuery.addQueryItem("titles", artist + ':' + title); 0147 url.setQuery(urlQuery); 0148 0149 connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveLyricsReply(QNetworkReply*))); 0150 m_networkAccessManager->get(QNetworkRequest(url)); 0151 } 0152 0153 void LyricsWidget::receiveLyricsReply(QNetworkReply* reply) 0154 { 0155 disconnect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveLyricsReply(QNetworkReply*))); 0156 if (reply->error() != QNetworkReply::NoError) { 0157 qCWarning(JUK_LOG) << "Error while fetching lyrics: " << reply->errorString(); 0158 setHtml(i18n("<span style='color:red'>Error while retrieving lyrics!</span>")); 0159 return; 0160 } 0161 const QUrlQuery replyUrlQuery(reply->url()); 0162 QString titlesUrlPart = replyUrlQuery.queryItemValue(QStringLiteral("titles"), QUrl::FullyEncoded); 0163 if (titlesUrlPart.isEmpty()) { 0164 // default homepage, but this code path should never happen at this point. 0165 titlesUrlPart = QStringLiteral("Lyrics_Wiki"); 0166 } 0167 const QString lyricsUrl = BASE_LYRICS_URL.toString() + QStringLiteral("wiki/") + titlesUrlPart; 0168 0169 QString content = QString::fromUtf8(reply->readAll()); 0170 int lIndex = content.indexOf("<lyrics>"); 0171 int rIndex = content.indexOf("</lyrics>"); 0172 if (lIndex == -1 || rIndex == -1) { 0173 qCWarning(JUK_LOG) << Q_FUNC_INFO << "Unable to find lyrics in text"; 0174 setText(i18n("No lyrics available.")); 0175 return; 0176 } 0177 lIndex += 15; // We skip the tag 0178 content = content.mid(lIndex, rIndex - lIndex).trimmed(); 0179 content.replace('\n', "<br />"); 0180 //setText(content); 0181 setHtml("<h1>" + m_title + "</h1>" + 0182 content + 0183 i18n("<br /><br /><i>Lyrics provided by <a href='%1'>LyricWiki</a></i>", lyricsUrl)); 0184 }