Migliorata l'interfaccia e aggiunto lo scaricamento dei canali in una lista

Leonardo Robol [2009-10-31 10:50]
Migliorata l'interfaccia e aggiunto lo scaricamento dei canali in una lista
Filename
RaiTV/ChannelLoader.py
RaiTV/Interface.py
RaiTV/VideoWidget.py
raitv.py
ui/RaiTV.ui
diff --git a/RaiTV/ChannelLoader.py b/RaiTV/ChannelLoader.py
new file mode 100644
index 0000000..ab5c971
--- /dev/null
+++ b/RaiTV/ChannelLoader.py
@@ -0,0 +1,57 @@
+#
+# -*- coding: utf-8 -*-
+#
+#  Scarica la lista di URI per vedere i canali rai
+#
+
+import urllib2, re, httplib
+
+class ChannelList():
+
+    def __init__(self):
+
+        ## Inizializzo un dizionario di canali
+        self.channels = {}
+
+        self.UA = 'Mozilla/5.0 (X11; U; Linux i686; it; rv:1.9.0.6) Gecko/2009011912 Firefox/3.0.11'
+
+    def updateChannels(self):
+
+        ## Qui dobbiamo un pochino imbrogliare..ehm ehm
+        req = urllib2.Request("http://www.rai.tv/dl/RaiTV/videoWall/PublishingBlock-5566288c-3d21-48dc-b3e2-af7fbe3b2af8.xml",
+                              None,
+                              { 'User-Agent': self.UA })
+        r = urllib2.urlopen(req)
+        self.parseChannels(r.read())
+
+    def parseChannels(self, xmlfile):
+        """Fai il parse dei canali scaricati dalla rai"""
+
+        for channel, url in re.findall("<videoUnit name=\"([^\"]*)\".*>.*\\n.*<url>(\S*)</url>", xmlfile):
+            url = re.sub(r"&amp;", "&", url)
+            self.channels[channel] = url
+
+
+    def getChannel(self, key):
+        """Ottiene il vero canale da cui guardare.. :)"""
+
+        if not self.channels.has_key(key):
+            return None
+
+        host = re.search(r"^.*//([^/]*)/", self.channels[key]).group(1)
+        # print " => host = %s" % host
+        path = re.search(r"%s/(.*)$" % host, self.channels[key]).group(1)
+        # print " => path = %s" % path
+
+        req = urllib2.Request(self.channels[key],
+                              None,
+                              {'User-Agent': self.UA})
+
+        r = urllib2.urlopen(req)
+        mms = r.read()
+        mms = re.search(r"HREF=\"(\S*)\"", mms).group(1)
+        return mms
+
+
+
+
diff --git a/RaiTV/Interface.py b/RaiTV/Interface.py
index 1e66d2b..c1e162a 100644
--- a/RaiTV/Interface.py
+++ b/RaiTV/Interface.py
@@ -10,20 +10,83 @@ import gtk, pygtk
 ## avrò bisogno di recuperare

 from VideoWidget import VideoWidget
+from ChannelLoader import ChannelList

