QML: Download images from the network
authorIvan Frade <ivan.frade@nokia.com>
Tue, 5 Apr 2011 07:42:56 +0000 (10:42 +0300)
committerIvan Frade <ivan.frade@nokia.com>
Tue, 5 Apr 2011 07:44:00 +0000 (10:44 +0300)
src/mussorgsky-qml.py
src/qml/controller.py
src/qml/coverItem.py
src/qml/coverModel.py
src/qml/logic.py
src/qml/utils.py [new file with mode: 0644]
ui/AlbumList.qml
ui/Alternatives.qml
ui/ClickeableImage.qml [new file with mode: 0644]
ui/main.qml

index 00a0029..223fd7a 100644 (file)
@@ -7,7 +7,6 @@ from PySide.QtGui import *
 from PySide.QtDeclarative import QDeclarativeView
 
 from qml.albumModel import AlbumModel
-from qml.logic import MussorgskyLogic
 from qml.controller import MussorgskyController
 from qml.coverModel import CoversModel
 
@@ -24,12 +23,11 @@ view = QDeclarativeView()
 #     AlbumItem ("Come with us", "Chemical brothers", None)
 #    ]
 
-logic = MussorgskyLogic ()
 
-albumModel = AlbumModel (logic.get_all_albums())
+controller = MussorgskyController ()
+albumModel = AlbumModel (controller.get_all_albums())
 print "Model with", albumModel.rowCount(), "rows"
 
-controller = MussorgskyController ()
 coverModel = CoversModel ()
 
 rc = view.rootContext ()
index ff1d62a..1393d98 100644 (file)
@@ -5,11 +5,63 @@ from PySide import QtCore
 from PySide import QtGui
 from PySide import QtDeclarative
 
+from aa_search import MussorgskyAlbumArt
+
+from tracker_backend_gi import TrackerBackendGI
+
+from albumItem import AlbumItem
+from album_art_spec import getCoverArtThumbFileName
+
+
+class DownloadThread (QtCore.QThread):
+
+    def __init__ (self, model, album):
+        QtCore.QThread.__init__ (self)
+        self.downloader = MussorgskyAlbumArt ()
+        self.model = model
+        self.album = album
+
+    def run (self):
+        print "Running the thread"
+        counter = 0
+        for x in self.downloader.get_possible_url (self.album.artist,
+                                                   self.album.title, 4):
+            if counter == 4:
+                break
+            print "Setting url", x
+            model.updateData (counter, x)
+            counter += 1
+        self.exec_ ()
+
 
 class MussorgskyController (QtCore.QObject):
 
-    @QtCore.Slot (QtCore.QObject, str)
-    def albumSelected (self, model, title):
-        print "clicked on", title
-        model.updateData (0, "images/button-green.png")
+    def __init__ (self):
+        QtCore.QObject.__init__ (self)
+        self.download = None
+        self.tracker = TrackerBackendGI ()
+
+    @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 ()
+
 
+    def get_all_albums (self):
+        """
+        Return a list of AlbumItem objects to build the model
+        This is not called from QML, no need to make it a slot
+        """
+        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))
+        return results
index b617d91..a9fb71e 100644 (file)
@@ -10,7 +10,7 @@ class CoverItem (QtCore.QObject):
 
     def __init__ (self, url):
         QtCore.QObject.__init__(self)
-        self._url = QtCore.QUrl (url)
+        self._url = url
 
     def _url (self):
         return self._url
@@ -21,4 +21,4 @@ class CoverItem (QtCore.QObject):
 
     url_changed = QtCore.Signal ()
 
-    url = QtCore.Property (QtCore.QUrl, _url, _setUrl, notify=url_changed)
+    url = QtCore.Property (unicode, _url, _setUrl, notify=url_changed)
index d73ccf8..d3d8578 100644 (file)
@@ -31,4 +31,4 @@ class CoversModel (QtCore.QAbstractListModel):
 
     def updateData (self, row, url):
         assert row >= 0 and row < len (self._alternatives)
-        self._alternatives[row].url = QtCore.QUrl(url)
+        self._alternatives[row].url = url
index 567ddc3..b78c999 100644 (file)
@@ -12,15 +12,6 @@ class MussorgskyLogic:
         self.tracker = TrackerBackendGI ()
 
 
