mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-16 11:19:18 +01:00
Allow the artist and album to be specified separately when searching for album covers
This commit is contained in:
parent
2e9ec3e9d4
commit
bac414a630
@ -39,8 +39,9 @@ class AmazonCoverProvider(clementine.CoverProvider):
|
||||
|
||||
self.network = clementine.NetworkAccessManager()
|
||||
|
||||
def StartSearch(self, query, id):
|
||||
url = QUrl.fromEncoded(self.API_URL.format(self.PrepareAmazonRESTUrl(query)))
|
||||
def StartSearch(self, artist, album, id):
|
||||
query = self.PrepareAmazonRESTUrl(artist + " " + album)
|
||||
url = QUrl.fromEncoded(self.API_URL.format(query))
|
||||
LOGGER.debug("ID %d: Sending request to '%s'" % (id, url))
|
||||
|
||||
reply = self.network.get(QNetworkRequest(url))
|
||||
|
@ -25,8 +25,8 @@ class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
}
|
||||
self.network = clementine.NetworkAccessManager()
|
||||
|
||||
def StartSearch(self, query, id):
|
||||
url = self.GetQueryURL(query)
|
||||
def StartSearch(self, artist, album, id):
|
||||
url = self.GetQueryURL(artist + " " + album)
|
||||
LOGGER.info("Id %d - sending request to '%s'" % (id, url))
|
||||
|
||||
reply = self.network.get(QNetworkRequest(url))
|
||||
@ -34,12 +34,12 @@ class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
def QueryFinished():
|
||||
LOGGER.debug("Id %d - finished" % id)
|
||||
|
||||
self.SearchFinished(id, self.ParseReply(query, reply))
|
||||
self.SearchFinished(id, self.ParseReply(artist, album, reply))
|
||||
|
||||
reply.connect("finished()", QueryFinished)
|
||||
return True
|
||||
|
||||
def ParseReply(self, query, reply):
|
||||
def ParseReply(self, artist, album, reply):
|
||||
results = json.loads(str(reply.readAll()))
|
||||
|
||||
parsed = []
|
||||
@ -48,7 +48,9 @@ class GoogleImagesCoverProvider(clementine.CoverProvider):
|
||||
LOGGER.warning("Error parsing reply: %s", results["responseDetails"])
|
||||
return parsed
|
||||
|
||||
LOGGER.info("Parsing reply for query '%s'", query)
|
||||
query = "%s - %s" % (artist, album)
|
||||
|
||||
LOGGER.info("Parsing reply for query '%s'" % query)
|
||||
for result in results['responseData']['results']:
|
||||
current = clementine.CoverSearchResult()
|
||||
|
||||
|
@ -33,10 +33,11 @@ AlbumCoverFetcher::AlbumCoverFetcher(QObject* parent, QNetworkAccessManager* net
|
||||
connect(request_starter_, SIGNAL(timeout()), SLOT(StartRequests()));
|
||||
}
|
||||
|
||||
quint64 AlbumCoverFetcher::FetchAlbumCover(
|
||||
const QString& artist_name, const QString& album_name) {
|
||||
quint64 AlbumCoverFetcher::FetchAlbumCover(const QString& artist,
|
||||
const QString& album) {
|
||||
CoverSearchRequest request;
|
||||
request.query = artist_name + " " + album_name;
|
||||
request.artist = artist;
|
||||
request.album = album;
|
||||
request.search = false;
|
||||
request.id = next_id_ ++;
|
||||
|
||||
@ -44,9 +45,11 @@ quint64 AlbumCoverFetcher::FetchAlbumCover(
|
||||
return request.id;
|
||||
}
|
||||
|
||||
quint64 AlbumCoverFetcher::SearchForCovers(const QString &query) {
|
||||
quint64 AlbumCoverFetcher::SearchForCovers(const QString& artist,
|
||||
const QString& album) {
|
||||
CoverSearchRequest request;
|
||||
request.query = query;
|
||||
request.artist = artist;
|
||||
request.album = album;
|
||||
request.search = true;
|
||||
request.id = next_id_ ++;
|
||||
|
||||
@ -81,8 +84,8 @@ void AlbumCoverFetcher::StartRequests() {
|
||||
|
||||
// search objects are this fetcher's children so worst case scenario - they get
|
||||
// deleted with it
|
||||
AlbumCoverFetcherSearch* search = new AlbumCoverFetcherSearch(request, network_,
|
||||
this);
|
||||
AlbumCoverFetcherSearch* search = new AlbumCoverFetcherSearch(
|
||||
request, network_, this);
|
||||
active_requests_.insert(request.id, search);
|
||||
|
||||
connect(search, SIGNAL(SearchFinished(quint64, CoverSearchResults)),
|
||||
|
@ -38,8 +38,11 @@ class AlbumCoverFetcherSearch;
|
||||
struct CoverSearchRequest {
|
||||
// an unique (for one AlbumCoverFetcher) request identifier
|
||||
quint64 id;
|
||||
|
||||
// a search query
|
||||
QString query;
|
||||
QString artist;
|
||||
QString album;
|
||||
|
||||
// is this only a search request or should we also fetch the first
|
||||
// cover that's found?
|
||||
bool search;
|
||||
@ -77,7 +80,7 @@ class AlbumCoverFetcher : public QObject {
|
||||
|
||||
static const int kMaxConcurrentRequests;
|
||||
|
||||
quint64 SearchForCovers(const QString& query);
|
||||
quint64 SearchForCovers(const QString& artist, const QString& album);
|
||||
quint64 FetchAlbumCover(const QString& artist, const QString& album);
|
||||
|
||||
void Clear();
|
||||
|
@ -60,18 +60,19 @@ void AlbumCoverFetcherSearch::TerminateSearch() {
|
||||
void AlbumCoverFetcherSearch::Start() {
|
||||
CoverProviders* providers = &CoverProviders::instance();
|
||||
|
||||
// end this search before it even began if there are no providers...
|
||||
foreach(CoverProvider* provider, providers->List()) {
|
||||
connect(provider, SIGNAL(SearchFinished(int,QList<CoverSearchResult>)),
|
||||
SLOT(ProviderSearchFinished(int,QList<CoverSearchResult>)));
|
||||
const int id = providers->NextId();
|
||||
const bool success = provider->StartSearch(request_.query, id);
|
||||
const bool success = provider->StartSearch(
|
||||
request_.artist, request_.album, id);
|
||||
|
||||
if (success) {
|
||||
pending_requests_[id] = provider;
|
||||
}
|
||||
}
|
||||
|
||||
// end this search before it even began if there are no providers...
|
||||
if(pending_requests_.isEmpty()) {
|
||||
TerminateSearch();
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
// Starts searching for covers matching the given query text. Returns true
|
||||
// if the query has been started, or false if an error occurred. The provider
|
||||
// should remember the ID and emit it along with the result when it finishes.
|
||||
virtual bool StartSearch(const QString& query, int id) = 0;
|
||||
virtual bool StartSearch(const QString& artist, const QString& album, int id) = 0;
|
||||
|
||||
virtual void CancelSearch(int id) {}
|
||||
|
||||
|
@ -30,10 +30,10 @@ LastFmCoverProvider::LastFmCoverProvider(QObject* parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool LastFmCoverProvider::StartSearch(const QString& query, int id) {
|
||||
bool LastFmCoverProvider::StartSearch(const QString& artist, const QString& album, int id) {
|
||||
QMap<QString, QString> params;
|
||||
params["method"] = "album.search";
|
||||
params["album"] = query;
|
||||
params["album"] = album + " " + artist;
|
||||
|
||||
QNetworkReply* reply = lastfm::ws::post(params);
|
||||
connect(reply, SIGNAL(finished()), SLOT(QueryFinished()));
|
||||
|
@ -33,7 +33,7 @@ class LastFmCoverProvider : public CoverProvider {
|
||||
public:
|
||||
LastFmCoverProvider(QObject* parent);
|
||||
|
||||
bool StartSearch(const QString& query, int id);
|
||||
bool StartSearch(const QString& artist, const QString& album, int id);
|
||||
|
||||
private slots:
|
||||
void QueryFinished();
|
||||
|
@ -79,16 +79,16 @@ if (_wrapper) {
|
||||
}
|
||||
CoverProvider::CancelSearch(id);
|
||||
}
|
||||
bool PythonQtShell_CoverProvider::StartSearch(const QString& query, int id)
|
||||
bool PythonQtShell_CoverProvider::StartSearch(const QString& artist, const QString& album, int id)
|
||||
{
|
||||
if (_wrapper) {
|
||||
PyObject* obj = PyObject_GetAttrString((PyObject*)_wrapper, "StartSearch");
|
||||
PyErr_Clear();
|
||||
if (obj && !PythonQtSlotFunction_Check(obj)) {
|
||||
static const char* argumentList[] ={"bool" , "const QString&" , "int"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(3, argumentList);
|
||||
static const char* argumentList[] ={"bool" , "const QString&" , "const QString&" , "int"};
|
||||
static const PythonQtMethodInfo* methodInfo = PythonQtMethodInfo::getCachedMethodInfoFromArgumentList(4, argumentList);
|
||||
bool returnValue = 0;
|
||||
void* args[3] = {NULL, (void*)&query, (void*)&id};
|
||||
void* args[4] = {NULL, (void*)&artist, (void*)&album, (void*)&id};
|
||||
PyObject* result = PythonQtSignalTarget::call(obj, methodInfo, args, true);
|
||||
if (result) {
|
||||
args[0] = PythonQtConv::ConvertPythonToQt(methodInfo->parameters().at(0), result, false, NULL, &returnValue);
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
PythonQtShell_CoverProvider(const QString& name, QObject* parent):CoverProvider(name, parent),_wrapper(NULL) {};
|
||||
|
||||
virtual void CancelSearch(int id);
|
||||
virtual bool StartSearch(const QString& query, int id);
|
||||
virtual bool StartSearch(const QString& artist, const QString& album, int id);
|
||||
virtual void childEvent(QChildEvent* arg__1);
|
||||
virtual void customEvent(QEvent* arg__1);
|
||||
virtual bool event(QEvent* arg__1);
|
||||
|
@ -158,12 +158,7 @@ QString AlbumCoverChoiceController::LoadCoverFromURL(Song* song) {
|
||||
|
||||
QString AlbumCoverChoiceController::SearchForCover(Song* song) {
|
||||
// Get something sensible to stick in the search box
|
||||
QString query = song->artist();
|
||||
if (!query.isEmpty())
|
||||
query += " ";
|
||||
query += song->album();
|
||||
|
||||
QImage image = cover_searcher_->Exec(query);
|
||||
QImage image = cover_searcher_->Exec(song->artist(), song->album());
|
||||
|
||||
if(!image.isNull()) {
|
||||
QString cover = SaveCoverInCache(song->artist(), song->album(), image);
|
||||
|
@ -115,11 +115,12 @@ void AlbumCoverSearcher::Init(AlbumCoverFetcher* fetcher) {
|
||||
connect(fetcher_, SIGNAL(SearchFinished(quint64,CoverSearchResults)), SLOT(SearchFinished(quint64,CoverSearchResults)));
|
||||
}
|
||||
|
||||
QImage AlbumCoverSearcher::Exec(const QString &query) {
|
||||
ui_->query->setText(query);
|
||||
ui_->query->setFocus();
|
||||
QImage AlbumCoverSearcher::Exec(const QString& artist, const QString& album) {
|
||||
ui_->artist->setText(artist);
|
||||
ui_->album->setText(album);
|
||||
ui_->artist->setFocus();
|
||||
|
||||
if(!query.isEmpty()) {
|
||||
if(!artist.isEmpty() || !album.isEmpty()) {
|
||||
Search();
|
||||
}
|
||||
|
||||
@ -140,13 +141,14 @@ QImage AlbumCoverSearcher::Exec(const QString &query) {
|
||||
void AlbumCoverSearcher::Search() {
|
||||
ui_->busy->show();
|
||||
ui_->search->setEnabled(false);
|
||||
ui_->query->setEnabled(false);
|
||||
ui_->artist->setEnabled(false);
|
||||
ui_->album->setEnabled(false);
|
||||
ui_->covers->setEnabled(false);
|
||||
|
||||
model_->clear();
|
||||
cover_loading_tasks_.clear();
|
||||
|
||||
id_ = fetcher_->SearchForCovers(ui_->query->text());
|
||||
id_ = fetcher_->SearchForCovers(ui_->artist->text(), ui_->album->text());
|
||||
}
|
||||
|
||||
void AlbumCoverSearcher::SearchFinished(quint64 id, const CoverSearchResults& results) {
|
||||
@ -154,7 +156,8 @@ void AlbumCoverSearcher::SearchFinished(quint64 id, const CoverSearchResults& re
|
||||
return;
|
||||
|
||||
ui_->search->setEnabled(true);
|
||||
ui_->query->setEnabled(true);
|
||||
ui_->artist->setEnabled(true);
|
||||
ui_->album->setEnabled(true);
|
||||
ui_->covers->setEnabled(true);
|
||||
id_ = 0;
|
||||
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
|
||||
void Init(AlbumCoverFetcher* fetcher);
|
||||
|
||||
QImage Exec(const QString& query);
|
||||
QImage Exec(const QString& artist, const QString& album);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *);
|
||||
|
@ -17,9 +17,22 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="LineEdit" name="query">
|
||||
<widget class="LineEdit" name="artist">
|
||||
<property name="toolTip">
|
||||
<string>Artist</string>
|
||||
</property>
|
||||
<property name="hint" stdset="0">
|
||||
<string>Enter search terms here</string>
|
||||
<string>Artist</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LineEdit" name="album">
|
||||
<property name="toolTip">
|
||||
<string>Album</string>
|
||||
</property>
|
||||
<property name="hint" stdset="0">
|
||||
<string>Album</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -99,7 +112,8 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>query</tabstop>
|
||||
<tabstop>artist</tabstop>
|
||||
<tabstop>album</tabstop>
|
||||
<tabstop>search</tabstop>
|
||||
<tabstop>covers</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
@ -139,7 +153,7 @@
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>query</sender>
|
||||
<sender>artist</sender>
|
||||
<signal>returnPressed()</signal>
|
||||
<receiver>search</receiver>
|
||||
<slot>click()</slot>
|
||||
|
Loading…
Reference in New Issue
Block a user