-builder = gtk.Builder()
-builder.add_from_file("ui/RaiTV.ui")
+class UI():
+
+    def __init__(self):
+        """Recupera tutti gli oggetti necessari aprendo
+        il file .ui e costruisce quelli che mancano"""
+
+        self.builder = gtk.Builder()
+        self.builder.add_from_file("ui/RaiTV.ui")
+
+        self.win = self.builder.get_object("win")
+        self.listacanali = self.builder.get_object("listacanali")
+
+        ## Lista dei canali (in astratto)
+        self.channellist = ChannelList()
+
+
+        ## Questo hbox è quello dove dobbiamo inserire
+        ## la videowidget
+        self.hbox1 = self.builder.get_object("hbox1")
+
+        self.videowidget = VideoWidget()
+        self.hbox1.pack_start(self.videowidget)
+
+        ## Qualche setting prima di partire
+        self.win.resize(640,480)
+
+        ## Carico i pulsanti
+        self.stop_btn, self.play_btn, self.pause_btn, self.record_btn, self.updatelist = \
+        self.builder.get_object("stop"), self.builder.get_object("play"), \
+        self.builder.get_object("pause"), self.builder.get_object("record"), \
+        self.builder.get_object("updatelist")
+
+        ## La statusbar
+        self.statusbar = self.builder.get_object("statusbar")
+        self.sb_info("Applicazione inizializzata")
+
+        self.connect_buttons()
+
+
+        ## Connettiamo la richiesta di uscire a qualcosa che lo gestisca
+        self.win.connect("destroy", self.destroy)
+
+    def show_all(self):
+        """Mostra tutta l'interfaccia"""
+        self.win.show_all()
+
+    def sb_info(self, text):
+        """Pubblica delle informazioni nella statusbar"""
+        assert self.statusbar
+        id = self.statusbar.get_context_id("info")
+        self.statusbar.push(id, "Info: " + text)
+
+    def connect_buttons(self):
+        """Connette i bottoni con le relative azioni"""
+        self.stop_btn.connect("clicked", lambda w: self.videowidget.stop() )
+        self.play_btn.connect("clicked", lambda w: self.videowidget.play() )
+        self.pause_btn.connect("clicked", lambda w: self.videowidget.pause() )
+        self.updatelist.connect("clicked", lambda w: self.channellist.updateChannels() )
+
+    def start_video(self):
+        """Avvia il video"""
+        self.videowidget.registerXID()
+        self.videowidget.load_video("file:///home/leonardo/Video/The.Big.Bang.Theory.S03E02.HDTV.XviD-XII.avi")
+        # self.videowidget.load_video("mms://livestream.rai.it.edgestreams.net/reflector:64084?auth=daEcjcOancgdlaecAdqdccmdwbZbkb0aHd.-bk6_3l-b4-JlruuGt&aifp=V001")
+        # self.videowidget.load_video("mms://livestream.rai.it.edgestreams.net/reflector:64084?auth=daEcvcIa9clbgaEbjbfbFdHc_dkcCbUb7dQ-bk7abm-b4-BlvusGo&aifp=V001")
+
+    def destroy(self, w):
+        """Chiamata per distruggere l'interfaccia"""
+
+        ## Fermiamo il video
+        self.videowidget.stop()
+
+        ## e ce ne andiamo
+        gtk.main_quit()

-win = builder.get_object("win")
-listacanali = builder.get_object("listacanali")
-hbox1 = builder.get_object("hbox1")
-videowidget = VideoWidget()
-hbox1.pack_start(videowidget)


-win.show_all()
-win.resize(640,480)
-videowidget.reset()
-videowidget.registerXID()
-videowidget.start_video("file:///home/leonardo/Video/The.Big.Bang.Theory.S03E02.HDTV.XviD-XII.avi")

diff --git a/RaiTV/VideoWidget.py b/RaiTV/VideoWidget.py
index 0a953e8..d4a93f7 100644
--- a/RaiTV/VideoWidget.py
+++ b/RaiTV/VideoWidget.py
@@ -17,6 +17,16 @@ class VideoWidget(gtk.DrawingArea):
         self.set_size_request(320,320)
         self.unset_flags(gtk.DOUBLE_BUFFERED)

+        ## Configurazione del player gstreamer
+        self.player = gst.element_factory_make("playbin", "player")
+        bus = self.player.get_bus()
+        bus.enable_sync_message_emission()
+        bus.add_signal_watch()
+        bus.connect("sync-message::element", self.on_sync_message)
+        bus.connect("message", self.on_message)
+
+
+
     def do_expose_event(self, event):
         if self.imagesink:
             self.imagesink.expose()
@@ -29,16 +39,19 @@ class VideoWidget(gtk.DrawingArea):
         self.imagesink = sink
         self.imagesink.set_xwindow_id(self.window.xid)

-    def start_video(self, uri):
+    def load_video(self, uri):
         """Start video playing with the specified URI"""
-        self.player = gst.element_factory_make("playbin", "player")
         self.player.set_property("uri", uri)

