enigma2 20130114 (master) -> 20130216 (master)
[enigma2.git] / usr / lib / enigma2 / python / Plugins / SystemPlugins / UPnP / DreamboxServiceStore.py
1 # -*- coding: utf-8 -*-
2
3 # Licensed under the MIT license
4 # http://opensource.org/licenses/mit-license.php
5
6 # Copyright 2009, Jose Luis Garduno Garcia <deepsight[atsign]gmail.com>
7 # Based on the Lolcats Media backend from Benjamin Kampmann
8 # Copyright 2008, Benjamin Kampmann <ben.kampmann@googlemail.com>
9
10 #relicensed under the enigma2 license!
11 """
12 This is a Media Backend that allows you to access video streams from
13 a Dreambox which uses the Enigma2 web interface. Based on the
14 Lolcats media backend.
15
16 """
17 from enigma import eServiceReference
18 from Components.Sources.ServiceList import ServiceList
19
20 from coherence.backend import ROOT_CONTAINER_ID, AbstractBackendStore, Container, LazyContainer, BackendItem
21 from coherence.upnp.core import DIDLLite
22
23 from twisted.internet import defer
24 from coherence.extern.et import parse_xml
25
26 class DreamboxService(BackendItem):
27         def __init__(self, title, url, service_number, storage):
28                 self.update_id = 0
29                 self.name = title
30                 self.location = url
31                 self.storage = storage
32                 self.item = None
33                 self.service_number = service_number
34
35         def get_service_number(self):
36                 return self.service_number
37
38         def get_children(self, start=0, end=0):
39                 []
40
41         def get_child_count(self):
42                 return 0
43
44         def get_id(self):
45                 return self.storage_id
46
47         def get_path(self):
48                 return self.location
49
50         def get_item(self):
51                 if self.item == None:
52                         self.item = DIDLLite.VideoItem(self.get_id(), self.storage.get_id(), self.name)
53                         res = DIDLLite.Resource(self.location, 'http-get:*:video/mpeg:DLNA_PN=MPEG_PS_PAL')
54                         res.size = None
55                         self.item.res.append(res)
56
57                 return self.item
58
59 class DreamboxServiceStore(AbstractBackendStore):
60         implements = ['MediaServer']
61         logCategory = 'dreambox_service_store'
62
63         def __init__(self, server, *args, **kwargs):
64                 AbstractBackendStore.__init__(self, server, **kwargs)
65
66                 self.name = kwargs.get('name','Dreambox (TV)')
67                 # streaminghost is the ip address of the dreambox machine, defaults to localhost
68                 self.streaminghost = kwargs.get('streaminghost', self.server.coherence.hostname)
69
70                 self.refresh = float(kwargs.get('refresh', 1)) * 60
71                 self.init_root()
72                 self.init_completed()
73
74         def init_root(self):
75                 root = Container(None, ROOT_CONTAINER_ID)
76                 self.set_root_item( root )
77                 root.add_child(
78                         LazyContainer(
79                                 root,
80                                 _("Bouquets (TV)"),
81                                 external_id="1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM BOUQUET \"bouquets.tv\" ORDER BY bouquet",
82                                 childrenRetriever=self.populate_container))
83                 root.add_child(
84                         LazyContainer(
85                                 root,
86                                 ("Provider (TV)"),
87                                 external_id="1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM PROVIDERS ORDER BY name",
88                                 childrenRetriever=self.populate_container))
89                 root.add_child(
90                         LazyContainer(
91                                 root,
92                                 _("Bouquets (Radio)"),
93                                 external_id="1:7:2:0:0:0:0:0:0:0:(type == 2)FROM BOUQUET \"bouquets.radio\" ORDER BY bouquet",
94                                 childrenRetriever=self.populate_container))
95                 root.add_child(
96                         LazyContainer(
97                                 root,
98                                 _("Provider (Radio)"),
99                                 external_id="1:7:2:0:0:0:0:0:0:0:(type == 2) FROM PROVIDERS ORDER BY name",
100                                 childrenRetriever=self.populate_container))
101                 root.sorted = True
102
103         def populate_container(self, parent=None):
104                 self.warning("ref %s" %parent.external_id)
105                 retriever = self.populate_container
106
107                 def do_populate(parent=None):
108                         if parent.external_id == None:
109                                 self.warning("Invalid ref %s" %parent.external_id)
110                                 return
111
112                         servicelist = None
113                         def get_servicelist(ref):
114                                 servicelist.root = ref
115                         ref = eServiceReference(parent.external_id)
116                         if not ref.valid():
117                                 self.warning("Invalid ref %s" %parent.external_id)
118                                 return
119
120                         servicelist = ServiceList(ref, command_func=get_servicelist, validate_commands=False)
121                         services = servicelist.getServicesAsList()
122
123                         snum = 1
124                         isChannelList = False
125                         for sref, name in services:
126                                 name = unicode(name.replace('\xc2\x86', '').replace('\xc2\x87', ''), errors='ignore')
127                                 item = None
128                                 if sref.startswith("1:7:"): #Bouquet
129                                         item = LazyContainer(parent, name, childrenRetriever=retriever)
130                                 else:
131                                         isChannelList = True
132                                         if not sref.startswith("1:64:"): # skip markers
133                                                 url = 'http://' + self.streaminghost + ':8001/' + sref
134                                                 item = DreamboxService(name, url, snum, parent)
135                                                 snum += 1
136
137                                 if item is not None:
138                                         parent.add_child(item, external_id=sref)
139
140                         if isChannelList:
141                                 def sort(x, y):
142                                         return cmp(x.get_service_number(), y.get_service_number())
143                                 parent.sorting_method = sort
144
145                 d = defer.maybeDeferred(do_populate, parent=parent)
146                 return d
147
148         def upnp_init(self):
149                 if self.server:
150                         self.server.connection_manager_server.set_variable(\
151                                 0, 'SourceProtocolInfo', ['http-get:*:video/mpeg:DLNA_PN=MPEG_PS_PAL',
152                                 'http-get:*:video/mpeg:DLNA_PN=MPEG_TS_PAL', ])
153