Package brisa :: Package upnp :: Package services :: Package cds :: Module content_directory
[hide private]
[frames] | no frames]

Source Code for Module brisa.upnp.services.cds.content_directory

  1  # Licensed under the MIT license 
  2  # http://opensource.org/licenses/mit-license.php or see LICENSE file. 
  3  # Copyright 2005, Tim Potter <tpot@samba.org> 
  4  # Copyright 2006 John-Mark Gurney <gurney_j@resnet.uoregon.edu> 
  5  # Copyright 2007-2008 Brisa Team <brisa-develop@garage.maemo.org> 
  6   
  7  """ Content Directory service implementation. 
  8   
  9  Common usage is to just add a ContentDirectory class instance to a device. 
 10  """ 
 11   
 12  import os.path 
 13   
 14  from brisa.core import log, plugin_manager 
 15  from brisa.upnp.device import Service 
 16  from brisa.upnp.didl.didl_lite import Element 
 17  from brisa.upnp.services.xmls import xml_path 
 18   
 19   
 20  log = log.getLogger('services.cds') 
 21   
 22  service_name = 'ContentDirectory' 
 23  service_type = 'urn:schemas-upnp-org:service:ContentDirectory:1' 
 24  scpd_xml_path = os.path.join(xml_path, 'content-directory-scpd.xml') 
 25   
 26   
