Package brisa :: Package upnp :: Package didl :: Module didl_lite
[hide private]
[frames] | no frames]

Source Code for Module brisa.upnp.didl.didl_lite

   1  # Licensed under the MIT license 
   2  # http://opensource.org/licenses/mit-license.php or see LICENSE file. 
   3  # Copyright 2007-2008 Brisa Team <brisa-develop@garage.maemo.org> 
   4   
   5  """ DIDL-Lite classes (object, items, containers and etc). 
   6  """ 
   7   
   8  from xml.etree.ElementTree import _ElementInterface 
   9  from xml.etree import cElementTree as ElementTree 
  10   
  11  from brisa.core import log 
  12  from brisa.core.network import parse_xml 
  13   
  14  from brisa.upnp.didl import dlna 
  15   
  16   
  17  ns = {'didl': 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/', 
  18        'dc': 'http://purl.org/dc/elements/1.1/', 
  19        'upnp': 'urn:schemas-upnp-org:metadata-1-0/upnp/', 
  20        'dlna': 'urn:schemas-dlna-org:metadata-1-0'} 
21 22 23 -def find(elt, namespace, key):
24 f = elt.find('{%s}%s' % (ns[namespace], key)) 25 if f is None: 26 return () 27 return f
28
29 30 -def findall(elt, namespace, key):
31 f = elt.findall('{%s}%s' % (ns[namespace], key)) 32 if f is None: 33 return () 34 return f
35
36 37 -class Resource(object):
38 """Represents a resource. Used for generating the DIDL XML messages. 39 """ 40
41 - def __init__(self, value='', protocol_info='', import_uri='', size=None, 42 duration='', bitrate=None, sample_frequency=None, 43 bits_per_sample=None, nr_audio_channels=None, resolution='', 44 color_depth=None, protection=''):
45 """ Constructor for the Resource class. 46 47 @param value: value of the res tag 48 @param protocol_info: information about the protocol in the form 49 a:b:c:d 50 @param import_uri: uri locator for resource update 51 @param size: size in bytes 52 @param duration: duration of the playback of the res at normal speed 53 (H*:MM:SS:F* or H*:MM:SS:F0/F1) 54 @param bitrate: bitrate in bytes/second 55 @param sample_frequency: sample frequency in Hz 56 @param bits_per_sample: bits per sample 57 @param nr_audio_channels: number of audio channels 58 @param resolution: resolution of the resource (X*Y) 59 @param color_depth: color depth in bits 60 @param protection: statement of protection type 61 62 @type protocol_info: string 63 @type import_uri: string 64 @type size: int 65 @type duration: string 66 @type bitrate: int 67 @type sample_frequency: int 68 @type bits_per_sample: int 69 @type nr_audio_channels: int 70 @type resolution: string 71 @type color_depth: int 72 @type protection: string 73 """ 74 self.value = value 75 self.protocol_info = protocol_info 76 self.import_uri = import_uri 77 self.size = size 78 self.duration = duration 79 self.bitrate = bitrate 80 self.sample_frequency = sample_frequency 81 self.bits_per_sample = bits_per_sample 82 self.nr_audio_channels = nr_audio_channels 83 self.resolution = resolution 84 self.color_depth = color_depth 85 self.protection = protection
86
87 - def from_element(self, elt):
88 """ Sets the resource properties from an element. 89 """ 90 if 'protocolInfo' not in elt.attrib: 91 raise Exception('Could not create Resource from Element: '\ 92 'protocolInfo not found (required).') 93 94 # Required 95 self.protocol_info = elt.attrib['protocolInfo'] 96 97 # Optional 98 self.import_uri = elt.attrib.get('importUri', '') 99 self.size = elt.attrib.get('size', None) 100 self.duration = elt.attrib.get('duration', '') 101 self.bitrate = elt.attrib.get('bitrate', None) 102 self.sample_frequency = elt.attrib.get('sampleFrequency', None) 103 self.bits_per_sample = elt.attrib.get('bitsPerSample', None) 104 self.nr_audio_channels = elt.attrib.get('nrAudioChannels', None) 105 self.resolution = elt.attrib.get('resolution', '') 106 self.color_depth = elt.attrib.get('colorDepth', None) 107 self.protection = elt.attrib.get('protection', '') 108 self.value = elt.text
109 110 @classmethod
111 - def from_string(cls, xml_string):
112 """ Returns an instance generated from a xml string. 113 """ 114 instance = cls() 115 elt = parse_xml(xml_string) 116 instance.from_element(elt.getroot()) 117 return instance
118
119 - def to_didl_element(self):
120 """ Returns an Element based on this Resource. 121 """ 122 if not self.protocol_info: 123 raise Exception('Could not create Element for this resource: '\ 124 'protocolInfo not set (required).') 125 root = ElementTree.Element('res') 126 127 # Required 128 root.attrib['protocolInfo'] = self.protocol_info 129 130 # Optional 131 if self.import_uri: 132 root.attrib['importUri'] = self.importUri 133 if self.size: 134 root.attrib['size'] = self.size 135 if self.duration: 136 root.attrib['duration'] = self.duration 137 if self.bitrate: 138 root.attrib['bitrate'] = self.bitrate 139 if self.sample_frequency: 140 root.attrib['sampleFrequency'] = self.sample_frequency 141 if self.bits_per_sample: 142 root.attrib['bitsPerSample'] = self.bits_per_sample 143 if self.nr_audio_channels: 144 root.attrib['nrAudioChannels'] = self.nr_audio_channels 145 if self.resolution: 146 root.attrib['resolution'] = self.resolution 147 if self.color_depth: 148 root.attrib['colorDepth'] = self.color_depth 149 if self.protection: 150 root.attrib['protection'] = self.protection 151 152 root.text = self.value 153 154 return root
155 156 157 # upnp:writeStatus possible values 158 WRITE_STATUS_NOT_WRITABLE, WRITE_STATUS_WRITABLE, WRITE_STATUS_PROTECTED, \ 159 WRITE_STATUS_UNKNOWN, WRITE_STATUS_MIXED = ('NOT_WRITABLE', 'WRITABLE', 160 'PROTECTED', 'UNKNOWN', 'MIXED')
161 162 163 -class Object(object):
164 """ Root class and most basic class of the content directory class 165 hierarchy. 166 """ 167 168 upnp_class = 'object' 169 element_name = 'object' 170
171 - def __init__(self, id='', parent_id='', title='', restricted=False, 172 creator='', write_status=WRITE_STATUS_NOT_WRITABLE):
173 """ Constructor for the Object class. 174 175 @param id: unique identifier for the object 176 @param parent_id: id of object's parent 177 @param title: name of the object 178 @param restricted: True if only CDS can modify the object 179 @param creator: content creator or owner 180 @param write_status: modifiability of the resources of this object. 181 Integer parameter based on WRITE_STATUS_* 182 constants 183 184 @type id: string 185 @type parent_id: string 186 @type title: string 187 @type restricted: bool 188 @type creator: string 189 @type write_status: integer 190 """ 191 self.resources = [] 192 self.id = id 193 self.parent_id = parent_id 194 self.title = title 195 self.creator = creator 196 self.restricted = restricted 197 self.write_status = write_status
198
199 - def add_resource(self, res):
200 """ Adds a resource to the object. 201 """ 202 if res not in self.resources: 203 self.resources.append(res)
204
205 - def from_element(self, elt):
206 """ Sets the object properties from an element. 207 """ 208 req_attr_not_present = 'Could not create Object from Element: %s '\ 209 'attribute not present (required).' 210 211 # Check required attributes 212 if 'id' not in elt.attrib: 213 raise Exception(req_attr_not_present % 'id') 214 if 'parentID' not in elt.attrib: 215 raise Exception(req_attr_not_present % 'parentID') 216 if 'restricted' not in elt.attrib: 217 raise Exception(req_attr_not_present % 'restricted') 218 219 upnp_class_elt = find(elt, 'upnp', 'class') 220 if not upnp_class_elt.text: 221 raise Exception(req_attr_not_present % 'upnp:class') 222 223 title_elt = find(elt, 'dc', 'title') 224 if not title_elt.text: 225 raise Exception(req_attr_not_present % 'dc:title') 226 227 self.element_name = elt.tag 228 self.resources = [] 229 230 # Required 231 self.id = elt.attrib['id'] 232 self.parent_id = elt.attrib['parentID'] 233 self.restricted = {True: 'true', False: 'false'}\ 234 .get(elt.attrib['restricted'], True) 235 self.upnp_class = upnp_class_elt.text 236 self.title = title_elt.text 237 238 # Optional 239 write_status_elt = find(elt, 'upnp', 'writeStatus') 240 if write_status_elt: 241 self.write_status = write_status_elt.text 242 243 creator_elt = find(elt, 'dc', 'creator') 244 if creator_elt: 245 self.creator = creator_elt.text 246 247 for res in findall(elt, 'didl', 'res'): 248 self.resources.append(\ 249 Resource.from_string(ElementTree.tostring(res)))
250 251 @classmethod
252 - def from_string(cls, xml_string):
253 """ Returns an instance generated from a xml string. 254 """ 255 instance = cls() 256 elt = parse_xml(xml_string) 257 instance.from_element(elt.getroot()) 258 return instance
259
260 - def to_didl_element(self):
261 """ Returns an Element based on this Resource. 262 """ 263 root = ElementTree.Element(self.element_name) 264 root.attrib['id'] = str(self.id) 265 root.attrib['parentID'] = str(self.parent_id) 266 ElementTree.SubElement(root, 'dc:title').text = self.title 267 ElementTree.SubElement(root, 'upnp:class').text = self.upnp_class 268 269 if self.restricted: 270 root.attrib['restricted'] = 'true' 271 else: 272 root.attrib['restricted'] = 'false' 273 274 if self.creator: 275 ElementTree.SubElement(root, 'dc:creator').text = self.creator 276 if self.write_status: 277 ElementTree.SubElement(root, 'upnp:writeStatus').text = \ 278 self.write_status 279 280 for r in self.resources: 281 root.append(r.to_didl_element()) 282 283 return root
284
285 - def to_string(self):
286 """ String representation of this object. 287 """ 288 return ElementTree.tostring(self.to_didl_element())
289
290 291 -class SearchClass(object):
292 """ Instances of this class may be passed to search_classes parameter of 293 Container constructors. 294 """ 295
296 - def __init__(self, class_name, include_derived=False, 297 class_friendly_name=''):
298 self.class_name = class_name 299 self.class_friendly_name = class_friendly_name 300 self.include_derived = include_derived
301
302 - def get_element(self):
303 if not self.include_derived: 304 raise Exception('Could not create Element from SearchClass: '\ 305 'includeDerived attribute missing (required).') 306 307 elt = ElementTree.Element('upnp:searchClass') 308 elt.attrib['includeDerived'] = {True: 'true', False: 'false'}\ 309 .get(self.include_derived, False) 310 311 if self.class_friendly_name: 312 elt.attrib['name'] = self.class_friendly_name 313 314 elt.text = self.class_name 315 return elt
316
317 318 -class CreateClass(SearchClass):
319 """ Instances of this class may be passed to create_classes parameter of 320 Container constructors. 321 """ 322
323 - def get_element(self):
324 if not self.include_derived: 325 raise Exception('Could not create Element from CreateClass: '\ 326 'includeDerived attribute missing (required).') 327 328 elt = ElementTree.Element('upnp:createClass') 329 elt.attrib['includeDerived'] = {True: 'true', False: 'false'}\ 330 .get(self.include_derived, False) 331 332 if self.class_friendly_name: 333 elt.attrib['name'] = self.class_friendly_name 334 335 elt.text = self.class_name 336 return elt
337
338 339 -class Container(Object):
340 """ An object that can contain other objects. 341 """ 342 343 upnp_class = '%s%s' % (Object.upnp_class, '.container') 344 element_name = 'container' 345 create_class = None 346 _count = 0 347
348 - def __init__(self, id='', parent_id='', title='', restricted=False, 349 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 350 searchable=True, search_classes=[], create_classes=[]):
351 """ Constructor for the Container class. 352 353 @param id: unique identifier for the object 354 @param parent_id: id of object's parent 355 @param title: name of the object 356 @param restricted: True if only CDS can modify the object 357 @param creator: content creator or owner 358 @param write_status: modifiability of the resources of this object. 359 Integer parameter based on WRITE_STATUS_* 360 constants 361 @param searchable: if True, Search action can be performed upon the 362 container 363 @param search_classes: list of SearchClass objects 364 @param create_classes: list of CreateClass objects 365 366 @type id: string 367 @type parent_id: string 368 @type title: string 369 @type restricted: bool 370 @type creator: string 371 @type write_status: integer 372 @type searchable: bool 373 @type search_classes: list 374 @type create_classes: list 375 """ 376 Object.__init__(self, id, parent_id, title, restricted, creator, 377 write_status) 378 self.searchable = searchable 379 self.search_classes = search_classes 380 self.create_classes = create_classes 381 self.containers = [] 382 self.items = []
383
384 - def _get_child_count(self):
385 if self.containers or self.items: 386 return len(self.containers) + len(self.items) 387 return self._count
388
389 - def _set_child_count(self, c):
390 self._count = c
391 392 child_count = property(_get_child_count, _set_child_count) 393
394 - def from_element(self, elt):
395 """ Sets Container attributes from an Element. 396 """ 397 Object.from_element(self, elt) 398 self.child_count = int(elt.attrib.get('childCount', '0')) 399 self.searchable = elt.attrib.get('searchable', '0') in \ 400 ['True', 'true', '1'] 401 self.search_classes = [] 402 403 for s in findall(elt, 'upnp', 'searchClass'): 404 self.search_classes.append(SearchClass(s.text, 405 s.attrib['includeDerived'], 406 s.attrib.get('name', ''))) 407 408 for c in findall(elt, 'upnp', 'createClass'): 409 self.create_classes.append(CreateClass(c.text, 410 c.attrib['includeDerived'], 411 c.attrib.get('name', '')))
412
413 - def to_didl_element(self):
414 """ Creates Element from this Container. 415 """ 416 root = Object.to_didl_element(self) 417 root.attrib['childCount'] = str(self.child_count) 418 419 for s in self.search_classes: 420 root.append(s.get_element()) 421 for c in self.create_classes: 422 root.append(c.get_element()) 423 424 root.attrib['searchable'] = {True: 'true', False: 'false'}\ 425 .get(self.searchable) 426 427 return root
428
429 - def add_item(self, item):
430 """ Adds a item to the container. 431 """ 432 if item not in self.items: 433 self.items.append(item) 434 item.parent_id = self.id
435
436 - def add_container(self, c):
437 """ Adds a container to the container. 438 """ 439 if c not in self.containers: 440 self.containers.append(c) 441 c.parent_id = self.id
442
443 444 -class Item(Object):
445 """ A class used to represent atomic (non-container) content 446 objects. 447 """ 448 upnp_class = '%s%s' % (Object.upnp_class, '.item') 449 element_name = 'item' 450
451 - def __init__(self, id='', parent_id='', title='', restricted=False, 452 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 453 ref_id=''):
454 """ Constructor for the Item class. 455 456 @param id: unique identifier for the object 457 @param parent_id: id of object's parent 458 @param title: name of the object 459 @param restricted: True if only CDS can modify the object 460 @param creator: content creator or owner 461 @param write_status: modifiability of the resources of this object. 462 Integer parameter based on WRITE_STATUS_* 463 constants 464 @param ref_id: id property of the item being referred to 465 466 @type id: string 467 @type parent_id: string 468 @type title: string 469 @type restricted: bool 470 @type creator: string 471 @type write_status: integer 472 @type ref_id: string 473 """ 474 Object.__init__(self, id, parent_id, title, restricted, creator, 475 write_status) 476 self.ref_id = ref_id
477
478 - def from_element(self, elt):
479 """ Sets the resource properties from an element. 480 """ 481 Object.from_element(self, elt) 482 self.ref_id = elt.attrib.get('refID', '')
483
484 - def to_didl_element(self):
485 root = Object.to_didl_element(self) 486 root.attrib['refID'] = self.ref_id 487 return root
488
489 - def _get_uri(self):
490 if len(self.resources) > 0: 491 return self.resources[0].value 492 else: 493 return ''
494 495 uri = property(fget=_get_uri)
496
497 498 -class AudioItem(Item):
499 """ A piece of content that when rendered generates audio. 500 """ 501 upnp_class = '%s%s' % (Item.upnp_class, '.audioItem') 502
503 - def __init__(self, id='', parent_id='', title='', restricted=False, 504 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 505 genres=[], description='', long_description='', publishers=[], 506 language='', relations=[], rights=[]):
507 """ Constructor for the Item class. 508 509 @param id: unique identifier for the object 510 @param parent_id: id of object's parent 511 @param title: name of the object 512 @param restricted: True if only CDS can modify the object 513 @param creator: content creator or owner 514 @param write_status: modifiability of the resources of this object. 515 Integer parameter based on WRITE_STATUS_* 516 constants 517 @param ref_id: id property of the item being referred to 518 @param genres: genres to which the object belongs 519 @param description: description 520 @param long_description: long description 521 @param publishers: entities responsible for making the resource 522 available 523 @param language: language of the resource 524 @param relations: related resources 525 @param rights: rights held in and over the resource 526 527 @type id: string 528 @type parent_id: string 529 @type title: string 530 @type restricted: bool 531 @type creator: string 532 @type write_status: integer 533 @type ref_id: string 534 @type genres: list 535 @type description: string 536 @type long_description: string 537 @type publishers: list 538 @type language: string 539 @type relations: list 540 @type rights: list 541 """ 542 Item.__init__(self, id, parent_id, title, restricted, creator, 543 write_status, ref_id) 544 self.genres = genres 545 self.description = description 546 self.long_description = long_description 547 self.publishers = publishers 548 self.language = language 549 self.relations = relations 550 self.rights = rights
551
552 - def from_element(self, elt):
553 """ Sets AudioItem properties from an element. 554 """ 555 Item.from_element(self, elt) 556 long_desc_elt = find(elt, 'upnp', 'longDescription') 557 desc_elt = find(elt, 'dc', 'description') 558 559 self.genres = [g.text for g in findall(elt, 'upnp', 'genre')] 560 self.publishers = [p.text for p in findall(elt, 'dc', 'publisher')] 561 self.relations = [r.text for r in findall(elt, 'dc', 'relation')] 562 self.rights = [r.text for r in findall(elt, 'dc', 'rights')] 563 564 if long_desc_elt: 565 self.long_description = long_desc_elt.text 566 567 if desc_elt: 568 self.description = desc_elt.text
569
570 - def to_didl_element(self):
571 """ Create Element from AudioItem. 572 """ 573 root = Item.to_didl_element(self) 574 575 for g in self.genres: 576 ElementTree.SubElement(root, 'upnp:genre').text = g 577 for r in self.relations: 578 ElementTree.SubElement(root, 'dc:relation').text = r 579 for r in self.rights: 580 ElementTree.SubElement(root, 'dc:rights').text = r 581 for p in self.publishers: 582 ElementTree.SubElement(root, 'dc:publisher').text = p 583 584 if self.long_description: 585 ElementTree.SubElement(root, 'upnp:longDescription').text =\ 586 self.long_description 587 if self.description: 588 ElementTree.SubElement(root, 'dc:description').text =\ 589 self.description 590 if self.language: 591 ElementTree.SubElement(root, 'dc:language').text = self.language 592 593 return root
594 595 596 # upnp:storageMedium possible values 597 (STORAGE_MEDIUM_UNKNOWN, STORAGE_MEDIUM_DV, STORAGE_MEDIUM_MINI_DV, 598 STORAGE_MEDIUM_VHS, STORAGE_MEDIUM_W_VHS, STORAGE_MEDIUM_S_VHS, 599 STORAGE_MEDIUM_D_VHS, STORAGE_MEDIUM_VHSC, STORAGE_MEDIUM_VIDE08, 600 STORAGE_MEDIUM_HI8, STORAGE_MEDIUM_CD_ROM, STORAGE_MEDIUM_CD_DA, 601 STORAGE_MEDIUM_CD_R, STORAGE_MEDIUM_CD_RW, STORAGE_MEDIUM_VIDEO_CD, 602 STORAGE_MEDIUM_SACD, STORAGE_MEDIUM_MD_AUDIO, STORAGE_MEDIUM_MD_PICTURE, 603 STORAGE_MEDIUM_DVD_ROM, STORAGE_MEDIUM_DVD_VIDEO, STORAGE_MEDIUM_DVD_R, 604 STORAGE_MEDIUM_DVD_PLUS_RW, STORAGE_MEDIUM_DVD_RW, STORAGE_MEDIUM_DVD_RAM, 605 STORAGE_MEDIUM_DVD_AUDIO, STORAGE_MEDIUM_DAT, STORAGE_MEDIUM_LD, 606 STORAGE_MEDIUM_HDD) = ('UNKNOWN', 'DV', 'MINI-DV', 'VHS', 607 'W-VHS', 'S-VHS', 'D-VHS', 'VHSC', 'VIDE08', 'HI8', 'CD-ROM', 'CD-DA', 'CD-R', 608 'CD-RW', 'VIDEO-CD', 'SACD', 'MD-AUDIO', 'MD-PICTURE', 'DVD-ROM', 'DVD-VIDEO', 609 'DVD-R', 'DVD+RW', 'DVD-RW', 'DVD-RAM', 'DVD-AUDIO', 'DAT', 'LD', 'HDD')
610 611 612 -class MusicTrack(AudioItem):
613 """ A discrete piece of audio that should be interpreted as music. 614 """ 615 upnp_class = '%s%s' % (AudioItem.upnp_class, '.musicTrack') 616
617 - def __init__(self, id='', parent_id='', title='', restricted=False, 618 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 619 genres=[], description='', long_description='', publishers=[], 620 language='', relations=[], rights=[], artists=[], albums=[], 621 original_track_number='', playlists=[], storage_medium='', 622 contributors=[], date=''):
623 """ Constructor for the Item class. 624 625 @param id: unique identifier for the object 626 @param parent_id: id of object's parent 627 @param title: name of the object 628 @param restricted: True if only CDS can modify the object 629 @param creator: content creator or owner 630 @param write_status: modifiability of the resources of this object. 631 Integer parameter based on WRITE_STATUS_* 632 constants 633 @param ref_id: id property of the item being referred to 634 @param genres: genres to which the object belongs 635 @param description: description 636 @param long_description: long description 637 @param publishers: entities responsible for making the resource 638 available 639 @param language: language of the resource 640 @param relations: related resources 641 @param rights: rights held in and over the resource 642 @param artists: artists to which the object belongs 643 @param albums: albums to which the object belongs 644 @param original_track_number: original track number on an Audio CD or 645 other medium 646 @param playlists: names of the playlists to which the item belongs 647 @param storage_medium: indicates the type of storage used for the 648 content. Possible values are enumerated on 649 STORAGE_MEDIUM_* variables 650 @param contributors: entities responsible for making contributions to 651 the resource 652 @param date: ISO 8601, form YYYY-MM-DD 653 654 @type id: string 655 @type parent_id: string 656 @type title: string 657 @type restricted: bool 658 @type creator: string 659 @type write_status: integer 660 @type ref_id: string 661 @type genres: list 662 @type description: string 663 @type long_description: string 664 @type publishers: list 665 @type language: string 666 @type relations: list 667 @type rights: list 668 @type artists: list 669 @type albums: list 670 @type original_track_number: int 671 @type playlists: list 672 @type storage_medium: string 673 @type contributors: list 674 @type date: string 675 """ 676 AudioItem.__init__(self, id, parent_id, title, restricted, creator, 677 write_status, ref_id, genres, description, 678 long_description, publishers, language, relations, 679 rights) 680 self.artists = artists 681 self.albums = albums 682 self.original_track_number = original_track_number 683 self.playlists = playlists 684 self.storage_medium = storage_medium 685 self.contributors = contributors 686 self.date = date
687
688 - def from_element(self, elt):
689 """ Set MusicTrack attributes from an element. 690 """ 691 AudioItem.from_element(self, elt) 692 self.artists = [a.text for a in findall(elt, 'upnp', 'artist')] 693 self.albums = [a.text for a in findall(elt, 'upnp', 'album')] 694 self.playlists = [p.text for p in findall(elt, 'upnp', 'playlist')] 695 self.contributors = [c.text for c in findall(elt, 'dc', 'contributor')] 696 trackno_elt = find(elt, 'upnp', 'originalTrackNumber') 697 storage_elt = find(elt, 'upnp', 'storageMedium') 698 date_elt = find(elt, 'dc', 'date') 699 700 if trackno_elt: 701 self.original_track_number = trackno_elt.text 702 if storage_elt: 703 self.storage_medium = storage_elt.text 704 if date_elt: 705 self.date = date_elt.text
706
707 - def to_didl_element(self):
708 """ Create Element from MusicTrack. 709 """ 710 root = AudioItem.to_didl_element(self) 711 712 for a in self.artists: 713 element = ElementTree.SubElement(root, 'upnp:artist') 714 element.attrib['role'] = 'AlbumArtist' 715 element.text = str(a) 716 for a in self.albums: 717 ElementTree.SubElement(root, 'upnp:album').text = a 718 for p in self.playlists: 719 ElementTree.SubElement(root, 'upnp:playlist').text = p 720 for c in self.contributors: 721 ElementTree.SubElement(root, 'dc:contributor').text = c 722 if self.original_track_number: 723 ElementTree.SubElement(root, 'upnp:originalTrackNumber').text = \ 724 str(self.original_track_number) 725 if self.storage_medium: 726 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 727 self.storage_medium 728 if self.date: 729 ElementTree.SubElement(root, 'dc:date').text = self.date 730 731 return root
732
733 734 -class AudioBroadcast(AudioItem):
735 """ A continuous stream of audio. 736 """ 737 upnp_class = '%s%s' % (AudioItem.upnp_class, '.audioBroadcast') 738
739 - def __init__(self, id='', parent_id='', title='', restricted=False, 740 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 741 genres=[], description='', long_description='', publishers=[], 742 language='', relations=[], rights=[], region='', 743 radio_call_sign='', radio_station_id='', radio_band='', 744 channel_nr=None):
745 """ Constructor for the AudioBroadcast class. 746 747 @param id: unique identifier for the object 748 @param parent_id: id of object's parent 749 @param title: name of the object 750 @param restricted: True if only CDS can modify the object 751 @param creator: content creator or owner 752 @param write_status: modifiability of the resources of this object. 753 Integer parameter based on WRITE_STATUS_* 754 constants 755 @param ref_id: id property of the item being referred to 756 @param genres: genres to which the object belongs 757 @param description: description 758 @param long_description: long description 759 @param publishers: entities responsible for making the resource 760 available 761 @param language: language of the resource 762 @param relations: related resources 763 @param rights: rights held in and over the resource 764 @param region: identification of the region of the object (source) 765 @param radio_call_sign: radio station call sign 766 @param radio_station_id: identification of the station (e.g. broadcast 767 frequency) 768 @param radio_band: radio station frequency band 769 @param channel_nr: identification of tuner channels 770 771 @type id: string 772 @type parent_id: string 773 @type title: string 774 @type restricted: bool 775 @type creator: string 776 @type write_status: integer 777 @type ref_id: string 778 @type genres: list 779 @type description: string 780 @type long_description: string 781 @type publishers: list 782 @type language: string 783 @type relations: list 784 @type rights: list 785 @type region: string 786 @type radio_call_sign: string 787 @type radio_station_id: string 788 @type radio_band: string 789 @type channel_nr: int 790 """ 791 AudioItem.__init__(self, id, parent_id, title, restricted, creator, 792 write_status, ref_id, genres, description, 793 long_description, publishers, language, relations, 794 rights) 795 self.region = region 796 self.radio_call_sign = radio_call_sign 797 self.radio_station_id = radio_station_id 798 self.radio_band = radio_band 799 self.channel_nr = channel_nr
800
801 - def to_didl_element(self):
802 """ Create element for this AudioBroadcast. 803 """ 804 root = AudioItem.to_didl_element(self) 805 806 if self.region: 807 ElementTree.SubElement(root, 'upnp:region').text = self.region 808 if self.radio_call_sign: 809 ElementTree.SubElement(root, 'upnp:radioCallSign').text =\ 810 self.radio_call_sign 811 if self.radio_station_id: 812 ElementTree.SubElement(root, 'upnp:radioStationId').text =\ 813 self.radio_station_id 814 if self.radio_band: 815 ElementTree.SubElement(root, 'upnp:radioBand').text = \ 816 self.radio_band 817 if self.channel_nr: 818 ElementTree.SubElement(root, 'upnp:channelNr').text = \ 819 self.channel_nr 820 821 return root
822
823 - def from_element(self, elt):
824 """ Sets AudioBroadcast attributes and properties from an element. 825 """ 826 AudioItem.from_element(self, elt) 827 828 region_elt = find(elt, 'upnp', 'region') 829 radio_sign_elt = find(elt, 'upnp', 'radioCallSign') 830 radio_sid_elt = find(elt, 'upnp', 'radioStationId') 831 radio_band_elt = find(elt, 'upnp', 'radioBand') 832 channel_elt = find(elt, 'upnp', 'channelNr') 833 834 if region_elt: 835 self.region = region_elt.text 836 if radio_sign_elt: 837 self.radio_call_sign = radio_sign_elt.text 838 if radio_sid_elt: 839 self.radio_station_id = radio_sid_elt.text 840 if radio_band_elt: 841 self.radio_band = radio_band_elt.text 842 if channel_elt: 843 self.channel_nr = int(channel_elt.text)
844
845 846 -class AudioBook(AudioItem):
847 """ Discrete piece of audio that should be interpreted as a book. 848 """ 849 upnp_class = '%s%s' % (AudioItem.upnp_class, '.audioBook') 850
851 - def __init__(self, id='', parent_id='', title='', restricted=False, 852 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 853 genres=[], description='', long_description='', publishers=[], 854 language='', relations=[], rights=[], storage_medium='', 855 producers=[], contributors=[], date=''):
856 """ Constructor for the AudioBook class. 857 858 @param id: unique identifier for the object 859 @param parent_id: id of object's parent 860 @param title: name of the object 861 @param restricted: True if only CDS can modify the object 862 @param creator: content creator or owner 863 @param write_status: modifiability of the resources of this object. 864 Integer parameter based on WRITE_STATUS_* 865 constants 866 @param ref_id: id property of the item being referred to 867 @param genres: genres to which the object belongs 868 @param description: description 869 @param long_description: long description 870 @param publishers: entities responsible for making the resource 871 available 872 @param language: language of the resource 873 @param relations: related resources 874 @param rights: rights held in and over the resource 875 @param storage_medium: indicates the type of storage used for the 876 content. Possible values are enumerated on 877 STORAGE_MEDIUM_* variables 878 @param producers: names of the producers 879 @param contributors: entities responsible for making contributions to 880 the resource 881 @param date: ISO 8601, form YYYY-MM-DD 882 883 @type id: string 884 @type parent_id: string 885 @type title: string 886 @type restricted: bool 887 @type creator: string 888 @type write_status: integer 889 @type ref_id: string 890 @type genres: list 891 @type description: string 892 @type long_description: string 893 @type publishers: list 894 @type language: string 895 @type relations: list 896 @type rights: list 897 @type storage_medium: string 898 @type producers: list 899 @type contributors: list 900 @type date: string 901 """ 902 AudioItem.__init__(self, id, parent_id, title, restricted, creator, 903 write_status, ref_id, genres, description, 904 long_description, publishers, language, relations, 905 rights) 906 self.storage_medium = storage_medium 907 self.producer = producer 908 self.contributors = contributors 909 self.date = date
910
911 - def from_element(self, elt):
912 """ Sets AudioBook properties and attributes from an element. 913 """ 914 AudioItem.from_element(self, elt) 915 self.contributors = [c.text for c in findall(elt, 'dc', 'contributor')] 916 self.producers = [p.text for p in find(elt, 'upnp', 'producer')] 917 date_elt = find(elt, 'dc', 'date') 918 storage_elt = find(elt, 'upnp', 'storageMedium') 919 920 if storage_elt: 921 self.storage_medium = storage_elt.text 922 if date_elt: 923 self.date = date_elt.text
924
925 - def to_didl_element(self):
926 """ Create Element based on this AudioBook. 927 """ 928 root = AudioItem.to_didl_element(self) 929 930 for p in self.producer: 931 ElementTree.SubElement(root, 'upnp:producer').text = p 932 for c in self.contributors: 933 ElementTree.SubElement(root, 'dc:contributor').text = c 934 if self.date: 935 ElementTree.SubElement(root, 'dc:date').text = self.date 936 if self.storage_medium: 937 ElementTree.SubElement(root, 'upnp:storageMedium').text =\ 938 self.storage_medium 939 940 return root
941
942 943 -class VideoItem(Item):
944 """ A video representation. 945 """ 946 upnp_class = '%s%s' % (Item.upnp_class, '.videoItem') 947
948 - def __init__(self, id='', parent_id='', title='', restricted=False, 949 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 950 genres=[], long_description='', producers=[], rating='', 951 actors=[], directors=[], description='', publishers=[], 952 language='', relations=[]):
953 """ Constructor for the Item class. 954 955 @param id: unique identifier for the object 956 @param parent_id: id of object's parent 957 @param title: name of the object 958 @param restricted: True if only CDS can modify the object 959 @param creator: content creator or owner 960 @param write_status: modifiability of the resources of this object. 961 Integer parameter based on WRITE_STATUS_* 962 constants 963 @param ref_id: id property of the item being referred to 964 @param genres: list of genre titles that apply to this item 965 @param long_description: long description 966 @param producers: list of producers 967 @param rating: rating of the object's resource 968 @param actors: list of actors 969 @param directors: list of directors 970 @param description: short description 971 @param publishers: list of publisher names 972 @param language: main language of the video 973 @param relations: list of related resource names 974 975 @type id: string 976 @type parent_id: string 977 @type title: string 978 @type restricted: bool 979 @type creator: string 980 @type write_status: integer 981 @type ref_id: string 982 @type genres: list 983 @type long_description: string 984 @type producers: list 985 @type rating: string 986 @type actors: list 987 @type directors: list 988 @type description: string 989 @type publishers: list 990 @type language: string 991 @type relations: list 992 """ 993 Item.__init__(self, id, parent_id, title, restricted, creator, 994 write_status, ref_id) 995 self.genres = genres 996 self.long_description = long_description 997 self.producers = producers 998 self.rating = rating 999 self.actors = actors 1000 self.directors = directors 1001 self.description = description 1002 self.publishers = publishers 1003 self.language = language 1004 self.relations = relations
1005
1006 - def from_element(self, elt):
1007 """ Set VideoItem properties and attributes from an element. 1008 """ 1009 Item.from_element(self, elt) 1010 long_desc_elt = find(elt, 'upnp', 'longDescription') 1011 rating_elt = find(elt, 'upnp', 'rating') 1012 description_elt = find(elt, 'dc', 'description') 1013 language_elt = find(elt, 'dc', 'language') 1014 1015 self.genres = [g.text for g in find(elt, 'upnp', 'genre')] 1016 self.producers = [p.text for p in find(elt, 'upnp', 'producer')] 1017 self.actors = [a.text for a in find(elt, 'upnp', 'actor')] 1018 self.directors = [d.text for d in find(elt, 'upnp', 'director')] 1019 self.publishers = [p.text for p in findall(elt, 'dc', 'publisher')] 1020 self.relations = [r.text for r in findall(elt, 'dc', 'relation')] 1021 1022 if long_desc_elt: 1023 self.long_description = long_desc_elt.text 1024 if rating_elt: 1025 self.rating = rating_elt.text 1026 if description_elt: 1027 self.description = description_elt.text 1028 if language_elt: 1029 self.language = language_elt.text
1030
1031 - def to_didl_element(self):
1032 """ Create Element based on this VideoItem. 1033 """ 1034 root = Item.to_didl_element(self) 1035 1036 if self.long_description: 1037 ElementTree.SubElement(root, 'upnp:longDescription').text =\ 1038 self.long_description 1039 if self.rating: 1040 ElementTree.SubElement(root, 'upnp:rating').text = self.rating 1041 1042 for g in self.genres: 1043 ElementTree.SubElement(root, 'upnp:genre').text = g 1044 for p in self.producers: 1045 ElementTree.SubElement(root, 'upnp:producer').text = p 1046 for a in self.actors: 1047 ElementTree.SubElement(root, 'upnp:actor').text = a 1048 for d in self.directors: 1049 ElementTree.SubElement(root, 'upnp:director').text = d 1050 for p in self.producers: 1051 ElementTree.SubElement(root, 'dc:producer').text = p 1052 for r in self.relations: 1053 ElementTree.SubElement(root, 'dc:relation').text = r 1054 1055 if self.description: 1056 ElementTree.SubElement(root, 'dc:description').text =\ 1057 self.description 1058 if self.language: 1059 ElementTree.SubElement(root, 'dc:language').text = self.language 1060 1061 return root
1062
1063 1064 -class Movie(VideoItem):
1065 """ A movie representation. 1066 """ 1067 upnp_class = '%s%s' % (VideoItem.upnp_class, '.movie') 1068
1069 - def __init__(self, id='', parent_id='', title='', restricted=False, 1070 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 1071 genres=[], long_description='', producers=[], rating='', 1072 actors=[], directors=[], description='', publishers=[], 1073 language='', relations=[], storage_medium='', 1074 dvd_region_code='', channel_name='', 1075 scheduled_start_time='', scheduled_end_time=''):
1076 """ Constructor for the Movie class. 1077 1078 @param id: unique identifier for the object 1079 @param parent_id: id of object's parent 1080 @param title: name of the object 1081 @param restricted: True if only CDS can modify the object 1082 @param creator: content creator or owner 1083 @param write_status: modifiability of the resources of this object. 1084 Integer parameter based on WRITE_STATUS_* 1085 constants 1086 @param ref_id: id property of the item being referred to 1087 @param genres: list of genre titles that apply to this item 1088 @param long_description: long description 1089 @param producers: list of producers 1090 @param rating: rating of the object's resource 1091 @param actors: list of actors 1092 @param directors: list of directors 1093 @param description: short description 1094 @param publishers: list of publisher names 1095 @param language: main language of the video 1096 @param relations: list of related resource names 1097 @param storage_medium: indicates the type of storage used for the 1098 content. Possible values are enumerated on 1099 STORAGE_MEDIUM_* variables 1100 @param dvd_region_code: region code of the DVD disc 1101 @param channel_name: identification of channel 1102 @param scheduled_start_time: start time of a schedule program, 1103 ISO 8601, form yyyy-mm-ddThh:mm:ss 1104 @param scheduled_end_time: end time of a schedule program, ISO 8601, 1105 form yyyy-mm-ddThh:mm:ss 1106 1107 @type id: string 1108 @type parent_id: string 1109 @type title: string 1110 @type restricted: bool 1111 @type creator: string 1112 @type write_status: integer 1113 @type ref_id: string 1114 @type genres: list 1115 @type long_description: string 1116 @type producers: list 1117 @type rating: string 1118 @type actors: list 1119 @type directors: list 1120 @type description: string 1121 @type publishers: list 1122 @type language: string 1123 @type relations: list 1124 @type storage_medium: string 1125 @type dvd_region_code: string 1126 @type channel_name: string 1127 @type scheduled_start_time: string 1128 @type scheduled_end_time: string 1129 """ 1130 VideoItem.__init__(self, id, parent_id, title, restricted, creator, 1131 write_status, ref_id, genres, long_description, 1132 producers, rating, actors, directors, description, 1133 publishers, language, relations) 1134 self.storage_medium = storage_medium 1135 self.dvd_region_code = dvd_region_code 1136 self.channel_name = channel_name 1137 self.scheduled_start_time = scheduled_start_time 1138 self.scheduled_end_time = scheduled_end_time
1139
1140 - def from_element(self, elt):
1141 """ Sets Movie properties and attributes from an element. 1142 """ 1143 VideoItem.from_element(self, elt) 1144 storage_elt = find(elt, 'upnp', 'storageMedium') 1145 dvd_region_elt = find(elt, 'upnp', 'DVDRegionCode') 1146 channel_name_elt = find(elt, 'upnp', 'channelName') 1147 sched_start_elt = find(elt, 'upnp', 'scheduledStartTime') 1148 sched_end_elt = find(elt, 'upnp', 'scheduledEndTime') 1149 1150 if storage_elt: 1151 self.storage_medium = storage_elt.text 1152 if dvd_region_elt: 1153 self.dvd_region_code = dvd_region_elt.text 1154 if channel_name_elt: 1155 self.channel_name = channel_name_elt.text 1156 if sched_start_elt: 1157 self.scheduled_start_time = sched_start_elt.text 1158 if sched_end_elt: 1159 self.scheduled_end_time = sched_end_elt.text
1160
1161 - def to_didl_element(self):
1162 """ Create Element from this Movie. 1163 """ 1164 root = VideoItem.to_didl_element(self) 1165 1166 if self.storage_medium: 1167 ElementTree.SubElement(root, 'upnp:storageMedium').text =\ 1168 self.storage_medium 1169 if self.dvd_region_code: 1170 ElementTree.SubElement(root, 'upnp:DVDRegionCode').text = \ 1171 self.dvd_region_code 1172 if self.channel_name: 1173 ElementTree.SubElement(root, 'upnp:channelName').text = \ 1174 self.channelName 1175 if self.scheduled_start_time: 1176 ElementTree.SubElement(root, 'upnp:scheduledStartTime').text = \ 1177 self.scheduled_start_time 1178 if self.scheduled_end_time: 1179 ElementTree.SubElement(root, 'upnp:scheduledEndTime').text = \ 1180 self.scheduled_end_time 1181 1182 return root
1183
1184 1185 -class VideoBroadcast(VideoItem):
1186 """ A continuous stream of video representation. 1187 """ 1188 upnp_class = '%s%s' % (VideoItem.upnp_class, '.videoBroadcast') 1189
1190 - def __init__(self, id='', parent_id='', title='', restricted=False, 1191 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 1192 genres=[], long_description='', producers=[], rating='', 1193 actors=[], directors=[], description='', publishers=[], 1194 language='', relations=[], icon='', region='', channel_nr=''):
1195 """ Constructor for the VideoBroadcast class. 1196 1197 @param id: unique identifier for the object 1198 @param parent_id: id of object's parent 1199 @param title: name of the object 1200 @param restricted: True if only CDS can modify the object 1201 @param creator: content creator or owner 1202 @param write_status: modifiability of the resources of this object. 1203 Integer parameter based on WRITE_STATUS_* 1204 constants 1205 @param ref_id: id property of the item being referred to 1206 @param genres: list of genre titles that apply to this item 1207 @param long_description: long description 1208 @param producers: list of producers 1209 @param rating: rating of the object's resource 1210 @param actors: list of actors 1211 @param directors: list of directors 1212 @param description: short description 1213 @param publishers: list of publisher names 1214 @param language: main language of the video 1215 @param relations: list of related resource names 1216 @param icon: uri of the icon 1217 @param region: identification of the region (source) 1218 @param channel_nr: channel number 1219 1220 @type id: string 1221 @type parent_id: string 1222 @type title: string 1223 @type restricted: bool 1224 @type creator: string 1225 @type write_status: integer 1226 @type ref_id: string 1227 @type genres: list 1228 @type long_description: string 1229 @type producers: list 1230 @type rating: string 1231 @type actors: list 1232 @type directors: list 1233 @type description: string 1234 @type publishers: list 1235 @type language: string 1236 @type relations: list 1237 @type icon: string 1238 @type region: string 1239 @type channel_nr: int 1240 """ 1241 VideoItem.__init__(self, id, parent_id, title, restricted, creator, 1242 write_status, ref_id, genres, long_description, 1243 producers, rating, actors, directors, description, 1244 publishers, language, relations) 1245 self.icon = icon 1246 self.region = region 1247 self.channel_nr = channel_nr
1248
1249 - def from_element(self, elt):
1250 """ Sets VideoBroadcast properties and attributes from an element. 1251 """ 1252 VideoItem.from_element(self, elt) 1253 icon_elt = find(elt, 'upnp', 'icon') 1254 region_elt = find(elt, 'upnp', 'region') 1255 channel_nr_elt = find(elt, 'upnp', 'channelNr') 1256 1257 if icon_elt: 1258 self.icon = icon_elt.text 1259 if region_elt: 1260 self.region = region_elt.text 1261 if channel_nr_elt: 1262 self.channel_nr = channel_nr_elt.text
1263
1264 - def to_didl_element(self):
1265 """ Create Element from this VideoBroadcast. 1266 """ 1267 root = VideoItem.to_didl_element(self) 1268 1269 if self.icon: 1270 ElementTree.SubElement(root, 'upnp:icon').text = self.icon 1271 if self.region: 1272 ElementTree.SubElement(root, 'upnp:region').text = self.region 1273 if self.channel_nr: 1274 ElementTree.SubElement(root, 'upnp:channelNr').text = \ 1275 self.channel_nr 1276 1277 return root
1278
1279 1280 -class MusicVideoClip(VideoItem):
1281 """ A music video clip representation. 1282 """ 1283 upnp_class = '%s%s' % (VideoItem.upnp_class, '.musicVideoClip') 1284
1285 - def __init__(self, id='', parent_id='', title='', restricted=False, 1286 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 1287 genres=[], long_description='', producers=[], rating='', 1288 actors=[], directors=[], description='', publishers=[], 1289 language='', relations=[], artists=[], storage_medium='', 1290 albums=[], scheduled_start_time='', scheduled_end_time='', 1291 contributors=[], date=''):
1292 """ Constructor for the VideoItem class. 1293 1294 @param id: unique identifier for the object 1295 @param parent_id: id of object's parent 1296 @param title: name of the object 1297 @param restricted: True if only CDS can modify the object 1298 @param creator: content creator or owner 1299 @param write_status: modifiability of the resources of this object. 1300 Integer parameter based on WRITE_STATUS_* 1301 constants 1302 @param ref_id: id property of the item being referred to 1303 @param genres: list of genre titles that apply to this item 1304 @param long_description: long description 1305 @param producers: list of producers 1306 @param rating: rating of the object's resource 1307 @param actors: list of actors 1308 @param directors: list of directors 1309 @param description: short description 1310 @param publishers: list of publisher names 1311 @param language: main language of the video 1312 @param relations: list of related resource names 1313 @param artists: list of artists 1314 @param storage_medium: indicates the type of storage used for the 1315 content. Possible values are enumerated on 1316 STORAGE_MEDIUM_* variables 1317 @param albums: list of albums that this resource belongs to 1318 @param scheduled_start_time: start time of a schedule program, 1319 ISO 8601, form yyyy-mm-ddThh:mm:ss 1320 @param scheduled_end_time: end time of a schedule program, ISO 8601, 1321 form yyyy-mm-ddThh:mm:ss 1322 @param contributors: entities responsible for making contributions to 1323 the resource 1324 @param date: ISO 8601, form YYYY-MM-DD 1325 1326 @type id: string 1327 @type parent_id: string 1328 @type title: string 1329 @type restricted: bool 1330 @type creator: string 1331 @type write_status: integer 1332 @type ref_id: string 1333 @type genres: list 1334 @type long_description: string 1335 @type producers: list 1336 @type rating: string 1337 @type actors: list 1338 @type directors: list 1339 @type description: string 1340 @type publishers: list 1341 @type language: string 1342 @type relations: list 1343 @type artists: list 1344 @type storage_medium: string 1345 @type albums: list 1346 @type scheduled_start_time: string 1347 @type scheduled_end_time: string 1348 @type contributors: list 1349 @type date: string 1350 """ 1351 VideoItem.__init__(self, id, parent_id, title, restricted, creator, 1352 write_status, ref_id, genres, long_description, 1353 producers, rating, actors, directors, description, 1354 publishers, language, relations) 1355 self.artists = artists 1356 self.storage_medium = storage_medium 1357 self.albums = albums 1358 self.scheduled_start_time = scheduled_start_time 1359 self.scheduled_end_time = scheduled_end_time 1360 self.contributors = contributors 1361 self.date = date
1362
1363 - def from_element(self, elt):
1364 """ Sets MusicVideoClip properties and attributes from an element. 1365 """ 1366 VideoItem.from_element(self, elt) 1367 storage_elt = find(elt, 'upnp', 'storageMedium') 1368 sched_start_elt = find(elt, 'upnp', 'scheduledStartTime') 1369 sched_end_elt = find(elt, 'upnp', 'scheduledEndTime') 1370 date_elt = find(elt, 'dc', 'date') 1371 1372 self.artists = [a.text for a in find(elt, 'upnp', 'artist')] 1373 self.albums = [a.text for a in find(elt, 'upnp', 'album')] 1374 self.contributors = [c.text for c in findall(elt, 'dc', 'contributor')] 1375 1376 if storage_elt: 1377 self.storage_medium = storage_elt.text 1378 if sched_start_elt: 1379 self.scheduled_start_time = sched_start_elt.text 1380 if sched_end_elt: 1381 self.scheduled_end_time = sched_end_elt.text 1382 if date_elt: 1383 self.date = date_elt.text
1384
1385 - def to_didl_element(self):
1386 """ Create Element from this MusicVideoClip. 1387 """ 1388 root = VideoItem.to_didl_element(self) 1389 1390 for a in self.artists: 1391 ElementTree.SubElement(root, 'upnp:artist').text = a 1392 for a in self.albums: 1393 ElementTree.SubElement(root, 'upnp:album').text = a 1394 for c in self.contributors: 1395 ElementTree.SubElement(root, 'dc:contributor').text = c 1396 1397 if self.storage_medium: 1398 ElementTree.SubElement(root, 'upnp:storageMedium').text =\ 1399 self.storage_medium 1400 if self.scheduled_start_time: 1401 ElementTree.SubElement(root, 'upnp:scheduledStartTime').text = \ 1402 self.scheduled_start_time 1403 if self.scheduled_end_time: 1404 ElementTree.SubElement(root, 'upnp:scheduledEndTime').text = \ 1405 self.scheduled_end_time 1406 if self.date: 1407 ElementTree.SubElement(root, 'dc:date').text = self.date 1408 1409 return root
1410
1411 1412 -class ImageItem(Item):
1413 """ An image representation. Content that when rendered generates some 1414 image. 1415 """ 1416 upnp_class = '%s%s' % (Item.upnp_class, '.imageItem') 1417
1418 - def __init__(self, id='', parent_id='', title='', restricted=False, 1419 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 1420 long_description='', storage_medium='', rating='', 1421 description='', publishers=[], date='', rights=[]):
1422 """ Constructor for the ImageItem class. 1423 1424 @param id: unique identifier for the object 1425 @param parent_id: id of object's parent 1426 @param title: name of the object 1427 @param restricted: True if only CDS can modify the object 1428 @param creator: content creator or owner 1429 @param write_status: modifiability of the resources of this object. 1430 Integer parameter based on WRITE_STATUS_* 1431 constants 1432 @param ref_id: id property of the item being referred to 1433 @param long_description: long description 1434 @param storage_medium: indicates the type of storage used for the 1435 content. Possible values are enumerated on 1436 STORAGE_MEDIUM_* variables 1437 @param rating: rating of the object's resource 1438 @param description: description 1439 @param publishers: entities responsible for making the resource 1440 available 1441 @param date: ISO 8601, form YYYY-MM-DD 1442 @param rights: rights held in and over the resource 1443 1444 @type id: string 1445 @type parent_id: string 1446 @type title: string 1447 @type restricted: bool 1448 @type creator: string 1449 @type write_status: integer 1450 @type ref_id: string 1451 @type long_description: string 1452 @type storage_medium: string 1453 @type rating: string 1454 @type description: string 1455 @type publishers: list 1456 @type date: string 1457 @type rights: list 1458 """ 1459 Item.__init__(self, id, parent_id, title, restricted, creator, 1460 write_status, ref_id) 1461 self.long_description = long_description 1462 self.storage_medium = storage_medium 1463 self.rating = rating 1464 self.description = description 1465 self.date = date 1466 self.rights = rights
1467
1468 - def from_element(self, elt):
1469 """ Sets the resource properties from an element. 1470 """ 1471 Item.from_element(self, elt) 1472 long_desc_elt = find(elt, 'upnp', 'longDescription') 1473 storage_elt = find(elt, 'upnp', 'storageMedium') 1474 rating_elt = find(elt, 'upnp', 'rating') 1475 description_elt = find(elt, 'dc', 'description') 1476 date_elt = find(elt, 'dc', 'date') 1477 self.rights = [r.text for r in findall(elt, 'dc', 'rights')] 1478 1479 if long_desc_elt: 1480 self.long_description = long_desc_elt.text 1481 if storage_elt: 1482 self.storage_medium = storage_elt.text 1483 if rating_elt: 1484 self.rating = rating_elt.text 1485 if description_elt: 1486 self.description = description_elt.text 1487 if date_elt: 1488 self.date = date_elt.text
1489
1490 - def to_didl_element(self):
1491 """ Returns an Element based on this Resource. 1492 """ 1493 root = Item.to_didl_element(self) 1494 1495 if self.long_description: 1496 ElementTree.SubElement(root, 'upnp:longDescription').text =\ 1497 self.long_description 1498 if self.storage_medium: 1499 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 1500 self.storage_medium 1501 if self.rating: 1502 ElementTree.SubElement(root, 'upnp:rating').text = self.rating 1503 if self.description: 1504 ElementTree.SubElement(root, 'dc:description').text =\ 1505 self.description 1506 if self.date: 1507 ElementTree.SubElement(root, 'dc:date').text = self.date 1508 for r in self.rights: 1509 ElementTree.SubElement(root, 'dc:rights').text = r 1510 1511 return root
1512
1513 1514 -class Photo(ImageItem):
1515 """ A photo representation. 1516 """ 1517 upnp_class = '%s%s' % (ImageItem.upnp_class, '.photo') 1518
1519 - def __init__(self, id='', parent_id='', title='', restricted=False, 1520 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 1521 long_description='', storage_medium='', rating='', 1522 description='', publishers=[], date='', rights=[], albums=[]):
1523 """ Constructor for the Photo class. 1524 1525 @param id: unique identifier for the object 1526 @param parent_id: id of object's parent 1527 @param title: name of the object 1528 @param restricted: True if only CDS can modify the object 1529 @param creator: content creator or owner 1530 @param write_status: modifiability of the resources of this object. 1531 Integer parameter based on WRITE_STATUS_* 1532 constants 1533 @param ref_id: id property of the item being referred to 1534 @param long_description: long description 1535 @param storage_medium: indicates the type of storage used for the 1536 content. Possible values are enumerated on 1537 STORAGE_MEDIUM_* variables 1538 @param rating: rating of the object's resource 1539 @param description: description 1540 @param publishers: entities responsible for making the resource 1541 available 1542 @param date: ISO 8601, form YYYY-MM-DD 1543 @param rights: rights held in and over the resource 1544 @param albums: albums to which the photo belongs 1545 1546 @type id: string 1547 @type parent_id: string 1548 @type title: string 1549 @type restricted: bool 1550 @type creator: string 1551 @type write_status: integer 1552 @type ref_id: string 1553 @type long_description: string 1554 @type storage_medium: string 1555 @type rating: string 1556 @type description: string 1557 @type publishers: list 1558 @type date: string 1559 @type rights: list 1560 @type albums: list 1561 """ 1562 ImageItem.__init__(self, id, parent_id, title, restricted, creator, 1563 write_status, ref_id, long_description, 1564 storage_medium, rating, description, publishers, 1565 date, rights) 1566 self.albums = albums
1567
1568 - def from_element(self, elt):
1569 """ Sets the resource properties from an element. 1570 """ 1571 ImageItem.from_element(self, elt) 1572 self.albums = [a.text for a in find(elt, 'upnp', 'album')]
1573
1574 - def to_didl_element(self):
1575 """ Returns an Element based on this Resource. 1576 """ 1577 root = ImageItem.to_didl_element(self) 1578 1579 for a in self.albums: 1580 ElementTree.SubElement(root, 'upnp:album').text = a 1581 1582 return root
1583
1584 1585 -class PlaylistItem(Item):
1586 """ Represents a playable sequence of resources (audio, video, image). Must 1587 have a resource element added for playback of the whole sequence. 1588 """ 1589 upnp_class = '%s%s' % (Item.upnp_class, '.playlistItem') 1590
1591 - def __init__(self, id='', parent_id='', title='', restricted=False, 1592 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, ref_id='', 1593 authors=[], protection='', long_description='', 1594 storage_medium='', rating='', description='', publishers=[], 1595 contributors=[], date='', relations=[], languages=[], 1596 rights=[]):
1597 """ Constructor for the PlaylistItem class. 1598 1599 @param id: unique identifier for the object 1600 @param parent_id: id of object's parent 1601 @param title: name of the object 1602 @param restricted: True if only CDS can modify the object 1603 @param creator: content creator or owner 1604 @param write_status: modifiability of the resources of this object. 1605 Integer parameter based on WRITE_STATUS_* 1606 constants 1607 @param ref_id: id property of the item being referred to 1608 @param authors: list of author names 1609 @param protection: protection 1610 @param long_description: long description 1611 @param storage_medium: indicates the type of storage used for the 1612 content. Possible values are enumerated on 1613 STORAGE_MEDIUM_* variables 1614 @param rating: rating of the object's resource 1615 @param description: description 1616 @param publishers: list of publisher names 1617 @param contributors: entities responsible for making contributions to 1618 the resource 1619 @param date: ISO 8601, form YYYY-MM-DD 1620 @param relations: list of relation (related resources names) 1621 @param languages: list of languages used 1622 @param rights: list of rights 1623 1624 @type id: string 1625 @type parent_id: string 1626 @type title: string 1627 @type restricted: bool 1628 @type creator: string 1629 @type write_status: integer 1630 @type ref_id: string 1631 @type authors: list 1632 @type protection: string 1633 @type long_description: string 1634 @type storage_medium: string 1635 @type rating: string 1636 @type description: string 1637 @type publishers: list 1638 @type contributors: list 1639 @type date: string 1640 @type relations: list 1641 @type languages: list 1642 @type rights: list 1643 """ 1644 Item.__init__(self, id, parent_id, title, restricted, creator, 1645 write_status, ref_id) 1646 self.authors = authors 1647 self.protection = protection 1648 self.long_description = long_description 1649 self.storage_medium = storage_medium 1650 self.rating = rating 1651 self.description = description 1652 self.publishers = publishers 1653 self.contributors = contributors 1654 self.date = date 1655 self.relations = relations 1656 self.languages = languages 1657 self.rights = rights
1658
1659 - def from_element(self, elt):
1660 """ Sets the resource properties from an element. 1661 """ 1662 Item.from_element(self, elt) 1663 protection_elt = find(elt, 'upnp', 'protection') 1664 long_desc_elt = find(elt, 'upnp', 'longDescription') 1665 storage_elt = find(elt, 'upnp', 'storageMedium') 1666 rating_elt = find(elt, 'upnp', 'rating') 1667 description_elt = find(elt, 'dc', 'description') 1668 date_elt = find(elt, 'dc', 'date') 1669 1670 self.authors = [a.text for a in find(elt, 'upnp', 'author')] 1671 self.publishers = [p.text for p in findall(elt, 'dc', 'publisher')] 1672 self.contributors = [c.text for c in findall(elt, 'dc', 'contributor')] 1673 self.relations = [r.text for r in findall(elt, 'dc', 'relation')] 1674 self.languages = [l.text for l in findall(elt, 'dc', 'language')] 1675 self.rights = [r.text for r in findall(elt, 'dc', 'rights')] 1676 1677 if protection_elt: 1678 self.protection = protection_elt.text 1679 if long_desc_elt: 1680 self.long_description = long_desc_elt.text 1681 if storage_elt: 1682 self.storage_medium = storage_elt.text 1683 if rating_elt: 1684 self.rating = rating_elt.text 1685 if description_elt: 1686 self.description = description_elt.text 1687 if date_elt: 1688 self.date = date_elt.text
1689
1690 - def to_didl_element(self):
1691 """ Returns an Element based on this Resource. 1692 """ 1693 root = Item.to_didl_element(self) 1694 1695 if self.protection: 1696 ElementTree.SubElement(root, 'upnp:protection').text = \ 1697 self.protection 1698 if self.storage_medium: 1699 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 1700 self.storage_medium 1701 if self.long_description: 1702 ElementTree.SubElement(root, 'upnp:longDescription').text = \ 1703 self.long_description 1704 if self.rating: 1705 ElementTree.SubElement(root, 'upnp:rating').text = self.rating 1706 if self.description: 1707 ElementTree.SubElement(root, 'dc:description').text = \ 1708 self.description 1709 if self.date: 1710 ElementTree.SubElement(root, 'dc:date').text = self.date 1711 1712 for a in self.authors: 1713 ElementTree.SubElement(root, 'upnp:author').text = a 1714 for p in self.publishers: 1715 ElementTree.SubElement(root, 'dc:publisher').text = p 1716 for c in self.contributors: 1717 ElementTree.SubElement(root, 'dc:contributor').text = c 1718 for r in self.relations: 1719 ElementTree.SubElement(root, 'dc:relation').text = r 1720 for l in self.languages: 1721 ElementTree.SubElement(root, 'dc:language').text = l 1722 for r in self.rights: 1723 ElementTree.SubElement(root, 'dc:rights').text = r 1724 1725 return root
1726
1727 1728 -class Album(Container):
1729 """ Ordered collection of objects. Rendering the album has the semantics of 1730 rendering each object in sequence. 1731 """ 1732 upnp_class = '%s%s' % (Container.upnp_class, '.album') 1733
1734 - def __init__(self, id='', parent_id='', title='', restricted=False, 1735 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 1736 searchable=True, search_classes=[], create_classes=[], 1737 storage_medium='', long_description='', description='', 1738 publishers=[], contributors=[], date='', relations=[], 1739 rights=[]):
1740 """ Constructor for the Album class. 1741 1742 @param id: unique identifier for the object 1743 @param parent_id: id of object's parent 1744 @param title: name of the object 1745 @param restricted: True if only CDS can modify the object 1746 @param creator: content creator or owner 1747 @param write_status: modifiability of the resources of this object. 1748 Integer parameter based on WRITE_STATUS_* 1749 constants 1750 @param searchable: if True, Search action can be performed upon the 1751 container 1752 @param search_classes: list of SearchClass objects 1753 @param create_classes: list of CreateClass objects 1754 @param storage_medium: indicates the type of storage used for the 1755 content. Possible values are enumerated on 1756 STORAGE_MEDIUM_* variables 1757 @param long_description: long description 1758 @param description: description 1759 @param publishers: list of publishers names 1760 @param contributors: entities responsible for making contributions to 1761 the resource 1762 @param date: ISO 8601, form YYYY-MM-DD 1763 @param relations: list of related resource names 1764 @param rights: rights held in and over the resource 1765 1766 @type id: string 1767 @type parent_id: string 1768 @type title: string 1769 @type restricted: bool 1770 @type creator: string 1771 @type write_status: integer 1772 @type searchable: bool 1773 @type search_classes: list 1774 @type create_classes: list 1775 @type storage_medium: string 1776 @type long_description: string 1777 @type description: string 1778 @type publishers: list 1779 @type contributors: list 1780 @type date: string 1781 @type relations: list 1782 @type rights: list 1783 """ 1784 Container.__init__(self, id, parent_id, title, restricted, creator, 1785 write_status, searchable, search_classes, 1786 create_classes) 1787 self.storage_medium = storage_medium 1788 self.long_description = long_description 1789 self.description = description 1790 self.publishers = publishers 1791 self.contributors = contributors 1792 self.date = date 1793 self.relations = relations 1794 self.rights = rights
1795
1796 - def from_element(self, elt):
1797 """ Sets the resource properties from an element. 1798 """ 1799 Container.from_element(self, elt) 1800 storage_elt = find(elt, 'upnp', 'storageMedium') 1801 long_desc_elt = find(elt, 'upnp', 'longDescription') 1802 description_elt = find(elt, 'dc', 'description') 1803 date_elt = find(elt, 'dc', 'date') 1804 1805 self.publishers = [p.text for p in findall(elt, 'dc', 'publisher')] 1806 self.contributors = [c.text for c in findall(elt, 'dc', 'contributor')] 1807 self.relations = [r.text for r in findall(elt, 'dc', 'relation')] 1808 self.rights = [r.text for r in findall(elt, 'dc', 'rights')] 1809 1810 if storage_elt: 1811 self.storage_medium = storage_elt.text 1812 if long_desc_elt: 1813 self.long_description = long_desc_elt.text 1814 if description_elt: 1815 self.description = description_elt.text 1816 if date_elt: 1817 self.date = date_elt.text
1818
1819 - def to_didl_element(self):
1820 """ Returns an Element based on this Resource. 1821 """ 1822 root = Container.to_didl_element(self) 1823 1824 if self.storage_medium: 1825 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 1826 self.storage_medium 1827 if self.long_description: 1828 ElementTree.SubElement(root, 'upnp:longDescription').text = \ 1829 self.long_description 1830 if self.description: 1831 ElementTree.SubElement(root, 'dc:description').text = \ 1832 self.description 1833 if self.date: 1834 ElementTree.SubElement(root, 'dc:date').text = self.date 1835 1836 for p in self.publishers: 1837 ElementTree.SubElement(root, 'dc:publisher').text = p 1838 for c in self.contributors: 1839 ElementTree.SubElement(root, 'dc:contributor').text = c 1840 for r in self.relations: 1841 ElementTree.SubElement(root, 'dc:relation').text = r 1842 for r in self.rights: 1843 ElementTree.SubElement(root, 'dc:rights').text = r 1844 1845 return root
1846
1847 1848 -class MusicAlbum(Album):
1849 """ A music album representation. 1850 """ 1851 upnp_class = '%s%s' % (Album.upnp_class, '.musicAlbum') 1852
1853 - def __init__(self, id='', parent_id='', title='', restricted=False, 1854 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 1855 searchable=True, search_classes=[], create_classes=[], 1856 storage_medium='', long_description='', description='', 1857 publishers=[], contributors=[], date='', relations=[], 1858 rights=[], artists=[], genres=[], producers=[], 1859 album_art_uri=[], toc=''):
1860 """ Constructor for the MusicAlbum class. 1861 1862 @param id: unique identifier for the object 1863 @param parent_id: id of object's parent 1864 @param title: name of the object 1865 @param restricted: True if only CDS can modify the object 1866 @param creator: content creator or owner 1867 @param write_status: modifiability of the resources of this object. 1868 Integer parameter based on WRITE_STATUS_* 1869 constants 1870 @param searchable: if True, Search action can be performed upon the 1871 container 1872 @param search_classes: list of SearchClass objects 1873 @param create_classes: list of CreateClass objects 1874 @param storage_medium: indicates the type of storage used for the 1875 content. Possible values are enumerated on 1876 STORAGE_MEDIUM_* variables 1877 @param long_description: long description 1878 @param description: description 1879 @param publishers: list of publishers names 1880 @param contributors: entities responsible for making contributions to 1881 the resource 1882 @param date: ISO 8601, form YYYY-MM-DD 1883 @param relations: list of related resource names 1884 @param rights: rights held in and over the resource 1885 @param artists: list of artists names 1886 @param genres: list of genres that apply to this album 1887 @param producers: list of producers 1888 @param album_art_uri: reference to the album art 1889 @param toc: identifier for an audio CD 1890 1891 @type id: string 1892 @type parent_id: string 1893 @type title: string 1894 @type restricted: bool 1895 @type creator: string 1896 @type write_status: integer 1897 @type searchable: bool 1898 @type search_classes: list 1899 @type create_classes: list 1900 @type storage_medium: string 1901 @type long_description: string 1902 @type description: string 1903 @type publishers: list 1904 @type contributors: list 1905 @type date: string 1906 @type relations: list 1907 @type rights: list 1908 @type artists: list 1909 @type genres: list 1910 @type producers: list 1911 @type album_art_uri: string 1912 @type toc: string 1913 """ 1914 Album.__init__(self, id, parent_id, title, restricted, creator, 1915 write_status, searchable, search_classes, 1916 create_classes, storage_medium, long_description, 1917 description, publishers, contributors, date, relations, 1918 rights) 1919 self.artists = artists 1920 self.genres = genres 1921 self.producers = producers 1922 self.album_art_uri = album_art_uri 1923 self.toc = toc
1924
1925 - def from_element(self, elt):
1926 """ Sets the resource properties from an element. 1927 """ 1928 Album.from_element(self, elt) 1929 album_art_uri_elt = find(elt, 'upnp', 'albumArtURI') 1930 toc_elt = find(elt, 'upnp', 'toc') 1931 1932 self.artists = [a.text for a in find(elt, 'upnp', 'artist')] 1933 self.genres = [g.text for g in find(elt, 'upnp', 'genre')] 1934 self.producers = [p.text for p in findall(elt, 'upnp', 'producer')] 1935 1936 if album_art_uri_elt: 1937 self.album_art_uri = album_art_uri_elt.text 1938 if toc_elt: 1939 self.toc = toc_elt.text
1940
1941 - def to_didl_element(self):
1942 """ Returns an Element based on this Resource. 1943 """ 1944 root = Album.to_didl_element(self) 1945 1946 for a in self.artists: 1947 ElementTree.SubElement(root, 'upnp:artist').text = a 1948 for g in self.genres: 1949 ElementTree.SubElement(root, 'upnp:genre').text = g 1950 for p in self.producers: 1951 ElementTree.SubElement(root, 'upnp:producer').text = p 1952 if self.album_art_uri: 1953 ElementTree.SubElement(root, 'upnp:albumArtURI').text = \ 1954 self.album_art_uri 1955 if self.toc: 1956 ElementTree.SubElement(root, 'upnp:toc').text = self.toc 1957 1958 return root
1959
1960 1961 -class PhotoAlbum(Album):
1962 """ A photo album representation. 1963 """ 1964 upnp_class = '%s%s' % (Album.upnp_class, '.photoAlbum') 1965
1966 - def add_container(self, c):
1967 if isinstance(c, PhotoAlbum): 1968 Album.add_container(self, c) 1969 return True 1970 return False
1971
1972 - def add_item(self, item):
1973 if isinstance(item, Photo): 1974 Album.add_item(self, item) 1975 return True 1976 return False
1977
1978 1979 -class Genre(Container):
1980 """ A container with a name denoting a genre. 1981 """ 1982 upnp_class = '%s%s' % (Container.upnp_class, '.genre') 1983
1984 - def __init__(self, id='', parent_id='', title='', restricted=False, 1985 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 1986 searchable=True, search_classes=[], create_classes=[], 1987 long_description='', description=''):
1988 """ Constructor for the Container class. 1989 1990 @param id: unique identifier for the object 1991 @param parent_id: id of object's parent 1992 @param title: name of the object 1993 @param restricted: True if only CDS can modify the object 1994 @param creator: content creator or owner 1995 @param write_status: modifiability of the resources of this object. 1996 Integer parameter based on WRITE_STATUS_* 1997 constants 1998 @param searchable: if True, Search action can be performed upon the 1999 container 2000 @param search_classes: list of SearchClass objects 2001 @param create_classes: list of CreateClass objects 2002 2003 @type id: string 2004 @type parent_id: string 2005 @type title: string 2006 @type restricted: bool 2007 @type creator: string 2008 @type write_status: integer 2009 @type searchable: bool 2010 @type search_classes: list 2011 @type create_classes: list 2012 """ 2013 Container.__init__(self, id, parent_id, title, restricted, creator, 2014 write_status, searchable, search_classes, 2015 create_classes) 2016 self.long_description = long_description 2017 self.description = description
2018
2019 - def from_element(self, elt):
2020 """ Sets the resource properties from an element. 2021 """ 2022 Container.from_element(self, elt) 2023 long_desc_elt = find(elt, 'upnp', 'longDescription') 2024 desc_elt = find(elt, 'dc', 'description') 2025 2026 if long_desc_elt: 2027 self.long_description = long_desc_elt.text 2028 if desc_elt: 2029 self.description = desc_elt.text
2030
2031 - def to_didl_element(self):
2032 """ Returns an Element based on this Resource. 2033 """ 2034 root = Container.to_didl_element(self) 2035 2036 if self.long_description: 2037 ElementTree.SubElement(root, 'upnp:longDescription').text = \ 2038 self.long_description 2039 if self.description: 2040 ElementTree.SubElement(root, 'dc:description').text = \ 2041 self.description 2042 2043 return root
2044
2045 2046 -class MusicGenre(Genre):
2047 """ Style of music. Can contain objects of class MusicArtist, MusicAlbum, 2048 AudioItem, MusicGenre. 2049 """ 2050 upnp_class = '%s%s' % (Genre.upnp_class, '.musicGenre') 2051
2052 - def add_container(self, c):
2053 if isinstance(c, MusicArtist) or ininstance(c, MusicAlbum) or\ 2054 isinstance(c, self.__class__): 2055 Genre.add_container(self, c) 2056 return True 2057 return False
2058
2059 - def add_item(self, item):
2060 if isinstance(item, AudioItem): 2061 Genre.add_item(self, item) 2062 return True 2063 return False
2064
2065 2066 -class MovieGenre(Genre):
2067 """ Style of movies. Can contain objects of class Person, VideoItem, 2068 MovieGenre. 2069 """ 2070 upnp_class = '%s%s' % (Genre.upnp_class, '.movieGenre') 2071
2072 - def add_container(self, c):
2073 if isinstance(c, Person) or isinstance(c, self.__class__): 2074 Genre.add_container(self, c) 2075 return True 2076 return False
2077
2078 - def add_item(self, item):
2079 if isinstance(item, VideoItem): 2080 Genre.add_item(self, item) 2081 return True 2082 return False
2083
2084 2085 -class PlaylistContainer(Container):
2086 """ A collection of objects. May mix audio, video and image items and is 2087 typically created by users. 2088 """ 2089 upnp_class = '%s%s' % (Container.upnp_class, '.playlistContainer') 2090
2091 - def __init__(self, id='', parent_id='', title='', restricted=False, 2092 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 2093 searchable=True, search_classes=[], create_classes=[], 2094 artists=[], genres=[], long_description='', producers=[], 2095 storage_medium='', description='', contributors=[], date='', 2096 languages=[], rights=[]):
2097 """ Constructor for the PlaylistContainer class. 2098 2099 @param id: unique identifier for the object 2100 @param parent_id: id of object's parent 2101 @param title: name of the object 2102 @param restricted: True if only CDS can modify the object 2103 @param creator: content creator or owner 2104 @param write_status: modifiability of the resources of this object. 2105 Integer parameter based on WRITE_STATUS_* 2106 constants 2107 @param searchable: if True, Search action can be performed upon the 2108 container 2109 @param search_classes: list of SearchClass objects 2110 @param create_classes: list of CreateClass objects 2111 @param artists: list of artists names 2112 @param genres: list of genres 2113 @param long_description: long description 2114 @param producers: list of producers names 2115 @param storage_medium: indicates the type of storage used for the 2116 content. Possible values are enumerated on 2117 STORAGE_MEDIUM_* variables 2118 @param description: description 2119 @param contributors: list of contributors 2120 @param date: ISO 8601, form YYYY-MM-DD 2121 @param languages: list of languages 2122 @param rights: rights held in and over the resource 2123 2124 @type id: string 2125 @type parent_id: string 2126 @type title: string 2127 @type restricted: bool 2128 @type creator: string 2129 @type write_status: integer 2130 @type searchable: bool 2131 @type search_classes: list 2132 @type create_classes: list 2133 @type artists: list 2134 @type genres: list 2135 @type long_description: string 2136 @type producers: list 2137 @type storage_medium: string 2138 @type description: string 2139 @type contributors: list 2140 @type date: string 2141 @type languages: list 2142 @type rights: list 2143 """ 2144 Container.__init__(self, id, parent_id, title, restricted, creator, 2145 write_status, searchable, search_classes, 2146 create_classes) 2147 self.artists = artists 2148 self.genres = genres 2149 self.long_description = long_description 2150 self.producers = producers 2151 self.storage_medium = storage_medium 2152 self.description = description 2153 self.contributors = contributors 2154 self.date = date 2155 self.languages = languages 2156 self.rights = rights
2157
2158 - def from_element(self, elt):
2159 """ Sets the resource properties from an element. 2160 """ 2161 Container.from_element(self, elt) 2162 long_desc_elt = find(elt, 'upnp', 'longDescription') 2163 storage_elt = find(elt, 'upnp', 'storageMedium') 2164 desc_elt = find(elt, 'dc', 'description') 2165 date_elt = find(elt, 'dc', 'date') 2166 languages_elt = findall(elt, 'dc', 'language') 2167 rights_elt = findall(elt, 'dc', 'rights') 2168 2169 self.artists = [a.text for a in find(elt, 'upnp', 'artist')] 2170 self.genres = [g.text for g in find(elt, 'upnp', 'genre')] 2171 self.producers = [p.text for p in find(elt, 'upnp', 'producer')] 2172 self.contributors = [c.text for c in findall(elt, 'dc', 'contributor')] 2173 self.languages = [l.text for l in findall(elt, 'dc', 'language')] 2174 self.rights = [r.text for r in findall(elt, 'dc', 'rights')] 2175 2176 if long_desc_elt: 2177 self.long_description = long_desc_elt.text 2178 if storage_elt: 2179 self.storage_medium = storage_elt.text 2180 if desc_elt: 2181 self.description = desc_elt.text 2182 if date_elt: 2183 self.date = date_elt.text
2184
2185 - def to_didl_element(self):
2186 """ Returns an Element based on this Resource. 2187 """ 2188 root = Container.to_didl_element(self) 2189 for a in self.artists: 2190 ElementTree.SubElement(root, 'upnp:artist').text = a 2191 for g in self.genres: 2192 ElementTree.SubElement(root, 'upnp:genre').text = g 2193 for p in self.producers: 2194 ElementTree.SubElement(root, 'upnp:producer').text = p 2195 for c in self.contributors: 2196 ElementTree.SubElement(root, 'dc:contributor').text = c 2197 for l in self.languages: 2198 ElementTree.SubElement(root, 'dc:language').text = l 2199 for r in self.rights: 2200 ElementTree.SubElement(root, 'dc:rights').text = r 2201 2202 if self.long_description: 2203 ElementTree.SubElement(root, 'upnp:longDescription').text = \ 2204 self.long_description 2205 if self.storage_medium: 2206 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 2207 self.storage_medium 2208 if self.description: 2209 ElementTree.SubElement(root, 'dc:description').text = \ 2210 self.description 2211 if self.date: 2212 ElementTree.SubElement(root, 'dc:date').text = self.date 2213 2214 return root
2215
2216 2217 -class Person(Container):
2218 """ Unordered collection of objects that belong to a person. 2219 """ 2220 upnp_class = '%s%s' % (Container.upnp_class, '.person') 2221
2222 - def __init__(self, id='', parent_id='', title='', restricted=False, 2223 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 2224 searchable=True, search_classes=[], create_classes=[], 2225 languages=[]):
2226 """ Constructor for the Person class. 2227 2228 @param id: unique identifier for the object 2229 @param parent_id: id of object's parent 2230 @param title: name of the object 2231 @param restricted: True if only CDS can modify the object 2232 @param creator: content creator or owner 2233 @param write_status: modifiability of the resources of this object. 2234 Integer parameter based on WRITE_STATUS_* 2235 constants 2236 @param searchable: if True, Search action can be performed upon the 2237 container 2238 @param search_classes: list of SearchClass objects 2239 @param create_classes: list of CreateClass objects 2240 @param languages: list of languages 2241 2242 @type id: string 2243 @type parent_id: string 2244 @type title: string 2245 @type restricted: bool 2246 @type creator: string 2247 @type write_status: integer 2248 @type searchable: bool 2249 @type search_classes: list 2250 @type create_classes: list 2251 @type languages: list 2252 """ 2253 Container.__init__(self, id, parent_id, title, restricted, creator, 2254 write_status, searchable, search_classes, 2255 create_classes) 2256 self.languages = languages
2257
2258 - def add_container(self, c):
2259 if isinstance(c, Album) or isinstance(c, PlaylistContainer): 2260 Container.add_container(self, c) 2261 return True 2262 return False
2263
2264 - def add_item(self, item):
2265 if isinstance(c, Item): 2266 Container.add_item(self, item) 2267 return True 2268 return False
2269
2270 - def from_element(self, elt):
2271 """ Sets the resource properties from an element. 2272 """ 2273 Container.from_element(self, elt) 2274 self.languages = [l.text for l in findall(elt, 'dc', 'language')]
2275
2276 - def to_didl_element(self):
2277 """ Returns an Element based on this Resource. 2278 """ 2279 root = Container.to_didl_element(self) 2280 2281 for l in self.languages: 2282 ElementTree.SubElement(root, 'dc:language').text = l 2283 2284 return root
2285
2286 2287 -class MusicArtist(Person):
2288 """ Person which should be interpreted as a music artist. 2289 """ 2290 upnp_class = '%s%s' % (Person.upnp_class, '.musicArtist') 2291
2292 - def __init__(self, id='', parent_id='', title='', restricted=False, 2293 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 2294 searchable=True, search_classes=[], create_classes=[], 2295 languages=[], genres=[], artist_discography_uri=''):
2296 """ Constructor for the MusicArtist class. 2297 2298 @param id: unique identifier for the object 2299 @param parent_id: id of object's parent 2300 @param title: name of the object 2301 @param restricted: True if only CDS can modify the object 2302 @param creator: content creator or owner 2303 @param write_status: modifiability of the resources of this object. 2304 Integer parameter based on WRITE_STATUS_* 2305 constants 2306 @param searchable: if True, Search action can be performed upon the 2307 container 2308 @param search_classes: list of SearchClass objects 2309 @param create_classes: list of CreateClass objects 2310 @param languages: list of languages 2311 @param genres: list of genres 2312 @param artist_discography_uri: artist discography uri 2313 2314 @type id: string 2315 @type parent_id: string 2316 @type title: string 2317 @type restricted: bool 2318 @type creator: string 2319 @type write_status: integer 2320 @type searchable: bool 2321 @type search_classes: list 2322 @type create_classes: list 2323 @type languages: list 2324 @type genres: list 2325 @type artist_discography_uri: string 2326 """ 2327 Person.__init__(self, id, parent_id, title, restricted, creator, 2328 write_status, searchable, search_classes, 2329 create_classes, languages) 2330 self.genres = genres 2331 self.artist_discography_uri = artist_discography_uri
2332
2333 - def from_element(self, elt):
2334 """ Sets the resource properties from an element. 2335 """ 2336 Person.from_element(self, elt) 2337 artist_disc_uri = find(elt, 'upnp', 'artistDiscographyURI') 2338 2339 self.genres = [g.text for g in find(elt, 'upnp', 'genre')] 2340 2341 if artist_disc_uri: 2342 self.artist_discography_uri = artist_disc_uri.text
2343
2344 - def to_didl_element(self):
2345 """ Returns an Element based on this Resource. 2346 """ 2347 root = Person.to_didl_element(self) 2348 2349 for g in self.genres: 2350 ElementTree.SubElement(root, 'upnp:genre').text = g 2351 2352 if self.artist_discography_uri: 2353 ElementTree.SubElement(root, 'upnp:artistDiscographyURI').text = \ 2354 self.artist_discography_uri 2355 2356 return root
2357
2358 2359 -class StorageSystem(Container):
2360 """ Heterogeneous collection of storage media. May only be child of the 2361 root container or another StorageSystem container. 2362 """ 2363 upnp_class = '%s%s' % (Container.upnp_class, '.storageSystem') 2364
2365 - def __init__(self, id='', parent_id='', title='', restricted=False, 2366 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 2367 searchable=True, search_classes=[], create_classes=[], 2368 storage_total=0, storage_used=0, storage_free=0, 2369 storage_max_partition=0, storage_medium=''):
2370 """ Constructor for the StorageSystem class. 2371 2372 @param id: unique identifier for the object 2373 @param parent_id: id of object's parent 2374 @param title: name of the object 2375 @param restricted: True if only CDS can modify the object 2376 @param creator: content creator or owner 2377 @param write_status: modifiability of the resources of this object. 2378 Integer parameter based on WRITE_STATUS_* 2379 constants 2380 @param searchable: if True, Search action can be performed upon the 2381 container 2382 @param search_classes: list of SearchClass objects 2383 @param create_classes: list of CreateClass objects 2384 @param storage_total: total capacity, in bytes, of the storage 2385 represented by the container. Value -1 is 2386 reserved to indicate that the capacity is 2387 unknown 2388 @param storage_used: combined space, in bytes, used by all the objects 2389 held in the storage represented by the container. 2390 Value -1 is reserved to indicate that the space is 2391 unknown 2392 @param storage_free: total free capacity, in bytes, of the storage 2393 represented by the container. Value -1 is reserved 2394 to indicate that the capacity is unknown 2395 @param storage_max_partition: largest amount of space, in bytes, 2396 available for storing a single resource 2397 in the container. Value -1 is reserved 2398 to indicate that the capacity is unknown 2399 @param storage_medium: indicates the type of storage used for the 2400 content. Possible values are enumerated on 2401 STORAGE_MEDIUM_* variables 2402 2403 @type id: string 2404 @type parent_id: string 2405 @type title: string 2406 @type restricted: bool 2407 @type creator: string 2408 @type write_status: integer 2409 @type searchable: bool 2410 @type search_classes: list 2411 @type create_classes: list 2412 @type storage_total: signed long 2413 @type storage_used: signed long 2414 @type storage_free: signed long 2415 @type storage_max_partition: signed long 2416 @type storage_medium: string 2417 """ 2418 Container.__init__(self, id, parent_id, title, restricted, creator, 2419 write_status, searchable, search_classes, 2420 create_classes) 2421 self.storage_total = storage_total 2422 self.storage_used = storage_used 2423 self.storage_free = storage_free 2424 self.storage_max_partition = storage_max_partition 2425 self.storage_medium = storage_medium
2426
2427 - def from_element(self, elt):
2428 """ Sets the resource properties from an element. 2429 """ 2430 Container.from_element(self, elt) 2431 total = find(elt, 'upnp', 'storageTotal') 2432 used = find(elt, 'upnp', 'storageUsed') 2433 free = find(elt, 'upnp', 'storageFree') 2434 max_part = find(elt, 'upnp', 'storageMaxPartition') 2435 medium = find(elt, 'upnp', 'storageMedium') 2436 2437 if not all([total, used, free, max_part, medium]): 2438 raise Exception('Could not set StorageSystem properties '\ 2439 'from element: missing required properties.') 2440 2441 self.storage_total = total.text 2442 self.storage_used = used.text 2443 self.storage_free = free.text 2444 self.storage_max_partition = max_part.text 2445 self.storage_medium = medium.text
2446
2447 - def to_didl_element(self):
2448 """ Returns an Element based on this Resource. 2449 """ 2450 root = Container.to_didl_element(self) 2451 2452 if not all([self.storage_total, self.storage_used, self.storage_free, 2453 self.storage_max_partition, self.storage_medium]): 2454 raise Exception('Could not create DIDL Element: missing required '\ 2455 'properties.') 2456 2457 ElementTree.SubElement(root, 'upnp:storageTotal').text = \ 2458 self.storage_total 2459 ElementTree.SubElement(root, 'upnp:storageUsed').text = \ 2460 self.storage_used 2461 ElementTree.SubElement(root, 'upnp:storageFree').text = \ 2462 self.storage_free 2463 ElementTree.SubElement(root, 'upnp:storageMaxPartition').text = \ 2464 self.storage_max_partition 2465 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 2466 self.storage_medium 2467 2468 return root
2469
2470 2471 -class StorageVolume(Container):
2472 """ Some physical storage unit of a single type. May only be a child of the 2473 root container or a StorageSystem container. 2474 """ 2475 upnp_class = '%s%s' % (Container.upnp_class, '.storageVolume') 2476
2477 - def __init__(self, id='', parent_id='', title='', restricted=False, 2478 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 2479 searchable=True, search_classes=[], create_classes=[], 2480 storage_total=0, storage_used=0, storage_free=0, 2481 storage_medium=''):
2482 """ Constructor for the StorageVolume class. 2483 2484 @param id: unique identifier for the object 2485 @param parent_id: id of object's parent 2486 @param title: name of the object 2487 @param restricted: True if only CDS can modify the object 2488 @param creator: content creator or owner 2489 @param write_status: modifiability of the resources of this object. 2490 Integer parameter based on WRITE_STATUS_* 2491 constants 2492 @param searchable: if True, Search action can be performed upon the 2493 container 2494 @param search_classes: list of SearchClass objects 2495 @param create_classes: list of CreateClass objects 2496 @param storage_total: total capacity, in bytes, of the storage 2497 represented by the container. Value -1 is 2498 reserved to indicate that the capacity is unknown 2499 @param storage_used: combined space, in bytes, used by all the objects 2500 held in the storage represented by the container. 2501 Value -1 is reserved to indicate that the space is 2502 unknown 2503 @param storage_free: total free capacity, in bytes, of the storage 2504 represented by the container. Value -1 is reserved 2505 to indicate that the capacity is unknown 2506 @param storage_medium: indicates the type of storage used for the 2507 content. Possible values are enumerated on 2508 STORAGE_MEDIUM_* variables 2509 2510 @type id: string 2511 @type parent_id: string 2512 @type title: string 2513 @type restricted: bool 2514 @type creator: string 2515 @type write_status: integer 2516 @type searchable: bool 2517 @type search_classes: list 2518 @type create_classes: list 2519 @type storage_total: signed long 2520 @type storage_used: signed long 2521 @type storage_free: signed long 2522 @type storage_medium: string 2523 """ 2524 self.storage_total = storage_total 2525 self.storage_used = storage_used 2526 self.storage_free = storage_free 2527 self.storage_medium = storage_medium
2528
2529 - def from_element(self, elt):
2530 """ Sets the resource properties from an element. 2531 """ 2532 Container.from_element(self, elt) 2533 total = find(elt, 'upnp', 'storageTotal') 2534 used = find(elt, 'upnp', 'storageUsed') 2535 free = find(elt, 'upnp', 'storageFree') 2536 medium = find(elt, 'upnp', 'storageMedium') 2537 2538 if not all([total, used, free, medium]): 2539 raise Exception('Could not set StorageVolume properties '\ 2540 'from element: missing required properties.') 2541 2542 self.storage_total = total.text 2543 self.storage_used = used.text 2544 self.storage_free = free.text 2545 self.storage_medium = medium.text
2546
2547 - def to_didl_element(self):
2548 """ Returns an Element based on this Resource. 2549 """ 2550 root = Container.to_didl_element(self) 2551 2552 if not all([self.storage_total, self.storage_used, self.storage_free, 2553 self.storage_medium]): 2554 raise Exception('Could not create DIDL Element: missing required '\ 2555 'properties.') 2556 2557 ElementTree.SubElement(root, 'upnp:storageTotal').text = \ 2558 self.storage_total 2559 ElementTree.SubElement(root, 'upnp:storageUsed').text = \ 2560 self.storage_used 2561 ElementTree.SubElement(root, 'upnp:storageFree').text = \ 2562 self.storage_free 2563 ElementTree.SubElement(root, 'upnp:storageMedium').text = \ 2564 self.storage_medium 2565 2566 return root
2567
2568 2569 -class StorageFolder(Container):
2570 """ Collection of objects stored on some storage medium. May only be a 2571 child of the root container or another storage container. 2572 """ 2573 upnp_class = '%s%s' % (Container.upnp_class, '.storageFolder') 2574
2575 - def __init__(self, id='', parent_id='', title='', restricted=False, 2576 creator='', write_status=WRITE_STATUS_NOT_WRITABLE, 2577 searchable=True, search_classes=[], create_classes=[], 2578 storage_used=''):
2579 """ Constructor for the StorageFolder class. 2580 2581 @param id: unique identifier for the object 2582 @param parent_id: id of object's parent 2583 @param title: name of the object 2584 @param restricted: True if only CDS can modify the object 2585 @param creator: content creator or owner 2586 @param write_status: modifiability of the resources of this object. 2587 Integer parameter based on WRITE_STATUS_* 2588 constants 2589 @param searchable: if True, Search action can be performed upon the 2590 container 2591 @param search_classes: list of SearchClass objects 2592 @param create_classes: list of CreateClass objects 2593 @param storage_used: combined space, in bytes, used by all the objects 2594 held in the storage represented by the container. 2595 Value -1 is reserved to indicate that the space is 2596 unknown 2597 2598 @type id: string 2599 @type parent_id: string 2600 @type title: string 2601 @type restricted: bool 2602 @type creator: string 2603 @type write_status: integer 2604 @type searchable: bool 2605 @type search_classes: list 2606 @type create_classes: list 2607 @type storage_used: signed long 2608 """ 2609 self.storage_used = storage_used
2610
2611 - def from_element(self, elt):
2612 """ Sets the resource properties from an element. 2613 """ 2614 Container.from_element(self, elt) 2615 used = find(elt, 'upnp', 'storageUsed') 2616 2617 if not used: 2618 raise Exception('Could not set StorageFolder properties '\ 2619 'from element: missing required properties.') 2620 2621 self.storage_used = used.text
2622
2623 - def to_didl_element(self):
2624 """ Returns an Element based on this Resource. 2625 """ 2626 root = Container.to_didl_element(self) 2627 2628 if not self.storage_used: 2629 raise Exception('Could not create DIDL Element: missing required '\ 2630 'properties.') 2631 2632 ElementTree.SubElement(root, 'upnp:storageUsed').text = \ 2633 self.storage_used 2634 2635 return root
2636
2637 2638 -class Element(_ElementInterface):
2639 """ Wrapper for elements. Can mount a complete tree of DIDL UPnP classes 2640 from a string and also mount the string from a complete tree. 2641 """ 2642
2643 - def __init__(self):
2644 _ElementInterface.__init__(self, 'DIDL-Lite', {}) 2645 self.attrib['xmlns'] = 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/' 2646 self.attrib['xmlns:dc'] = 'http://purl.org/dc/elements/1.1/' 2647 self.attrib['xmlns:upnp'] = 'urn:schemas-upnp-org:metadata-1-0/upnp/' 2648 self.attrib['xmlns:dlna'] = 'urn:schemas-dlna-org:metadata-1-0' 2649 self._items = []
2650
2651 - def add_container(self, id, parent_id, title, restricted=False):
2652 e = Container(id, parent_id, title, restricted) 2653 self.append(e.to_element())
2654
2655 - def add_item(self, item):
2656 self.append(item.to_didl_element()) 2657 self._items.append(item)
2658
2659 - def num_items(self):
2660 return len(self)
2661
2662 - def get_items(self):
2663 return self._items
2664
2665 - def to_string(self):
2666 return ElementTree.tostring(self)
2667 2668 @classmethod
2669 - def from_string(cls, aString):
2670 instance = cls() 2671 elt = parse_xml(aString) 2672 elt = elt.getroot() 2673 add_item = instance.add_item 2674 2675 for node in elt.getchildren(): 2676 upnp_class_name = node.find( 2677 ".//{urn:schemas-upnp-org:metadata-1-0/upnp/}class").text 2678 names = upnp_class_name.split('.') 2679 while names: 2680 class_name = names[-1] 2681 class_name = "%s%s" % (class_name[0].upper(), class_name[1:]) 2682 try: 2683 upnp_class = eval(class_name) 2684 new_node = upnp_class() 2685 new_node.from_element(node) 2686 add_item(new_node) 2687 break 2688 except Exception, e: 2689 names = names[:-1] 2690 log.debug('element from string critical bug: %s' % str(e)) 2691 continue 2692 2693 return instance
2694