diff --git a/CMakeLists.txt b/CMakeLists.txt index f855b40..b26deae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ set(WIDGETS_HEADER_FILES gui/tageditorwidget.h dbquery/dbquery.h dbquery/musicbrainz.h + dbquery/makeitpersonal.h dbquery/lyricswikia.h gui/dbquerywidget.h misc/networkaccessmanager.h @@ -96,6 +97,7 @@ set(WIDGETS_SRC_FILES gui/tageditorwidget.cpp dbquery/dbquery.cpp dbquery/musicbrainz.cpp + dbquery/makeitpersonal.cpp dbquery/lyricswikia.cpp gui/dbquerywidget.cpp misc/networkaccessmanager.cpp diff --git a/application/settings.cpp b/application/settings.cpp index 11b562d..be5e1c1 100644 --- a/application/settings.cpp +++ b/application/settings.cpp @@ -196,6 +196,7 @@ void restore() v.dbQuery.fields.restore(settings, QStringLiteral("fields")); v.dbQuery.musicBrainzUrl = settings.value(QStringLiteral("musicbrainzurl")).toString(); v.dbQuery.lyricsWikiaUrl = settings.value(QStringLiteral("lyricwikiurl")).toString(); + v.dbQuery.makeItPersonalUrl = settings.value(QStringLiteral("makeitpersonalurl")).toString(); v.dbQuery.coverArtArchiveUrl = settings.value(QStringLiteral("coverartarchiveurl")).toString(); settings.endGroup(); @@ -284,6 +285,7 @@ void save() v.dbQuery.fields.save(settings, QStringLiteral("fields")); settings.setValue(QStringLiteral("musicbrainzurl"), v.dbQuery.musicBrainzUrl); settings.setValue(QStringLiteral("lyricwikiurl"), v.dbQuery.lyricsWikiaUrl); + settings.setValue(QStringLiteral("makeitpersonalurl"), v.dbQuery.makeItPersonalUrl); settings.setValue(QStringLiteral("coverartarchiveurl"), v.dbQuery.coverArtArchiveUrl); settings.endGroup(); diff --git a/application/settings.h b/application/settings.h index 61d5df9..be97ac1 100644 --- a/application/settings.h +++ b/application/settings.h @@ -90,6 +90,7 @@ struct DbQuery { QString musicBrainzUrl; QString coverArtArchiveUrl; QString lyricsWikiaUrl; + QString makeItPersonalUrl; }; struct RenamingUtility { diff --git a/dbquery/dbquery.h b/dbquery/dbquery.h index 2ef0a10..cd1d93d 100644 --- a/dbquery/dbquery.h +++ b/dbquery/dbquery.h @@ -159,6 +159,7 @@ template inline void HttpResultsModel::addReply(QNetworkReply * QueryResultsModel *queryMusicBrainz(SongDescription &&songDescription); QueryResultsModel *queryLyricsWikia(SongDescription &&songDescription); QNetworkReply *queryCoverArtArchive(const QString &albumId); +QueryResultsModel *queryMakeItPersonal(SongDescription &&songDescription); } // namespace QtGui diff --git a/dbquery/makeitpersonal.cpp b/dbquery/makeitpersonal.cpp new file mode 100644 index 0000000..4733d36 --- /dev/null +++ b/dbquery/makeitpersonal.cpp @@ -0,0 +1,69 @@ +#include "./makeitpersonal.h" + +#include "../application/settings.h" +#include "../misc/networkaccessmanager.h" + +#include +#include +#include +#include + +#include + +using namespace std; +using namespace std::placeholders; +using namespace Utility; + +namespace QtGui { + +static const QString defaultMakeItPersonalUrl(QStringLiteral("https://makeitpersonal.co")); + +QUrl makeItPersonalApiUrl() +{ + const auto &makeItPersonalUrl = Settings::values().dbQuery.makeItPersonalUrl; + return QUrl((makeItPersonalUrl.isEmpty() ? defaultMakeItPersonalUrl : makeItPersonalUrl) + QStringLiteral("/lyrics")); +} + +MakeItPersonalResultsModel::MakeItPersonalResultsModel(SongDescription &&initialSongDescription, QNetworkReply *reply) + : HttpResultsModel(move(initialSongDescription), reply) +{ +} + +bool MakeItPersonalResultsModel::fetchLyrics(const QModelIndex &index) +{ + Q_UNUSED(index) + return true; // lyrics don't need to be fetched separately here +} + +void MakeItPersonalResultsModel::parseInitialResults(const QByteArray &data) +{ + // prepare parsing LyricsWikia meta data + beginResetModel(); + m_results.clear(); + + SongDescription desc = m_initialDescription; + desc.songId = m_initialDescription.artist + m_initialDescription.title; + desc.artistId = m_initialDescription.artist; + desc.lyrics = QString::fromUtf8(data).trimmed(); + if (desc.lyrics != QLatin1String("Sorry, We don't have lyrics for this song yet.")) { + m_results << move(desc); + } + + // promote changes + endResetModel(); +} + +QueryResultsModel *queryMakeItPersonal(SongDescription &&songDescription) +{ + // compose URL + QUrlQuery query; + query.addQueryItem(QStringLiteral("artist"), songDescription.artist); + query.addQueryItem(QStringLiteral("title"), songDescription.title); + QUrl url(makeItPersonalApiUrl()); + url.setQuery(query); + + // make request + return new MakeItPersonalResultsModel(move(songDescription), Utility::networkAccessManager().get(QNetworkRequest(url))); +} + +} // namespace QtGui diff --git a/dbquery/makeitpersonal.h b/dbquery/makeitpersonal.h new file mode 100644 index 0000000..e140508 --- /dev/null +++ b/dbquery/makeitpersonal.h @@ -0,0 +1,23 @@ +#ifndef QTGUI_MAKE_IT_PERSONAL_H +#define QTGUI_MAKE_IT_PERSONAL_H + +#include "./dbquery.h" + +#include + +namespace QtGui { + +class MakeItPersonalResultsModel : public HttpResultsModel { + Q_OBJECT + +public: + MakeItPersonalResultsModel(SongDescription &&initialSongDescription, QNetworkReply *reply); + bool fetchLyrics(const QModelIndex &index) override; + +protected: + void parseInitialResults(const QByteArray &data) override; +}; + +} // namespace QtGui + +#endif // QTGUI_MAKE_IT_PERSONAL_H diff --git a/gui/dbquerywidget.cpp b/gui/dbquerywidget.cpp index 67b26b9..16fabc8 100644 --- a/gui/dbquerywidget.cpp +++ b/gui/dbquerywidget.cpp @@ -84,6 +84,10 @@ DbQueryWidget::DbQueryWidget(TagEditorWidget *tagEditorWidget, QWidget *parent) m_searchLyricsWikiaAction->setIcon(searchIcon); m_searchLyricsWikiaAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); connect(m_searchLyricsWikiaAction, &QAction::triggered, this, &DbQueryWidget::searchLyricsWikia); + m_searchMakeItPersonalAction = m_menu->addAction(tr("Query makeitpersonal")); + m_searchMakeItPersonalAction->setIcon(searchIcon); + m_searchMakeItPersonalAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_K)); + connect(m_searchMakeItPersonalAction, &QAction::triggered, this, &DbQueryWidget::searchMakeItPersonal); m_menu->addSeparator(); m_insertPresentDataAction = m_menu->addAction(tr("Use present data as search criteria")); m_insertPresentDataAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); @@ -117,7 +121,11 @@ void DbQueryWidget::insertSearchTermsFromTagEdit(TagEdit *tagEdit, bool songSpec } // set album and artist - m_ui->albumLineEdit->setText(tagValueToQString(tagEdit->value(KnownField::Album))); + if (m_lastSearchAction == m_searchMakeItPersonalAction) { + m_ui->titleLineEdit->setText(tagValueToQString(tagEdit->value(KnownField::Title))); + } else { + m_ui->albumLineEdit->setText(tagValueToQString(tagEdit->value(KnownField::Album))); + } m_ui->artistLineEdit->setText(tagValueToQString(tagEdit->value(KnownField::Artist))); if (!songSpecific) { @@ -187,6 +195,30 @@ void DbQueryWidget::searchLyricsWikia() useQueryResults(queryLyricsWikia(currentSongDescription())); } +void DbQueryWidget::searchMakeItPersonal() +{ + m_lastSearchAction = m_searchMakeItPersonalAction; + + // check whether enough search terms are supplied + if (m_ui->artistLineEdit->text().isEmpty() || m_ui->titleLineEdit->text().isEmpty()) { + m_ui->notificationLabel->setNotificationType(NotificationType::Critical); + m_ui->notificationLabel->setText(tr("Insufficient search criteria supplied - artist and title are mandatory")); + return; + } + + // delete current model + m_ui->resultsTreeView->setModel(nullptr); + delete m_model; + + // show status + m_ui->notificationLabel->setNotificationType(NotificationType::Progress); + m_ui->notificationLabel->setText(tr("Retrieving lyrics from makeitpersonal ...")); + setStatus(false); + + // do actual query + useQueryResults(queryMakeItPersonal(currentSongDescription())); +} + void DbQueryWidget::abortSearch() { if (!m_model) { diff --git a/gui/dbquerywidget.h b/gui/dbquerywidget.h index 7dd9c3a..2239c37 100644 --- a/gui/dbquerywidget.h +++ b/gui/dbquerywidget.h @@ -38,6 +38,7 @@ public: public slots: void searchMusicBrainz(); void searchLyricsWikia(); + void searchMakeItPersonal(); void abortSearch(); void applySelectedResults(); void applySpecifiedResults(const QModelIndex &modelIndex); @@ -78,6 +79,7 @@ private: QAction *m_insertPresentDataAction; QAction *m_searchMusicBrainzAction; QAction *m_searchLyricsWikiaAction; + QAction *m_searchMakeItPersonalAction; QAction *m_lastSearchAction; QPoint m_contextMenuPos; };