Big changes all around. Basic download works.
authorIvan Frade <ivan.frade@gmail.com>
Fri, 1 Jul 2011 14:59:36 +0000 (17:59 +0300)
committerIvan Frade <ivan.frade@gmail.com>
Fri, 1 Jul 2011 14:59:36 +0000 (17:59 +0300)
src/qml/aa_search.py
src/qml/albumItem.py
src/qml/albumModel.py
src/qml/controller.py
src/qml/coverItem.py
src/qml/coverModel.py
src/qml/mussorgsky-qml.py
ui/AlbumsPage.qml
ui/Alternatives.qml
ui/Mussorgsky.qml
ui/main.qml

index edf39a3..6eaab7a 100644 (file)
@@ -1,25 +1,10 @@
 #!/usr/bin/env python2.5
 import os
-from aa_spec import getCoverArtFileName, getCoverArtThumbFileName, get_thumb_filename_for_path
 from utils import UrllibWrapper
 import dbus, time
 import string
 import urllib
 
-try:
-    import libxml2
-    libxml_available = True
-except ImportError:
-    libxml_available = False
-
-try:
-    import PIL
-    import Image
-except ImportError:
-    import sys
-    print "Please install python-imaging package"
-    sys.exit (-1)
-
 
 LASTFM_APIKEY = "1e1d53528c86406757a6887addef0ace"
 BASE_LASTFM = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo"
@@ -42,12 +27,10 @@ class AADownloadThread (threading.Thread):
 
     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 ()
 
     def grab_image (self, image_url):
@@ -55,12 +38,10 @@ class AADownloadThread (threading.Thread):
         image = self.urllib_wrapper.get_url (image_url)
         if (image):
             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)
         
     def get_result (self):
-        return self.image_path, self.thumb_path
+        return self.image_path
 
 
 
@@ -72,7 +53,6 @@ class MussorgskyAlbumArt:
         if (not os.path.exists (CACHE_LOCATION)):
             os.makedirs (CACHE_LOCATION)
             
-        self.thumbnailer = LocalThumbnailer ()
         self.urllib_wrapper = UrllibWrapper ()
 
     def get_possible_url (self, artist, album, amount=4):
@@ -80,45 +60,28 @@ class MussorgskyAlbumArt:
             return self.__get_url_from_msn_results_page (results_page)
         
 
-    def get_album_art (self, artist, album, force=False):
+    def get_album_art (self, albumItem, force=False):
         """
-        Return a tuple (album_art, thumbnail_album_art)
+        Save the first available result as the albumart for that item
         """
-        filename = getCoverArtFileName (album)
-        thumbnail = getCoverArtThumbFileName (album)
-
-        album_art_available = False
+        filename = albumItem.get_aa().get_media_art_path ()
         if (os.path.exists (filename) and not force):
             print "Album art already there " + filename
-            album_art_available = True
-        else:
-            results_page = self.__msn_images (artist, album)
-            for online_resource in self.__get_url_from_msn_results_page (results_page):
-                print "Choosed:", online_resource
-                content = self.urllib_wrapper.get_url (online_resource)
-                if (content):
-                    print "Albumart: %s " % (filename)
-                    self.urllib_wrapper.save_content_into_file (content, filename)
-                    album_art_available = True
-                    break
-
-        if (not album_art_available):
-            return (None, None)
-
-        if (not os.path.exists (thumbnail) or force or album_art_available):
-            if (not self.__request_thumbnail (filename)):
-                print "Failed doing thumbnail. Probably album art is not an image!"
-                os.remove (filename)
-                return (None, None)
-        else:
-            print "Thumbnail exists (and probably valid) " + thumbnail
-            
-        return (filename, thumbnail)
+            return
 
+        results_page = self.__msn_images (albumItem.artist, albumItem.title)
+        for online_resource in self.__get_url_from_msn_results_page (results_page):
+            print "Trying:", online_resource
+            content = self.urllib_wrapper.get_url (online_resource)
+            if (content):
+                print "Saved on: %s " % (filename)
+                self.urllib_wrapper.save_content_into_file (content, filename)
+                albumItem.album_art = filename
+                break
 
     def get_alternatives (self, artist, album, max_alternatives=4):
         """
-        return a list of paths of possible album arts
+        return a list of pairs (image/
         """
         results_page = self.__msn_images (artist, album)
         return self.__process_results_page (results_page, artist, album, max_alternatives)