-        bus = self.player.get_bus()
-        bus.enable_sync_message_emission()
-        bus.add_signal_watch()
-        bus.connect("sync-message::element", self.on_sync_message)
-        bus.connect("message", self.on_message)
+        self.play()
+
+    def pause(self):
+        self.player.set_state(gst.STATE_PAUSED)
+
+    def stop(self):
+        self.player.set_state(gst.STATE_NULL)
+
+    def play(self):
         self.player.set_state(gst.STATE_PLAYING)

     def on_sync_message(self, bus, message):
@@ -46,7 +59,6 @@ class VideoWidget(gtk.DrawingArea):
             return
         if message.structure.get_name() == 'prepare-xwindow-id':
             gtk.gdk.threads_enter()
-            # gtk.gdk.display.get_default.sync()
             self.set_sink(message.src)
             message.src.set_property("force-aspect-ratio", True)
             gtk.gdk.threads_leave()
diff --git a/raitv.py b/raitv.py
index 7f7e92f..296070f 100644
--- a/raitv.py
+++ b/raitv.py
@@ -6,10 +6,10 @@
 import gtk, pygtk, gst
 from RaiTV import VideoWidget, Interface

-Interface.listacanali.show()
-Interface.win.show()
+ui = Interface.UI()

-Interface.win.connect("destroy", gtk.main_quit)
+ui.show_all()
+ui.start_video()

 gtk.main()

diff --git a/ui/RaiTV.ui b/ui/RaiTV.ui
index 798d32c..c5537cd 100644
--- a/ui/RaiTV.ui
+++ b/ui/RaiTV.ui
@@ -2,13 +2,21 @@
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
+  <object class="GtkListStore" id="canalistore">
+    <columns>
+      <!-- column-name nomecanale -->
+      <column type="gchararray"/>
+      <!-- column-name url -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkWindow" id="win">
     <child>
       <object class="GtkVBox" id="vbox1">
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
         <child>
-          <object class="GtkMenuBar" id="menubar1">
+          <object class="GtkMenuBar" id="menubar">
             <property name="visible">True</property>
             <child>
               <object class="GtkMenuItem" id="menuitem1">
@@ -151,13 +159,23 @@
               <object class="GtkTreeView" id="listacanali">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="model">liststore1</property>
+                <property name="model">canalistore</property>
               </object>
               <packing>
                 <property name="position">0</property>
               </packing>
             </child>
             <child>
+              <object class="GtkVSeparator" id="vseparator1">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
               <placeholder/>
             </child>
           </object>
@@ -166,19 +184,110 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHButtonBox" id="hbuttonbox1">
+          <object class="GtkHBox" id="hbox2">
             <property name="visible">True</property>
             <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
+              <object class="GtkAlignment" id="alignment1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <child>
+                  <object class="GtkHButtonBox" id="hbuttonbox1">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkButton" id="updatelist">
+                        <property name="label" translatable="yes">Aggiorna canali</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="play">
+                        <property name="label">gtk-media-play</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_stock">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="pause">
+                        <property name="label">gtk-media-pause</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_stock">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="stop">
+                        <property name="label">gtk-media-stop</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_stock">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="record">
+                        <property name="label">gtk-media-record</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_stock">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
             </child>
             <child>
-              <placeholder/>
+              <object class="GtkVolumeButton" id="volumebutton">
+                <property name="label" translatable="yes">Volume</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="relief">none</property>
+                <property name="focus_on_click">False</property>
+                <property name="orientation">vertical</property>
+                <property name="icons">audio-volume-muted
+audio-volume-high
+audio-volume-low
+audio-volume-medium</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
             </child>
             <child>
               <placeholder/>
@@ -189,15 +298,18 @@
             <property name="position">2</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkStatusbar" id="statusbar">
+            <property name="visible">True</property>
+            <property name="spacing">2</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
       </object>
     </child>
   </object>
-  <object class="GtkListStore" id="liststore1">
-    <columns>
-      <!-- column-name nomecanale -->
-      <column type="gchararray"/>
-      <!-- column-name url -->
-      <column type="gchararray"/>
-    </columns>
-  </object>
+  <object class="GtkAction" id="action1"/>
 </interface>
ViewGit