-    def get_all_albums (self):
-        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))
-        return results
 
 
 # To test everything is fine here
diff --git a/src/qml/utils.py b/src/qml/utils.py
new file mode 100644 (file)
index 0000000..daffb06
--- /dev/null
@@ -0,0 +1,59 @@
+import gobject
+
+def escape_html (text, max_length=40):
+    if (len (text) > max_length):
+        cutpoint = text.find (' ', max_length-10)
+        if (cutpoint == -1 or cutpoint > max_length):
+            cutpoint = max_length
+        text = text [0:cutpoint] + "..."
+    return gobject.markup_escape_text (text)
+
+def is_empty (text):
+    return not text or len (text.strip ()) == 0
+
+# Set socket timeout
+import socket
+import urllib2
+
+timeout = 5
+socket.setdefaulttimeout(timeout)
+
+class UrllibWrapper ():
+
+    def save_content_into_file (self, content, filename):
+        output = open (filename, 'w')
+        output.write (content)
+        output.close ()
+        
+    def get_url (self, url):
+        request = urllib2.Request (url)
+        request.add_header ('User-Agent', 'Mussorgsky/0.1 Test')
+        opener = urllib2.build_opener ()
+        try:
+            return opener.open (request).read ()
+        except:
+            return None
+
+
+
+class Set:
+
+    def __init__ (self):
+        self.d = {}
+        self.k = None
+        
+    def insert (self, element):
+        if (not self.d.has_key (element)):
+            self.d[element] = 1
+            self.k = None
+
+    def as_list (self):
+        if (self.k):
+            return self.k
+        
+        self.k = self.d.keys ()
+        self.k.sort ()
+        return self.k
+        
+
+
index d8b3496..7fc7494 100644 (file)
@@ -4,7 +4,7 @@ ListView {
     id: albumListView
     anchors.fill: parent
 
-    signal rowSelected (int index, string albumTitle)
+    signal rowSelected (int index, variant album)
 
     delegate: Component {
           Rectangle {
@@ -51,7 +51,7 @@ ListView {
               
               MouseArea {
                    anchors.fill: parent
-                   onClicked: { albumListView.rowSelected (index, model.album.title) }
+                   onClicked: { albumListView.rowSelected (index, model.album) }
               }
           }
     }
index 72decd0..2b529dc 100644 (file)
@@ -10,7 +10,6 @@ Item {
 Row {
        id: coversAlternatives
 
-       //property alias worker : findImages
        property alias model: imagesLoop.model
 
        anchors.horizontalCenter : parent.horizontalCenter
@@ -20,20 +19,15 @@ Row {
 
        Repeater {
            id: imagesLoop
-           model: 4
-           Image {
-              source: model.cover.url
-              width: 120
-              height: 120
+           model: 5
+           delegate: Component {
+                ClickeableImage {
+                  source: model.cover.url
+                  width: 120
+                  height: 120
+                  onClicked: { console.log (model.cover.url) }
+               }
            }
        }
-
-/*
-       WorkerScript {
-             id: findImages
-             source: "findImages.js"
-             //onMessage: image1.source = messageObject.image1
-       }
-*/
 }
 
diff --git a/ui/ClickeableImage.qml b/ui/ClickeableImage.qml
new file mode 100644 (file)
index 0000000..aaff116
--- /dev/null
@@ -0,0 +1,19 @@
+import Qt 4.7
+
+Item {
+     id:clickeableImage
+     property alias source: alternativeImage.source
+     signal clicked
+
+     Image {
+          id: alternativeImage
+          width: 120
+          height: 120
+     }
+
+     MouseArea {
+               id:mouseArea
+               anchors.fill: alternativeImage
+               onClicked: { clickeableImage.clicked () }
+     }
+}
index 4226bfd..f2b0663 100644 (file)
@@ -34,9 +34,7 @@ Rectangle {
         model: albumModel
         onRowSelected: {
             screen.state = "in_alternativesPage"
-            missionControl.albumSelected (coversModel, albumTitle)
-            //var msg = {'model': alternativesPage.model, 'row': index}
-            //alternativesPage.worker.sendMessage (msg)
+            missionControl.albumSelected (coversModel, album)
         }
     }