@@ -146,7 +109,7 @@ class MussorgskyAlbumArt:
         for t in threads:
             t.join (5)
             if (t.isAlive ()):
-                yield (None, None)
+                yield None
             else:
                 yield t.get_result ()
             
@@ -246,29 +209,6 @@ class MussorgskyAlbumArt:
         clean = clean.replace (" CD1", "").replace(" CD2", "")
         return urllib.quote(clean)
 
-    def __request_thumbnail (self, filename):
-        thumbFile = get_thumb_filename_for_path (filename)
-        return self.thumbnailer.create (filename, thumbFile)
-            
-
-
-class LocalThumbnailer:
-    def __init__ (self):
-        self.THUMBNAIL_SIZE = (124,124)
-
-    def create (self, fullCoverFileName, thumbFile):
-        if (os.path.exists (fullCoverFileName)):
-            try:
-                image = Image.open (fullCoverFileName)
-                image = image.resize (self.THUMBNAIL_SIZE, Image.ANTIALIAS )
-                image.save (thumbFile, "JPEG")
-                print "Thumbnail: " + thumbFile
-            except IOError, e:
-                print e
-                return False
-        return True
-            
-
 
 if __name__ == "__main__":
     import sys
index 6d13ff6..7689db4 100644 (file)
@@ -5,14 +5,24 @@ from PySide import QtCore
 from PySide import QtGui
 from PySide import QtDeclarative
 
+from albumArt import AlbumArt
 
 class AlbumItem (QtCore.QObject):
 
-    def __init__ (self, title, artist, album_art):
+    def __init__ (self, title, artist):
         QtCore.QObject.__init__(self)
         self._title = title
         self._artist = artist
-        self._album_art = album_art
+        self.aa = AlbumArt (self._title, self._artist)
+        self.require_download = False
+        if os.path.exists (self.aa.get_media_art_path ()):
+            self._album_art = self.aa.get_media_art_path ()
+        elif os.path.exists (self.aa.get_generated ()):
+            self._album_art = self.aa.get_generated ()
+            self.require_download = True
+        else:
+            self.require_download = True
+            self._album_art = None
 
     def _title (self):
         return self._title
@@ -25,9 +35,13 @@ class AlbumItem (QtCore.QObject):
 
     def _setAlbumArt (self, path):
         print "Setting the new album art to", path
+        self.require_download = False
         self._album_art = path
         self.album_art_changed.emit ()
-    
+
+    def get_aa (self):
+        return self.aa
+
     prop_changed = QtCore.Signal ()
     album_art_changed = QtCore.Signal ()
 
index b93f5de..a8190c9 100644 (file)
@@ -31,3 +31,6 @@ class AlbumModel (QtCore.QAbstractListModel):
         print "Changing album_art from",self._albums[row].album_art, "to:", url
         assert row >= 0 and row < len (self._albums)
         self._albums[row].album_art = url
+
+    def get_albums (self):
+        return self._albums
index ecbdc89..53b99ce 100644 (file)
@@ -13,8 +13,7 @@ except ImportError:
     from tracker_backend_dbus import TrackerBackendDBus as TrackerBackend
 
 from albumItem import AlbumItem
-from aa_spec import getCoverArtThumbFileName, getCoverArtFileName
-
+from coverModel import CoversModel 
 
 class DownloadThread (QtCore.QThread):
 
@@ -28,55 +27,77 @@ class DownloadThread (QtCore.QThread):
         print "Running the thread"
         MAX_OPTIONS = 4
         counter = 0
-        for img, thumb in self.downloader.get_alternatives (self.album.artist,
-                                                            self.album.title, MAX_OPTIONS):
+        for img in self.downloader.get_alternatives (self.album.artist,
+                                                     self.album.title, MAX_OPTIONS):
             if counter >= MAX_OPTIONS:
                 break
 