27 -def compare_objects(a, b):
28 """ Compares two DIDL objects by their title for proper sorting. 29 30 @param a: A DIDL object to be compared with. 31 @param b: A DIDL object to compare with. 32 33 @type a: DIDL 34 @type b: DIDL 35 36 @return: The comparation result. 37 @rtype: boolean 38 """ 39 if a.title.lower().startswith("all "): 40 return -1 41 42 if b.title.lower().startswith("all "): 43 return 1 44 45 return cmp(a.title.lower(), b.title.lower())
46 47
48 -class ContentDirectory(Service):
49 """ Content Directory service implementation (version 1.0). 50 """ 51
52 - def __init__(self, plugins_folder, plugins_module_str):
53 Service.__init__(self, service_name, service_type, '', scpd_xml_path) 54 self.plugin_manager = plugin_manager.PluginManager(plugins_folder, 55 plugins_module_str) 56 self.updateID = 0
57
58 - def start(self):
59 """ Starts the ContentDirectory by loading the plugins. 60 """ 61 self.plugin_manager.load_plugins()
62
63 - def stop(self):
64 """ Stops the ContentDirectory servie by unloading the plugins. 65 """ 66 self.plugin_manager.unload_plugins()
67
68 - def publish(self, webserver):
71
72 - def soap_GetSearchCapabilities(self, *args, **kwargs):
73 """ Returns the search capabilities supported by the device. 74 75 @param args: list of arguments for the GetSearchCapabilities UPnP\ 76 function 77 @param kwargs: dict of arguments for the GetSearchCapabilities UPnP\ 78 function 79 80 @type args: list 81 @type kwargs: dict 82 83 @return: the search capabilities supported by the device 84 @rtype: dict 85 """ 86 log.debug('Action on ContentDirectory: GetSearchCapabilities()') 87 # While the search method is not properly implemented, the server does 88 # not support search. 89 return {'SearchCaps': ''}
90
91 - def soap_GetSortCapabilities(self, *args, **kwargs):
92 """ Returns the CSV list of meta-data tags that can be used in 93 sortCriteria. 94 95 @param args: list of arguments for the GetSortCapabilities UPnP\ 96 function 97 @param kwargs: dict of arguments for the GetSortCapabilities UPnP\ 98 function 99 100 @type args: list 101 @type kwargs: dict 102 103 @return: CSV list of meta-data 104 @rtype: dict 105 """ 106 log.debug('Action on ContentDirectory: GetSortCapabilities()') 107 return {'SortCaps': 'dc:title'}
108
109 - def soap_GetSystemUpdateID(self, *args, **kwargs):
110 """ Returns the current value of state variable SystemUpdateID. 111 112 @param args: list of arguments for the GetSystemUpdateID UPnP\ 113 function 114 @param kwargs: dict of arguments for the GetSystemUPdateID UPnP\ 115 function 116 117 @type args: list 118 @type kwargs: dict 119 120 @return: current value of SystemUpdateID 121 @rtype: dict 122 """ 123 log.debug('Action on ContentDirectory: GetSystemUpdateID()') 124 return {'Id': self.updateID}
125
126 - def soap_Browse(self, *args, **kwargs):
127 """ Implements the Browse action for the ContentDirectory. 128 129 @param args: list of arguments for the Browse UPnP\ 130 function 131 @param kwargs: dict of arguments for the Browse UPnP\ 132 function 133 134 @type args: list 135 @type kwargs: dict 136 137 @return: the results of the browsing 138 @rtype: dict 139 """ 140 log.debug('Action on ContentDirectory: Browse%s', args) 141 # Formats the parameters for the real soap browse 142 args = (kwargs['ObjectID'], kwargs['BrowseFlag'], kwargs['Filter'], 143 kwargs['StartingIndex'], kwargs['RequestedCount'], 144 kwargs['SortCriteria']) 145 l = {} 146 l['query'] = 'Browse(ObjectID=%s, BrowseFlags=%s, Filter=%s, ' \ 147 'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % \ 148 tuple(map(repr, args)) 149 try: 150 ret = self._soap_Browse(*args) 151 except Exception, e: 152 log.error('Action Browse on ContentDirectory: %s', e.message) 153 154 l['response'] = ret 155 156 return ret
157
158 - def _soap_Browse(self, *args):
159 """ Real implementation of the soap browse. 160 161 @param args: list of arguments 162 @type args: list 163 164 @return: the results of browsing 165 @rtype: dict 166 """ 167 (object_id, browse_flag, filter, starting_index, requested_count, 168 sort_criteria) = args 169 try: 170 starting_index = int(starting_index) 171 requested_count = int(requested_count) 172 last_index = None 173 plugin = self.plugin_manager.root_plugin 174 175 if browse_flag == 'BrowseDirectChildren' and \ 176 requested_count != 0: 177 last_index = requested_count + starting_index 178 179 if ':' in object_id: 180 namespace = object_id.split(':')[0] 181 plugin = self.plugin_manager.plugins_instances[namespace] 182 183 if not plugin: 184 log.error('Could not get plugin associated with this'\ 185 'browse action on id %s' % object_id) 186 187 elements = plugin.browse(object_id, browse_flag, filter, 188 starting_index, requested_count, 189 sort_criteria) 190 191 elements.sort(cmp=compare_objects) 192 didl = Element() 193 total = 0 194 195 if plugin.has_browse_filter: 196 for item in elements: 197 didl.add_item(item) 198 total = total + 1 199 else: 200 for item in elements[starting_index: last_index]: 201 didl.add_item(item) 202 total = total + 1 203 204 didl_xml = didl.to_string() 205 soap_result = {'Result': didl_xml, 206 'TotalMatches': len(elements), 207 'NumberReturned': total, 208 'UpdateID': self.updateID} 209 except Exception, e: 210 soap_result = {'Result': '', 211 'TotalMatches': 0, 212 'NumberReturned': 0, 213 'UpdateID': self.updateID} 214 log.error('ContentDirectory.Browse internal problem: %s', e) 215 216 return soap_result
217
218 - def soap_Search(self, *args, **kwargs):
219 """ Search for objects that match some search criteria. 220 221 @param args: list of arguments for the Search UPnP function 222 @param kwargs: dict of arguments for the Search UPnP function 223 224 @type args: list 225 @type kwargs: dict 226 227 TODO: forward the search to the respective plugin. 228 TODO: implement the search. 229 """ 230 return {'Result': '', 231 'NumberReturned': 0, 232 'TotalMatches': 0, 233 'UpdateID': self.updateID}
234