home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / rhythmbox / plugins / upnp_coherence / UpnpSource.py < prev    next >
Encoding:
Python Source  |  2009-04-07  |  5.8 KB  |  145 lines

  1. # Licensed under the MIT license
  2. # http://opensource.org/licenses/mit-license.php
  3. #
  4. # Copyright 2007, James Livingston  <doclivingston@gmail.com>
  5. # Copyright 2007,2008 Frank Scholz <coherence@beebits.net>
  6.  
  7. import rb, rhythmdb
  8. import gobject, gtk
  9.  
  10. from coherence import __version_info__ as coherence_version
  11.  
  12. from coherence import log
  13. from coherence.upnp.core import DIDLLite
  14.  
  15. class UpnpSource(rb.BrowserSource,log.Loggable):
  16.  
  17.     logCategory = 'rb_media_store'
  18.  
  19.     __gproperties__ = {
  20.         'plugin': (rb.Plugin, 'plugin', 'plugin', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
  21.         'client': (gobject.TYPE_PYOBJECT, 'client', 'client', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
  22.         'udn': (gobject.TYPE_PYOBJECT, 'udn', 'udn', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
  23.     }
  24.  
  25.     def __init__(self):
  26.         rb.BrowserSource.__init__(self)
  27.         self.__db = None
  28.         self.__activated = False
  29.         self.container_watch = []
  30.         if coherence_version < (0,5,1):
  31.             self.process_media_server_browse = self.old_process_media_server_browse
  32.         else:
  33.             self.process_media_server_browse = self.new_process_media_server_browse
  34.  
  35.     def do_set_property(self, property, value):
  36.         if property.name == 'plugin':
  37.             self.__plugin = value
  38.         elif property.name == 'client':
  39.             self.__client = value
  40.             self.props.name = self.__client.device.get_friendly_name()
  41.         elif property.name == 'udn':
  42.             self.__udn = value
  43.         else:
  44.             raise AttributeError, 'unknown property %s' % property.name
  45.  
  46.  
  47.     def do_impl_activate(self):
  48.         if not self.__activated:
  49.             print "activating upnp source"
  50.             self.__activated = True
  51.  
  52.             shell = self.get_property('shell')
  53.             self.__db = shell.get_property('db')
  54.             self.__entry_type = self.get_property('entry-type')
  55.  
  56.             # load upnp db
  57.             self.load_db(0)
  58.             self.__client.content_directory.subscribe_for_variable('ContainerUpdateIDs', self.state_variable_change)
  59.             self.__client.content_directory.subscribe_for_variable('SystemUpdateID', self.state_variable_change)
  60.  
  61.  
  62.     def load_db(self, id):
  63.         d = self.__client.content_directory.browse(id, browse_flag='BrowseDirectChildren', process_result=False, backward_compatibility=False)
  64.         d.addCallback(self.process_media_server_browse, self.__udn)
  65.  
  66.  
  67.     def state_variable_change(self, variable, udn=None):
  68.         self.info("%s changed from >%s< to >%s<", variable.name, variable.old_value, variable.value)
  69.         if variable.old_value == '':
  70.             return
  71.  
  72.         if variable.name == 'SystemUpdateID':
  73.             self.load_db(0)
  74.         elif variable.name == 'ContainerUpdateIDs':
  75.             changes = variable.value.split(',')
  76.             while len(changes) > 1:
  77.                 container = changes.pop(0).strip()
  78.                 update_id = changes.pop(0).strip()
  79.                 if container in self.container_watch:
  80.                     self.info("we have a change in %r, container needs a reload", container)
  81.                     self.load_db(container)
  82.  
  83.  
  84.     def new_process_media_server_browse(self, results, udn):
  85.         didl = DIDLLite.DIDLElement.fromString(results['Result'])
  86.         for item in didl.getItems():
  87.             self.info("process_media_server_browse %r %r", item.id, item)
  88.             if item.upnp_class.startswith('object.container'):
  89.                 self.load_db(item.id)
  90.             if item.upnp_class.startswith('object.item.audioItem'):
  91.  
  92.                 url = None
  93.                 duration = None
  94.                 size = None
  95.                 bitrate = None
  96.  
  97.                 for res in item.res:
  98.                     remote_protocol,remote_network,remote_content_format,remote_flags = res.protocolInfo.split(':')
  99.                     self.info("%r %r %r %r",remote_protocol,remote_network,remote_content_format,remote_flags)
  100.                     if remote_protocol == 'http-get':
  101.                         url = res.data
  102.                         duration = res.duration
  103.                         size = res.size
  104.                         bitrate = res.bitrate
  105.                         break
  106.  
  107.                 if url is not None:
  108.                     self.info("url %r %r",url,item.title)
  109.  
  110.                     entry = self.__db.entry_lookup_by_location (url)
  111.                     if entry == None:
  112.                         entry = self.__db.entry_new(self.__entry_type, url)
  113.  
  114.                     self.__db.set(entry, rhythmdb.PROP_TITLE, item.title)
  115.                     try:
  116.                         if item.artist is not None:
  117.                             self.__db.set(entry, rhythmdb.PROP_ARTIST, item.artist)
  118.                     except AttributeError:
  119.                         pass
  120.                     try:
  121.                         if item.album is not None:
  122.                             self.__db.set(entry, rhythmdb.PROP_ALBUM, item.album)
  123.                     except AttributeError:
  124.                         pass
  125.  
  126.                     try:
  127.                         self.info("%r %r", item.title,item.originalTrackNumber)
  128.                         if item.originalTrackNumber is not None:
  129.                             self.__db.set(entry, rhythmdb.PROP_TRACK_NUMBER, int(item.originalTrackNumber))
  130.                     except AttributeError:
  131.                         pass
  132.  
  133.                     if duration is not None:
  134.                         h,m,s = duration.split(':')
  135.                         seconds = int(h)*3600 + int(m)*60 + int(s)
  136.                         self.info("%r %r:%r:%r %r", duration, h, m , s, seconds)
  137.                         self.__db.set(entry, rhythmdb.PROP_DURATION, seconds)
  138.  
  139.                     if size is not None:
  140.                         self.__db.set(entry, rhythmdb.PROP_FILE_SIZE,int(size))
  141.  
  142.                     self.__db.commit()
  143.  
  144. gobject.type_register(UpnpSource)
  145.