From cc4a215a2fb8f94ddf1677d8ab7bd1098b412705 Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Thu, 7 Apr 2011 10:21:08 +0300 Subject: [PATCH 1/1] QML: Click on album shows the alternatives and saves them Album doesn't show yet the new selected image --- src/qml/aa_search.py | 17 +++++++++++------ src/qml/albumItem.py | 22 +++++++++++++++------- src/qml/albumModel.py | 4 ++++ src/qml/controller.py | 36 +++++++++++++++++++++++++++++++++--- src/qml/coverItem.py | 12 ++++++++++-- src/qml/coverModel.py | 25 ++++++++++++++++++++----- ui/Alternatives.qml | 14 +++++++++++--- ui/main.qml | 7 ++++++- 8 files changed, 110 insertions(+), 27 deletions(-) diff --git a/src/qml/aa_search.py b/src/qml/aa_search.py index ba65244..edf39a3 100644 --- a/src/qml/aa_search.py +++ b/src/qml/aa_search.py @@ -40,10 +40,12 @@ CACHE_LOCATION = os.path.join (os.getenv ("HOME"), ".cache", "mussorgsky") import threading class AADownloadThread (threading.Thread): - def __init__ (self, url, counter): + def __init__ (self, url, artist, album, counter): threading.Thread.__init__ (self, target=self.grab_image, args=(url,)) self.thumbnailer = LocalThumbnailer () self.counter = counter + self.artistName = artist.replace (" ", "_") + self.albumName = album.replace (" ", "_") self.image_path = None self.thumb_path = None self.urllib_wrapper = UrllibWrapper () @@ -52,8 +54,8 @@ class AADownloadThread (threading.Thread): print "Working", self.counter image = self.urllib_wrapper.get_url (image_url) if (image): - self.image_path = os.path.join (CACHE_LOCATION, "alternative-" + str(self.counter)) - self.thumb_path = os.path.join (CACHE_LOCATION, "alternative-" + str(self.counter) + "thumb") + self.image_path = os.path.join (CACHE_LOCATION, self.artistName + self.albumName + str(self.counter)) + self.thumb_path = os.path.join (CACHE_LOCATION, self.artistName + self.albumName + str(self.counter) + "thumb") self.urllib_wrapper.save_content_into_file (image, self.image_path) self.thumbnailer.create (self.image_path, self.thumb_path) @@ -119,13 +121,13 @@ class MussorgskyAlbumArt: return a list of paths of possible album arts """ results_page = self.__msn_images (artist, album) - return self.__process_results_page (results_page, max_alternatives) + return self.__process_results_page (results_page, artist, album, max_alternatives) def get_alternatives_free_text (self, search_text, max_alternatives=4): results_page = self.__msn_images_free_text (search_text) return self.__process_results_page (results_page, max_alternatives) - def __process_results_page (self, results_page, max_alternatives): + def __process_results_page (self, results_page, artist, album, max_alternatives): counter = 0 threads = [] for image_url in self.__get_url_from_msn_results_page (results_page): @@ -136,7 +138,7 @@ class MussorgskyAlbumArt: if (counter >= max_alternatives): break - t = AADownloadThread (image_url, counter) + t = AADownloadThread (image_url, artist, album, counter) t.start () threads.append (t) counter += 1 @@ -150,6 +152,9 @@ class MussorgskyAlbumArt: def save_alternative (self, artist, album, img_path, thumb_path): + """ + This is done now in the controller + """ if not os.path.exists (img_path) or not os.path.exists (thumb_path): print "**** CRITICAL **** image in path", path, "doesn't exist!" return (None, None) diff --git a/src/qml/albumItem.py b/src/qml/albumItem.py index 377d324..6d13ff6 100644 --- a/src/qml/albumItem.py +++ b/src/qml/albumItem.py @@ -20,13 +20,21 @@ class AlbumItem (QtCore.QObject): def _artist (self): return self._artist - def _album_art (self): + def _albumArt (self): return self._album_art - @QtCore.Signal - def changed (self): pass - - title = QtCore.Property (unicode, _title, notify=changed) - artist = QtCore.Property (unicode, _artist, notify=changed) - album_art = QtCore.Property (unicode, _album_art, notify=changed) + def _setAlbumArt (self, path): + print "Setting the new album art to", path + self._album_art = path + self.album_art_changed.emit () + + prop_changed = QtCore.Signal () + album_art_changed = QtCore.Signal () + + title = QtCore.Property (unicode, _title, notify=prop_changed) + artist = QtCore.Property (unicode, _artist, notify=prop_changed) + album_art = QtCore.Property (unicode, + _albumArt, + _setAlbumArt, + notify=album_art_changed) diff --git a/src/qml/albumModel.py b/src/qml/albumModel.py index 12ef53f..7e1708f 100644 --- a/src/qml/albumModel.py +++ b/src/qml/albumModel.py @@ -22,3 +22,7 @@ class AlbumModel (QtCore.QAbstractListModel): if index.isValid () and role == AlbumModel.COLUMNS.index ('album'): return self._albums[index.row ()] return None + + def updateThumb (self, row, url): + assert row >= 0 and row < len (self._albums) + self._albums[row].album_art = url diff --git a/src/qml/controller.py b/src/qml/controller.py index 618b973..6c5bee9 100644 --- a/src/qml/controller.py +++ b/src/qml/controller.py @@ -10,7 +10,7 @@ from aa_search import MussorgskyAlbumArt from tracker_backend_gi import TrackerBackendGI from albumItem import AlbumItem -from aa_spec import getCoverArtThumbFileName +from aa_spec import getCoverArtThumbFileName, getCoverArtFileName class DownloadThread (QtCore.QThread): @@ -30,8 +30,7 @@ class DownloadThread (QtCore.QThread): if counter >= MAX_OPTIONS: break - print counter, "Setting url", img - self.model.updateData (counter, img) + self.model.updateData (counter, img, thumb) counter += 1 @@ -52,6 +51,37 @@ class MussorgskyController (QtCore.QObject): self.download = DownloadThread (model, album) self.download.start () + @QtCore.Slot (QtCore.QObject, QtCore.QObject) + def albumSelected (self, model, album): + """ + Starts a thread to look for possible images online. + The thread will update the model (and the changes are visible in the UI) + """ + print "clicked on", album.title + self.download = DownloadThread (model, album) + self.download.start () + + @QtCore.Slot (str, QtCore.QObject) + def coverSelected (self, coverObject, albumObject): + """ + The user has clicked in one cover! + """ + print "Selected cover" + filename = getCoverArtFileName (albumObject.title) + thumbnail = getCoverArtThumbFileName (albumObject.title) + + os.rename (cover.url, filename) + os.rename (cover.thumb, thumbnail) + + albumObject.album_art = thumbnail + albumObject.album_art_changed.emit () + + @QtCore.Slot (QtCore.QObject) + def resetAlternatives (self, coversModel): + print "Reseting alternatives", coversModel + QtGui.QPixmapCache.clear () + coversModel.resetAlternatives () + def get_all_albums (self): """ diff --git a/src/qml/coverItem.py b/src/qml/coverItem.py index a9fb71e..36e291a 100644 --- a/src/qml/coverItem.py +++ b/src/qml/coverItem.py @@ -8,10 +8,11 @@ from PySide import QtDeclarative class CoverItem (QtCore.QObject): - def __init__ (self, url): + def __init__ (self, url, thumb): QtCore.QObject.__init__(self) self._url = url - + self._thumb = thumb + def _url (self): return self._url @@ -19,6 +20,13 @@ class CoverItem (QtCore.QObject): self._url = url self.url_changed.emit () + def _thumb (self): + return self._thumb + + def _setThumb (self, thumb): + self._thumb = thumb + url_changed = QtCore.Signal () url = QtCore.Property (unicode, _url, _setUrl, notify=url_changed) + thumb = QtCore.Property (unicode, _thumb, _setThumb) diff --git a/src/qml/coverModel.py b/src/qml/coverModel.py index d3d8578..e60600f 100644 --- a/src/qml/coverModel.py +++ b/src/qml/coverModel.py @@ -14,10 +14,10 @@ class CoversModel (QtCore.QAbstractListModel): def __init__ (self): QtCore.QAbstractListModel.__init__ (self) self._alternatives = [ - CoverItem ("images/button-red.png"), - CoverItem ("images/button-blue.png"), - CoverItem ("images/button-red.png"), - CoverItem ("images/button-blue.png") + CoverItem ("images/button-red.png", None), + CoverItem ("images/button-blue.png", None), + CoverItem ("images/button-red.png", None), + CoverItem ("images/button-blue.png", None) ] self.setRoleNames (dict(enumerate(CoversModel.COLUMNS))) @@ -29,6 +29,21 @@ class CoversModel (QtCore.QAbstractListModel): return self._alternatives[index.row ()] return None - def updateData (self, row, url): + def updateData (self, row, url, thumb): assert row >= 0 and row < len (self._alternatives) + print "Replacing", self._alternatives[row].url, "with", url, "in row", row self._alternatives[row].url = url + self._alternatives[row].thumb = thumb + + def resetAlternatives (self): + for row in range (0, len (self._alternatives)): + print "Removing cached images:" + print " ", self._alternatives[row].url + print " ", self._alternatives[row].thumb + os.remove (self._alternatives[row].url) + os.remove (self._alternatives[row].thumb) + if (row % 2) == 0: + self.updateData(row, "images/button-red.png", None) + else: + self.updateData(row, "images/button-blue.png", None) + print "Ok" diff --git a/ui/Alternatives.qml b/ui/Alternatives.qml index 2b529dc..44644fb 100644 --- a/ui/Alternatives.qml +++ b/ui/Alternatives.qml @@ -10,7 +10,11 @@ Item { Row { id: coversAlternatives - property alias model: imagesLoop.model + property alias altmodel: imagesLoop.model + property variant selectedAlbum + property variant mc + + signal done anchors.horizontalCenter : parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter @@ -19,13 +23,17 @@ Row { Repeater { id: imagesLoop - model: 5 delegate: Component { ClickeableImage { source: model.cover.url width: 120 height: 120 - onClicked: { console.log (model.cover.url) } + onClicked: { + console.log (model.cover.url) + mc.coverSelected (model.cover, selectedAlbum) + mc.resetAlternatives (altmodel) + coversAlternatives.done () + } } } } diff --git a/ui/main.qml b/ui/main.qml index f2b0663..2ce794a 100644 --- a/ui/main.qml +++ b/ui/main.qml @@ -35,12 +35,17 @@ Rectangle { onRowSelected: { screen.state = "in_alternativesPage" missionControl.albumSelected (coversModel, album) + alternativesPage.selectedAlbum = album } } Alternatives { id:alternativesPage - model: coversModel + altmodel: coversModel + mc: missionControl + onDone: { + screen.state = "in_albumsPage" + } } states: [ -- 1.7.9.5