Author: duncan
Date: Sun Mar 16 17:24:48 2008
New Revision: 10535

Log:
[ 1915730 ] Allow DVBStreamer live pause to use a remote streamer
Patch from Adam Charrett applied


Modified:
   branches/rel-1-7/freevo/ChangeLog
   branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/comms.py
   branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/live_pause.py
   branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/manager.py
   branches/rel-1/freevo/ChangeLog
   branches/rel-1/freevo/src/tv/plugins/dvbstreamer/comms.py
   branches/rel-1/freevo/src/tv/plugins/dvbstreamer/live_pause.py
   branches/rel-1/freevo/src/tv/plugins/dvbstreamer/manager.py

Modified: branches/rel-1-7/freevo/ChangeLog
==============================================================================
--- branches/rel-1-7/freevo/ChangeLog   (original)
+++ branches/rel-1-7/freevo/ChangeLog   Sun Mar 16 17:24:48 2008
@@ -16,11 +16,13 @@
 == Release 1.7.7 (2008-03-23) ==
 --------------------------------
 
+ * New atlantice skin (F#1907139)
  * New DVD to disk back-up plug-in (F#1892278)
  * New PDA control with feedback client and upd plug-in (F#1890855)
  * New placement support when using xrandr (F#1869969)
  * Updated cdbackup plug-in to add the year from cddb (F#1907065)
  * Updated cd_burn plug-in to support play lists (F#1901175)
+ * Updated dvbstreamer to allow the live pause to use a remote server 
(F#1915730)
  * Updated dvdbackup to allow customized menus (F#1890499)
  * Updated playlist to process "#EXTINF" comments in m3u files (F#1890203)
  * Updated Russian translation (B#1889826)

Modified: branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/comms.py
==============================================================================
--- branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/comms.py (original)
+++ branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/comms.py Sun Mar 16 
17:24:48 2008
@@ -30,32 +30,50 @@
 #
 # ----------------------------------------------------------------------- */
 from socket import *
+import re
 
 PRIMARY_SERVICE_FILTER='<Primary>'
+lssfs_re = re.compile(' (.*?) : (.*?) \((.*)\)')
 
 class Controller:
-    def __init__(self, host, adapter, username=None, password=None):
+    """
+    High level connection to a DVBStreamer daemon, uses a transitory connection
+    to process commands/requests.
+    """
+    def __init__(self, host, adapter, username=None, password=None, 
transitory=True):
         self.host = host
         self.adapter = adapter
         self.username = username
         self.password = password
+        self.transitory = transitory
+        self.connection = None
+        self.my_ip = None
 
     def execute_command(self, command, authenticate=False):
         """
         Send a command to the dvbstreamer instance to execute,
         first authorising if required.
         """
-        ctrlcon = ControlConnection(self.host, self.adapter)
-        ctrlcon.open()
-        if authenticate:
-            (ec, em, lines) = ctrlcon.send_command('auth %s %s' % 
(self.username, self.password))
-            if ec != 0:
-                raise RuntimeError, 'failed to authenticate'
-        result = ctrlcon.send_command(command)
-        ctrlcon.close()
+        if self.transitory or self.connection is None:
+            ctrlcon = ControlConnection(self.host, self.adapter)
+            ctrlcon.open()
+        else:
+            ctrlcon = self.connection
+        try:
+            if authenticate:
+                (ec, em, lines) = ctrlcon.send_command('auth %s %s' % 
(self.username, self.password))
+                if ec != 0:
+                    raise RuntimeError, 'failed to authenticate'
+            result = ctrlcon.send_command(command)
+            self.my_ip = ctrlcon.my_ip
+        finally:
+            if self.transitory:
+                ctrlcon.close()
+            else:
+                self.connection = ctrlcon
         return result
 
-    def select_service(self, service):
+    def set_current_service(self, service):
         """
         Select the primary service.
         """
@@ -63,6 +81,23 @@
         if errcode != 0:
             raise RuntimeError, errmsg
 
+
+    def get_current_service(self):
+        """
+        Retrieve the current primary service.
+        Returns a tuple containing service name and multiplex.
+        """
+        (errcode, errmsg, msg) = self.execute_command('current')
+        if errcode != 0:
+            raise RuntimeError, errmsg
+
+        m = re.match('Current Service : "(.+?)" \(.+?\) Multiplex: (.+)', 
msg[0])
+        if m:
+            return (m.group(1), m.group(2))
+
+        return None
+
+
     def set_servicefilter_mrl(self, service_filter, mrl):
         """
         Set the MRL (Media Resource Locator) for a given service filter.
@@ -71,6 +106,22 @@
         if errcode != 0:
             raise RuntimeError, errmsg
 
+    def get_servicefilters(self):
+        """
+        Get a dictionary containing tuples of service and mrl for each
+        service filter.
+        """
+        (errcode, errmsg, msg) = self.execute_command('lssfs')
+        if errcode != 0:
+            raise RuntimeError, errmsg
+        result = {}
+        for line in msg:
+            m = lssfs_re.match(line)
+            if m:
+                result[m.group(1)] = (m.group(2), m.group(3))
+        return result
+
+
     def get_services(self, mux=''):
         """
         Get the list of services available on all or a specific multiplex.
@@ -140,38 +191,64 @@
     def get_frontend_status(self):
         """
         Get the frontend status of the set dvbstreamer instance.
+        Returns a tuple contain locked state, ber, signal strength %, snr % and
+        uncorrected block count.
         """
         (errcode, errmsg, status) = self.execute_command('festatus')
         if errcode != 0:
             return None
 
-        locked = status[0].find('Lock,') != -1
+        locked = status[0].find('Lock') != -1
 
         line = status[1]
-        equalsindex = line.find('= ') + 2
-        spaceindex = line.find(' ', equalsindex)
-        ber = int(line[equalsindex:spaceindex])
-
-        equalsindex = line.find('= ',spaceindex) + 2
-        spaceindex = line.find(' ', equalsindex)
-        signal = int(line[equalsindex:spaceindex])
+        m = re.match('Signal Strength = ([0-9]+)% SNR = ([0-9]+)% BER = 
([0-9a-f]+?) Uncorrected Blocks = ([0-9a-f]+)', line)
+        if m:
+            signal = int(m.group(1))
+            snr = int(m.group(2))
+            ber = int(m.group(3),16)
+            ucb = int(m.group(4),16)
+        else:
+            # Should we raise an exception?
+            signal = 0
+            snr    = 0
+            ber    = 0
+            ucb    = 0
+
+        return (locked, ber, signal, snr, ucb)
 
-        equalsindex = line.find('= ',spaceindex) + 2
-        snr = int(line[equalsindex:])
+    def get_variable(self, var):
+        (errcode, errmsg, value) = self.execute_command('get ' + var)
+        if errcode != 0:
+            return None
+        return value
 
-        return (locked, ber, signal, snr)
 
 class ControlConnection:
+    """
+    Class implementing a connection to a DVBStreamer daemon.
+    """
     def __init__(self, host, adapter):
+        """
+        Create a connection object to communicate with a DVBStreamer daemon.
+        """
         self.host = host
         self.adapter = adapter
         self.opened = False
+        self.version = None
+        self.welcome_message = None
+        self.my_ip = None
 
     def open(self):
+        """
+        Open the connection to the DVBStreamer daemon.
+        """
         if self.opened:
             return
         self.socket = socket(AF_INET,SOCK_STREAM)
         self.socket.connect((self.host, self.adapter + 54197))
+
+        self.my_ip = self.socket.getsockname()[0]
+
         self.socket_file = self.socket.makefile('r+')
         self.opened = True
         (error_code, error_message, lines) = self.read_response()
@@ -185,12 +262,18 @@
         return self.opened
 
     def close(self):
+        """
+        Close the connection to the DVBStreamer daemon.
+        """
         if self.opened:
             self.socket_file.close()
             self.socket.close()
             self.opened = False
 
     def send_command(self, command):
+        """
+        Send a command to the connection DVBStreamer daemon.
+        """
         if not self.opened:
             raise RuntimeError, 'not connected'
 
@@ -200,6 +283,11 @@
         return self.read_response()
 
     def read_response(self):
+        """
+        Read a response from the DVBStreamer deamon after a command has been
+        sent.
+        Returns a tuple of error code, error message and response lines.
+        """
         more_lines = True
         lines = []
         error_code = -1

Modified: branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/live_pause.py
==============================================================================
--- branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/live_pause.py    
(original)
+++ branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/live_pause.py    Sun Mar 
16 17:24:48 2008
@@ -331,7 +331,12 @@
         if self.adapter_in_use != adapter:
             self.adapter_in_use = adapter
             try:
-                self.manager.enable_udp_output(self.adapter_in_use)
+                if adapter.find(':') != -1:
+                    my_ip = self.manager.controllers[adapter].my_ip
+                else:
+                    my_ip = 'localhost'
+
+                self.manager.enable_udp_output(self.adapter_in_use, my_ip, 
1234)
             except:
                 _debug_('Failed to enable output! ' + traceback.format_exc())
 
@@ -533,7 +538,7 @@
 
     def __osd_write(self, text):
         if self.app:
-            self.app.write('OSDWriteText$%s\n' % text)
+            self.app.write('OSDWriteText$    %s\n' % text)
 
     def __draw_state_screen(self):
         osd_obj = osd.get_singleton()

Modified: branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/manager.py
==============================================================================
--- branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/manager.py       
(original)
+++ branches/rel-1-7/freevo/src/tv/plugins/dvbstreamer/manager.py       Sun Mar 
16 17:24:48 2008
@@ -39,16 +39,14 @@
     def __init__(self, username, password):
         self.username = username
         self.password = password
-        self.destip   = 'localhost'
-        self.destport = 1234
         self.controllers = {}
 
 
-    def get_udp_mrl(self):
+    def get_udp_mrl(self, ip_address, port):
         """
         Get the mrl to use for dvbstreamer and xine.
         """
-        return 'udp://%s:%d' %(self.destip, self.destport)
+        return 'udp://%s:%d' %(ip_address, port)
 
 
     def get_file_mrl(self, filename):
@@ -58,11 +56,11 @@
         return 'file://%s' % filename
 
 
-    def enable_udp_output(self, adapter):
+    def enable_udp_output(self, adapter, ip_address, port):
         """
         Enable UDP output to localhost:1234
         """
-        self.set_mrl(adapter, self.get_udp_mrl())
+        self.set_mrl(adapter, self.get_udp_mrl(ip_address,port))
 
 
     def enable_file_output(self, adapter, filename):
@@ -75,7 +73,7 @@
         """
         Disable output from the specified dvbstreamer instance.
         """
-        _debug_('Disabling output on adapter %d' % adapter)
+        _debug_('Disabling output on adapter %s' % adapter)
         self.set_mrl(adapter,  'null://')
 
 
@@ -83,9 +81,9 @@
         """
         Select a channel on the specified dvbstreamer instance.
         """
-        _debug_('Selecting channel %s on adapter %d'%(channel, adapter))
+        _debug_('Selecting channel %s on adapter %s'%(channel, adapter))
         controller = self.get_controller(adapter)
-        controller.select_service(channel)
+        controller.set_current_service(channel)
 
 
     def set_mrl(self, adapter, mrl):
@@ -102,6 +100,12 @@
         """
         if adapter in self.controllers:
             return self.controllers[adapter]
-        controller = comms.Controller('localhost', adapter, self.username, 
self.password)
+        if adapter.find(':') != -1:
+            ip_address,dvb_adapter = adapter.split(':',2)
+            dvb_adapter = int(dvb_adapter)
+        else:
+            ip_address = 'localhost'
+            dvb_adapter = int(adapter)
+        controller = comms.Controller(ip_address, dvb_adapter, self.username, 
self.password)
         self.controllers[adapter] = controller
         return controller

Modified: branches/rel-1/freevo/ChangeLog
==============================================================================
--- branches/rel-1/freevo/ChangeLog     (original)
+++ branches/rel-1/freevo/ChangeLog     Sun Mar 16 17:24:48 2008
@@ -21,11 +21,13 @@
 == Release 1.7.7 (2008-03-23) ==
 --------------------------------
 
+ * New atlantice skin (F#1907139)
  * New DVD to disk back-up plug-in (F#1892278)
  * New PDA control with feedback client and upd plug-in (F#1890855)
  * New placement support when using xrandr (F#1869969)
  * Updated cdbackup plug-in to add the year from cddb (F#1907065)
  * Updated cd_burn plug-in to support play lists (F#1901175)
+ * Updated dvbstreamer to allow the live pause to use a remote server 
(F#1915730)
  * Updated dvdbackup to allow customized menus (F#1890499)
  * Updated playlist to process "#EXTINF" comments in m3u files (F#1890203)
  * Updated Russian translation (B#1889826)

Modified: branches/rel-1/freevo/src/tv/plugins/dvbstreamer/comms.py
==============================================================================
--- branches/rel-1/freevo/src/tv/plugins/dvbstreamer/comms.py   (original)
+++ branches/rel-1/freevo/src/tv/plugins/dvbstreamer/comms.py   Sun Mar 16 
17:24:48 2008
@@ -30,32 +30,50 @@
 #
 # ----------------------------------------------------------------------- */
 from socket import *
+import re
 
 PRIMARY_SERVICE_FILTER='<Primary>'
+lssfs_re = re.compile(' (.*?) : (.*?) \((.*)\)')
 
 class Controller:
-    def __init__(self, host, adapter, username=None, password=None):
+    """
+    High level connection to a DVBStreamer daemon, uses a transitory connection
+    to process commands/requests.
+    """
+    def __init__(self, host, adapter, username=None, password=None, 
transitory=True):
         self.host = host
         self.adapter = adapter
         self.username = username
         self.password = password
+        self.transitory = transitory
+        self.connection = None
+        self.my_ip = None
 
     def execute_command(self, command, authenticate=False):
         """
         Send a command to the dvbstreamer instance to execute,
         first authorising if required.
         """
-        ctrlcon = ControlConnection(self.host, self.adapter)
-        ctrlcon.open()
-        if authenticate:
-            (ec, em, lines) = ctrlcon.send_command('auth %s %s' % 
(self.username, self.password))
-            if ec != 0:
-                raise RuntimeError, 'failed to authenticate'
-        result = ctrlcon.send_command(command)
-        ctrlcon.close()
+        if self.transitory or self.connection is None:
+            ctrlcon = ControlConnection(self.host, self.adapter)
+            ctrlcon.open()
+        else:
+            ctrlcon = self.connection
+        try:
+            if authenticate:
+                (ec, em, lines) = ctrlcon.send_command('auth %s %s' % 
(self.username, self.password))
+                if ec != 0:
+                    raise RuntimeError, 'failed to authenticate'
+            result = ctrlcon.send_command(command)
+            self.my_ip = ctrlcon.my_ip
+        finally:
+            if self.transitory:
+                ctrlcon.close()
+            else:
+                self.connection = ctrlcon
         return result
 
-    def select_service(self, service):
+    def set_current_service(self, service):
         """
         Select the primary service.
         """
@@ -63,6 +81,23 @@
         if errcode != 0:
             raise RuntimeError, errmsg
 
+
+    def get_current_service(self):
+        """
+        Retrieve the current primary service.
+        Returns a tuple containing service name and multiplex.
+        """
+        (errcode, errmsg, msg) = self.execute_command('current')
+        if errcode != 0:
+            raise RuntimeError, errmsg
+
+        m = re.match('Current Service : "(.+?)" \(.+?\) Multiplex: (.+)', 
msg[0])
+        if m:
+            return (m.group(1), m.group(2))
+
+        return None
+
+
     def set_servicefilter_mrl(self, service_filter, mrl):
         """
         Set the MRL (Media Resource Locator) for a given service filter.
@@ -71,6 +106,22 @@
         if errcode != 0:
             raise RuntimeError, errmsg
 
+    def get_servicefilters(self):
+        """
+        Get a dictionary containing tuples of service and mrl for each
+        service filter.
+        """
+        (errcode, errmsg, msg) = self.execute_command('lssfs')
+        if errcode != 0:
+            raise RuntimeError, errmsg
+        result = {}
+        for line in msg:
+            m = lssfs_re.match(line)
+            if m:
+                result[m.group(1)] = (m.group(2), m.group(3))
+        return result
+
+
     def get_services(self, mux=''):
         """
         Get the list of services available on all or a specific multiplex.
@@ -140,38 +191,64 @@
     def get_frontend_status(self):
         """
         Get the frontend status of the set dvbstreamer instance.
+        Returns a tuple contain locked state, ber, signal strength %, snr % and
+        uncorrected block count.
         """
         (errcode, errmsg, status) = self.execute_command('festatus')
         if errcode != 0:
             return None
 
-        locked = status[0].find('Lock,') != -1
+        locked = status[0].find('Lock') != -1
 
         line = status[1]
-        equalsindex = line.find('= ') + 2
-        spaceindex = line.find(' ', equalsindex)
-        ber = int(line[equalsindex:spaceindex])
-
-        equalsindex = line.find('= ',spaceindex) + 2
-        spaceindex = line.find(' ', equalsindex)
-        signal = int(line[equalsindex:spaceindex])
+        m = re.match('Signal Strength = ([0-9]+)% SNR = ([0-9]+)% BER = 
([0-9a-f]+?) Uncorrected Blocks = ([0-9a-f]+)', line)
+        if m:
+            signal = int(m.group(1))
+            snr = int(m.group(2))
+            ber = int(m.group(3),16)
+            ucb = int(m.group(4),16)
+        else:
+            # Should we raise an exception?
+            signal = 0
+            snr    = 0
+            ber    = 0
+            ucb    = 0
+
+        return (locked, ber, signal, snr, ucb)
 
-        equalsindex = line.find('= ',spaceindex) + 2
-        snr = int(line[equalsindex:])
+    def get_variable(self, var):
+        (errcode, errmsg, value) = self.execute_command('get ' + var)
+        if errcode != 0:
+            return None
+        return value
 
-        return (locked, ber, signal, snr)
 
 class ControlConnection:
+    """
+    Class implementing a connection to a DVBStreamer daemon.
+    """
     def __init__(self, host, adapter):
+        """
+        Create a connection object to communicate with a DVBStreamer daemon.
+        """
         self.host = host
         self.adapter = adapter
         self.opened = False
+        self.version = None
+        self.welcome_message = None
+        self.my_ip = None
 
     def open(self):
+        """
+        Open the connection to the DVBStreamer daemon.
+        """
         if self.opened:
             return
         self.socket = socket(AF_INET,SOCK_STREAM)
         self.socket.connect((self.host, self.adapter + 54197))
+
+        self.my_ip = self.socket.getsockname()[0]
+
         self.socket_file = self.socket.makefile('r+')
         self.opened = True
         (error_code, error_message, lines) = self.read_response()
@@ -185,12 +262,18 @@
         return self.opened
 
     def close(self):
+        """
+        Close the connection to the DVBStreamer daemon.
+        """
         if self.opened:
             self.socket_file.close()
             self.socket.close()
             self.opened = False
 
     def send_command(self, command):
+        """
+        Send a command to the connection DVBStreamer daemon.
+        """
         if not self.opened:
             raise RuntimeError, 'not connected'
 
@@ -200,6 +283,11 @@
         return self.read_response()
 
     def read_response(self):
+        """
+        Read a response from the DVBStreamer deamon after a command has been
+        sent.
+        Returns a tuple of error code, error message and response lines.
+        """
         more_lines = True
         lines = []
         error_code = -1

Modified: branches/rel-1/freevo/src/tv/plugins/dvbstreamer/live_pause.py
==============================================================================
--- branches/rel-1/freevo/src/tv/plugins/dvbstreamer/live_pause.py      
(original)
+++ branches/rel-1/freevo/src/tv/plugins/dvbstreamer/live_pause.py      Sun Mar 
16 17:24:48 2008
@@ -331,7 +331,12 @@
         if self.adapter_in_use != adapter:
             self.adapter_in_use = adapter
             try:
-                self.manager.enable_udp_output(self.adapter_in_use)
+                if adapter.find(':') != -1:
+                    my_ip = self.manager.controllers[adapter].my_ip
+                else:
+                    my_ip = 'localhost'
+
+                self.manager.enable_udp_output(self.adapter_in_use, my_ip, 
1234)
             except:
                 _debug_('Failed to enable output! ' + traceback.format_exc())
 
@@ -533,7 +538,7 @@
 
     def __osd_write(self, text):
         if self.app:
-            self.app.write('OSDWriteText$%s\n' % text)
+            self.app.write('OSDWriteText$    %s\n' % text)
 
     def __draw_state_screen(self):
         osd_obj = osd.get_singleton()

Modified: branches/rel-1/freevo/src/tv/plugins/dvbstreamer/manager.py
==============================================================================
--- branches/rel-1/freevo/src/tv/plugins/dvbstreamer/manager.py (original)
+++ branches/rel-1/freevo/src/tv/plugins/dvbstreamer/manager.py Sun Mar 16 
17:24:48 2008
@@ -39,16 +39,14 @@
     def __init__(self, username, password):
         self.username = username
         self.password = password
-        self.destip   = 'localhost'
-        self.destport = 1234
         self.controllers = {}
 
 
-    def get_udp_mrl(self):
+    def get_udp_mrl(self, ip_address, port):
         """
         Get the mrl to use for dvbstreamer and xine.
         """
-        return 'udp://%s:%d' %(self.destip, self.destport)
+        return 'udp://%s:%d' %(ip_address, port)
 
 
     def get_file_mrl(self, filename):
@@ -58,11 +56,11 @@
         return 'file://%s' % filename
 
 
-    def enable_udp_output(self, adapter):
+    def enable_udp_output(self, adapter, ip_address, port):
         """
         Enable UDP output to localhost:1234
         """
-        self.set_mrl(adapter, self.get_udp_mrl())
+        self.set_mrl(adapter, self.get_udp_mrl(ip_address,port))
 
 
     def enable_file_output(self, adapter, filename):
@@ -75,7 +73,7 @@
         """
         Disable output from the specified dvbstreamer instance.
         """
-        _debug_('Disabling output on adapter %d' % adapter)
+        _debug_('Disabling output on adapter %s' % adapter)
         self.set_mrl(adapter,  'null://')
 
 
@@ -83,9 +81,9 @@
         """
         Select a channel on the specified dvbstreamer instance.
         """
-        _debug_('Selecting channel %s on adapter %d'%(channel, adapter))
+        _debug_('Selecting channel %s on adapter %s'%(channel, adapter))
         controller = self.get_controller(adapter)
-        controller.select_service(channel)
+        controller.set_current_service(channel)
 
 
     def set_mrl(self, adapter, mrl):
@@ -102,6 +100,12 @@
         """
         if adapter in self.controllers:
             return self.controllers[adapter]
-        controller = comms.Controller('localhost', adapter, self.username, 
self.password)
+        if adapter.find(':') != -1:
+            ip_address,dvb_adapter = adapter.split(':',2)
+            dvb_adapter = int(dvb_adapter)
+        else:
+            ip_address = 'localhost'
+            dvb_adapter = int(adapter)
+        controller = comms.Controller(ip_address, dvb_adapter, self.username, 
self.password)
         self.controllers[adapter] = controller
         return controller

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to