From 9bc9b217ac179832bbfe0abbc17418d1ae78fc2b Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Thu, 7 Jul 2011 18:07:33 +0300 Subject: [PATCH] Free text search to look for better album art --- src/controller.py | 49 +++++++++++++++++++++++++++++++++++++++++-------- src/coverItem.py | 20 +++++++++++++++++++- src/coverModel.py | 23 +++++++++++++++++++++-- ui/Alternatives.qml | 16 ++++++++++++---- 4 files changed, 93 insertions(+), 15 deletions(-) diff --git a/src/controller.py b/src/controller.py index db4f296..3815d43 100644 --- a/src/controller.py +++ b/src/controller.py @@ -45,13 +45,30 @@ class MassiveDownloadsThread (QtCore.QThread): def run (self): print "Download one cover per-album in a thread" - import time - time.sleep (4) for albumItem in self.albumModel.get_albums (): if albumItem.require_download: self.downloader.get_album_art (albumItem) +class FreeSearchThread (QtCore.QThread): + + def __init__ (self, model, search_str): + QtCore.QThread.__init__ (self) + self.downloader = MussorgskyAlbumArt () + self.model = model + self.search_str = search_str + + def run (self): + print "Free search thread:", self.search_str + MAX_OPTIONS = 4 + counter = 0 + for img in self.downloader.get_alternatives_free_text (self.search_str): + if counter >= MAX_OPTIONS: + break + + self.model.updateData (counter, img) + counter += 1 + class MussorgskyController (QtCore.QObject): def __init__ (self, rootContext): @@ -91,20 +108,35 @@ class MussorgskyController (QtCore.QObject): m = CoversModel (albumItem) print m.rowCount () self.ctx.setContextProperty ("coversModel", m) + if self.download: + self.download.quit () self.download = DownloadThread (m, albumItem) self.download.start () + + @QtCore.Slot (QtCore.QObject, str) + def get_options_for_text (self, coversModel, search_str): + if self.download: + print "Finishing the previous work" + self.download.quit () + coversModel.reset () + self.download = FreeSearchThread (coversModel, search_str) + self.download.start () + + + @QtCore.Slot (QtCore.QObject, int) def save_option_for (self, coversModel, index): print "Saving option", index coverItem = coversModel.getData (index) - coverItem.save (coversModel.albumItem.get_aa ().get_media_art_path ()) - # Update the main model. Is this enough? - if not coverItem.initialImage and not coverItem.deleteAction: - coversModel.albumItem.album_art = None - coversModel.albumItem.album_art = coversModel.albumItem.get_aa().get_media_art_path () + + if coverItem.initialImage: + # Same image as before, nothing to do + pass elif coverItem.deleteAction: - coversModel.albumItem.resetAlbumArt () + coversModel.albumItem.unset_image () + else: + coversModel.albumItem.set_image (coverItem.url) coversModel.cleanCache () @@ -113,6 +145,7 @@ class MussorgskyController (QtCore.QObject): def stop_pending_jobs (self): if self.download : self.download.quit () + self.download = None def get_all_albums (self): """ diff --git a/src/coverItem.py b/src/coverItem.py index 5033364..d3d32d8 100644 --- a/src/coverItem.py +++ b/src/coverItem.py @@ -13,6 +13,7 @@ class CoverItem (QtCore.QObject): self.initialImage = initialImage self.deleteAction = deleteAction self._url = image + self._isBroken = False def _url (self): return self._url @@ -21,6 +22,19 @@ class CoverItem (QtCore.QObject): self._url = url self.url_changed.emit () + def _broken (self): + return self._isBroken + + def _setBroken (self, value): + if (self._isBroken != value): + print "broken is now", value + self._isBroken = value + self.broken_changed.emit () + + def reset (self): + self.url = None + self.broken = False + def save (self, destination): if self.initialImage: print " -> No changes" @@ -40,7 +54,11 @@ class CoverItem (QtCore.QObject): print "Removing", self.url if os.path.exists (self.url): os.remove (self.url) - + self._setUrl (None) url_changed = QtCore.Signal () url = QtCore.Property (unicode, _url, _setUrl, notify=url_changed) + + + broken_changed = QtCore.Signal () + broken = QtCore.Property (bool, _broken, _setBroken, notify=broken_changed) diff --git a/src/coverModel.py b/src/coverModel.py index 9e15909..2abcb55 100644 --- a/src/coverModel.py +++ b/src/coverModel.py @@ -14,7 +14,7 @@ class CoversModel (QtCore.QAbstractListModel): def __init__ (self, albumItem): QtCore.QAbstractListModel.__init__ (self) self.albumItem = albumItem - + self.__searchString = self.albumItem.artist + " " + self.albumItem.title self.startOffset = 2 self._alternatives = [ CoverItem (self.albumItem.album_art, initialImage=True), @@ -36,14 +36,24 @@ class CoversModel (QtCore.QAbstractListModel): return None def updateData (self, row, url): + print "updating", row, "to", url position = row + self.startOffset assert position >= 0 and position < len (self._alternatives) - self._alternatives[position].url = url + if url == None: + self._alternatives[position].url = "images/broken.png" + self._alternatives[position].broken = True + else: + self._alternatives[position].url = url def getData (self, row): assert row >= 0 and row < len (self._alternatives) return self._alternatives[row] + def reset (self): + for i in range (self.startOffset, len (self._alternatives)): + self._alternatives[i].reset () + + def cleanCache (self): """ The model contains the urls of the downloaded alternatives. @@ -54,3 +64,12 @@ class CoversModel (QtCore.QAbstractListModel): # This url can be None if the image didn't finish downloading if self._alternatives[i].url and os.path.exists (self._alternatives[i].url): os.remove (self._alternatives[i].url) + + def _searchString (self): + return self.albumItem.artist + " " + self.albumItem.title + def _setSearchString (self, searchStr): + self.searchString = searchStr + searchString_changed.emit () + + searchString_changed = QtCore.Signal () + searchString = QtCore.Property (unicode, _searchString, _setSearchString, notify=searchString_changed) diff --git a/ui/Alternatives.qml b/ui/Alternatives.qml index a92a444..c37b1b2 100644 --- a/ui/Alternatives.qml +++ b/ui/Alternatives.qml @@ -35,7 +35,7 @@ Page { id: coversView model: coversModel anchors.top: titleArea.bottom - anchors.bottom : coversAlternativesPage.bottom + anchors.bottom : searchBox.top anchors.left: coversAlternativesPage.left anchors.right: coversAlternativesPage.right cellWidth: 160 @@ -68,16 +68,24 @@ Page { MouseArea { anchors.fill: coverPaintArea - enabled: !loadingIndicator.running + enabled: (!loadingIndicator.running && !model.cover.broken) onClicked: { - console.log ("wohooo") missionControl.save_option_for (coversModel, index) backButton.clicked () } } - } } } + SearchBox { + id: searchBox + text: coversModel.searchString + anchors.bottom: coversAlternativesPage.bottom + onSelected: { + console.log ("Now search:", search_text) + missionControl.get_options_for_text (coversModel, search_text) + } + } + } -- 1.7.9.5