-            self.model.updateData (counter, img, thumb)
+            self.model.updateData (counter, img)
             counter += 1
 
 
 class MussorgskyController (QtCore.QObject):
 
-    def __init__ (self):
+    def __init__ (self, rootContext):
         QtCore.QObject.__init__ (self)
         self.download = None
+        self.ctx = rootContext 
         self.tracker = TrackerBackend ()
 
-    @QtCore.Slot (QtCore.QObject, QtCore.QObject)
-    def albumSelected (self, coversModel, 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 (coversModel, album)
-        self.download.start ()
-
-    @QtCore.Slot (QtCore.QObject, QtCore.QObject, int)
-    def coverSelected (self, coverObject, albumModel, index):
-        """
-        The user has clicked in one cover!
-        """
-        albumObject = albumModel.getAlbumInRow (index)
-        
-        print "Selected cover", albumObject.title
-        filename = getCoverArtFileName (albumObject.title)
-        thumbnail = getCoverArtThumbFileName (albumObject.title)
-
-        coverObject.save (filename, thumbnail)
+#    @QtCore.Slot (QtCore.QObject, QtCore.QObject, int)
+#    def coverSelected (self, coverObject, albumModel, index):
+#        """
+#        The user has clicked in one cover!
+#        """
+#        albumObject = albumModel.getAlbumInRow (index)
+#        
+#        print "Selected cover", albumObject.title
+#        filename = getCoverArtFileName (albumObject.title)
+#        thumbnail = getCoverArtThumbFileName (albumObject.title)
+#
+#        coverObject.save (filename, thumbnail)
+#
+#        albumModel.updateThumb (index, filename)
+#        #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 ()
 
-        albumModel.updateThumb (index, filename)
-        #albumObject.album_art = thumbnail
-        albumObject.album_art_changed.emit ()
+    @QtCore.Slot (QtCore.QObject)
+    def download_all (self, albumModel):
+        print "well, we will do as soon as possible"
+        downloader = MussorgskyAlbumArt ()
+        for albumItem in albumModel.get_albums ():
+            if albumItem.require_download:
+                downloader.get_album_art (albumItem)
 
     @QtCore.Slot (QtCore.QObject)
-    def resetAlternatives (self, coversModel):
-        print "Reseting alternatives", coversModel
-        QtGui.QPixmapCache.clear ()
-        coversModel.resetAlternatives ()
+    def get_options_for (self, albumItem):
+        print "Getting options for", albumItem.title
+        m = CoversModel (albumItem)
+        print m.rowCount ()
+        self.ctx.setContextProperty ("coversModel", m)
+        self.download = DownloadThread (m, albumItem)
+        self.download.start ()
 
+    @QtCore.Slot (QtCore.QObject, int)
+    def save_option_for (self, coversModel, index):
+        print "Saving option", index
+        coverItem = coversModel.getData (index)
+        print "Moving image:", coverItem.url, "to", coversModel.albumItem.get_aa ().get_media_art_path ()
+        os.rename (coverItem.url, coversModel.albumItem.get_aa().get_media_art_path ())
+        # Update the main model. Is this enough?
+        coversModel.albumItem.album_art = None
+        coversModel.albumItem.album_art = coversModel.albumItem.get_aa().get_media_art_path ()
+
+    @QtCore.Slot ()
+    def stop_pending_jobs (self):
+        if self.download :
+            self.download.quit ()
 
     def get_all_albums (self):
         """
@@ -85,9 +106,5 @@ class MussorgskyController (QtCore.QObject):
         """
         results = []
         for album_title, album_artist in self.tracker.get_all_albums ():
-            album_art = getCoverArtThumbFileName (album_title)
-            if (not os.path.exists (album_art)):
-                album_art = None
-            
-            results.append (AlbumItem (album_title, album_artist, album_art))
+            results.append (AlbumItem (album_title, album_artist))
         return results
index 41b21fa..5f429a4 100644 (file)
@@ -12,7 +12,6 @@ class CoverItem (QtCore.QObject):
         QtCore.QObject.__init__(self)
         self._initial_image = initial_image
         self._url = initial_image
-        self._thumb = None
         
     def _url (self):
         return self._url
@@ -21,32 +20,23 @@ class CoverItem (QtCore.QObject):
         self._url = url
         self.url_changed.emit ()
 
-    def _thumb (self):
-        return self._thumb
 
-    def _setThumb (self, thumb):
-        self._thumb = thumb
-
-    def reset (self):
-        cached_image = self._url
-        if cached_image and os.path.exists (cached_image):
-            os.remove (cached_image)
-            
-        cached_thumb = self._thumb
-        if cached_thumb and os.path.exists (cached_thumb):
-            os.remove (cached_thumb)
-
-        self.url = self._initial_image
-        self.url_changed.emit ()
+#    def reset (self):
+#        cached_image = self._url
+#        if cached_image and os.path.exists (cached_image):
+#            os.remove (cached_image)
+#            
+#        if cached_thumb and os.path.exists (cached_thumb):
+#            os.remove (cached_thumb)
+#
+#        self.url = self._initial_image
+#        self.url_changed.emit ()
 
     def save (self, cover, thumbnail):
         assert not self.url == self._initial_image
         os.rename (self.url, cover)
-        os.rename (self.thumb, thumbnail)
-
 
 
     url_changed = QtCore.Signal ()
 
     url = QtCore.Property (unicode, _url, _setUrl, notify=url_changed)
-    thumb = QtCore.Property (unicode, _thumb, _setThumb)
index 25b9af3..19442bb 100644 (file)
@@ -6,13 +6,14 @@ from PySide import QtGui
 from PySide import QtDeclarative
 
 from coverItem import CoverItem
-
+from albumItem import AlbumItem
 
 class CoversModel (QtCore.QAbstractListModel):
     COLUMNS = ('cover', )
 
-    def __init__ (self):
+    def __init__ (self, albumItem):
         QtCore.QAbstractListModel.__init__ (self)
+        self.albumItem = albumItem
         self._alternatives = [
              CoverItem ("images/button-red.png"),
              CoverItem ("images/button-blue.png"),
@@ -29,12 +30,15 @@ class CoversModel (QtCore.QAbstractListModel):
             return self._alternatives[index.row ()]
         return None
 
-    def updateData (self, row, url, thumb):
+    def updateData (self, row, url):
         assert row >= 0 and row < len (self._alternatives)
         self._alternatives[row].url = url
-        self._alternatives[row].thumb = thumb
 
-    def resetAlternatives (self):
-        print "Resseting alternatives"
-        for cover in self._alternatives:
-            cover.reset ()
+    def getData (self, row):
+        assert row >= 0 and row < len (self._alternatives)
+        return self._alternatives[row]
+
+#    def resetAlternatives (self):
+#        print "Resseting alternatives"
+#        for cover in self._alternatives:
+#            cover.reset ()
index b88ef74..bc97a75 100644 (file)
@@ -8,32 +8,28 @@ from PySide.QtDeclarative import QDeclarativeView
 
 from albumModel import AlbumModel
 from controller import MussorgskyController
-from coverModel import CoversModel
 
 # Create Qt application and the QDeclarative view
 app = QApplication(sys.argv)
 view = QDeclarativeView()
 
+controller = MussorgskyController (view.rootContext ())
 
-#MOCK_DATA = [
-#     AlbumItem ("Are you experienced?", "Jimy Hendrix", None),
-#     AlbumItem ("Bring them all back home", "Bob dylan", None),
-#     AlbumItem ("OK computer", "Radiohead", None),
-#     AlbumItem ("Absolution", "Muse", None),
-#     AlbumItem ("Come with us", "Chemical brothers", None)
-#    ]
+#from albumItem import AlbumItem
+#MOCK_DATA = [AlbumItem (u"x", u"y") for i in xrange (0, 100)]
+#albumModel = AlbumModel (MOCK_DATA)
 
-
-controller = MussorgskyController ()
 albumModel = AlbumModel (controller.get_all_albums())
 print "Model with", albumModel.rowCount(), "rows"
 
-coverModel = CoversModel ()
+#from coverModel import CoversModel
+#coverModel = CoversModel ()
 
 rc = view.rootContext ()
 rc.setContextProperty ('albumModel', albumModel)
 rc.setContextProperty ('missionControl', controller)
-rc.setContextProperty ('coversModel', coverModel)
+#rc.setContextProperty ('coversModel', coverModel)
+
 # Create an URL to the QML file
 #url = QUrl('view.qml')
 url = QUrl ("../../ui/main.qml")
index 2c6fd6e..bb297a4 100644 (file)
@@ -1,14 +1,12 @@
 import QtQuick 1.1
 import com.meego 1.0
 
-Page {
+
+PageStack {
     id: albumsPage
-    tools: commonTools
 
     anchors.fill: parent
 
-    signal rowSelected (int index, variant selectedAlbum)
-
     GridView { 
         id: albumsView
         model: albumModel
@@ -25,21 +23,26 @@ Page {
               
               Image {
                  id: cover
-                 source: model.album.album_art // || "images/button-blue.png"
-                 //anchors.fill: parent
+                 source: model.album.album_art 
+                 width: parent.width
+                 height: parent.height
+                 cache: false
                  anchors.centerIn: parent
               }              
               
               Text {
                  id: t
-                 text: model.album.title
-                 visible: (model.album.album_art != null)
+                 text: "xxx"
+                 visible: (model.album.album_art == null)
               }
-              
 
               MouseArea {
                    anchors.fill: albumPaintArea
-                   onClicked: { albumsPage.rowSelected (index, model.album) }
+                   onClicked: {
+                      console.log (model.album.title)
+                      missionControl.get_options_for (model.album)
+                      pageStack.push(Qt.createComponent("Alternatives.qml"))
+                   }
               }
 
         }
index 41bab39..1fab2bb 100644 (file)
@@ -1,12 +1,63 @@
-import Qt 4.7
+import QtQuick 1.1
+import com.meego 1.0
+
+Page {
+    id: coversAlternativesPage
+
+    tools: ToolBarLayout {
+             ToolIcon {
+               id: backButton
+               iconId: "toolbar-back" 
+               onClicked: { missionControl.stop_pending_jobs(); pageStack.pop () }
+             }
+    }
+
+    GridView { 
+        id: coversView
+        model: coversModel
+        anchors.fill : coversAlternativesPage
+        cellWidth: 160
+        cellHeight: 160
+
+        delegate: Component {
+          Rectangle {
+              id: coverPaintArea
+              width: coversView.cellWidth
+              height: coversView.cellHeight
+              border.color: "red"
+              
+              Image {
+                 id: cover
+                 source: model.cover.url
+                 width: parent.width
+                 height: parent.height
+                 cache: false
+                 anchors.centerIn: parent
+              }              
+              
+              Text {
+                 id: t
+                 text: "xxx"
+                 visible: (model.cover.url == null)
+              }
+
+              MouseArea {
+                   anchors.fill: coverPaintArea
+                   onClicked: {
+                      console.log ("wohooo")
+                      missionControl.save_option_for (coversModel, index)
+                      backButton.clicked ()       
+                   }
+              }
+
+        }
+      }
+    }
 
-/*
-Item {
-     anchors.fill: parent
-     Text { text: "hola oh"; color: "white" }
 }
-*/
 
+
+/*
 Row {
        id: coversAlternatives
 
@@ -42,3 +93,4 @@ Row {
        }
 }
 
+*/
index 7722426..d77839b 100644 (file)
@@ -6,7 +6,7 @@ Page {
     TabGroup {
       id: tabGroup
       currentTab: albumsTab
-      AlbumsPage {id: albumsTab}
+      AlbumsPage {id: albumsTab }
       SongsPage {id: othersTab}
     }
 
@@ -33,8 +33,11 @@ Page {
     Menu {
         id: myMenu
         MenuLayout {
-            MenuItem { text: "Download all" }
+            MenuItem { text: "Download all"; 
+                       onClicked: { missionControl.download_all (albumModel) }
+            }
         }
     }
+
 }
 
index f7b65bf..4976ca4 100644 (file)
@@ -7,6 +7,4 @@ PageStackWindow {
     platformStyle: PageStackWindowStyle { id: defaultStyle }
 
     initialPage: Mussorgsky {}
-
-
 }