Ticket #186: dreambox_storage.py

File dreambox_storage.py, 5.0 kB (added by deepsight, 3 years ago)
Line 
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 """
11 This is a Media Backend that allows you to access video streams from
12 a Dreambox which uses the Enigma2 web interface. Based on the
13 Lolcats media backend.
14
15 """
16 import urllib
17
18 from coherence.backend import BackendStore
19 from coherence.backend import BackendItem
20 from coherence.upnp.core import DIDLLite
21 from coherence.upnp.core.utils import getPage
22 from twisted.internet import reactor
23 from coherence.extern.et import parse_xml
24
25 class TVChannel(BackendItem):
26
27     def __init__(self, parent_id, id, title, url):
28         self.parentid = parent_id       
29         self.update_id = 0
30         self.id = id                   
31         self.location = url             
32         self.name = title             
33         self.item = DIDLLite.VideoItem(id, parent_id, self.name)
34         res = DIDLLite.Resource(self.location, 'http-get:*:video/mpeg:DLNA_PN=MPEG_PS_PAL')
35         res.size = None
36         self.item.res.append(res)
37
38
39 class TVChannelsContainer(BackendItem):
40
41     def __init__(self, parent_id, id):
42         self.parent_id = parent_id
43         self.id = id
44         self.name = 'Dreambox'
45         self.mimetype = 'directory'
46         self.update_id = 0
47         self.children = []
48         self.item = DIDLLite.Container(id, parent_id, self.name)
49         self.item.childCount = None
50
51     def get_children(self, start=0, end=0):
52         if end != 0:
53             return self.children[start:end]
54         return self.children[start:]
55
56     def get_child_count(self):
57         return len(self.children)
58
59     def get_item(self):
60         return self.item
61
62     def get_name(self):
63         return self.name
64
65     def get_id(self):
66         return self.id
67
68 class DreamboxStore(BackendStore):
69
70     implements = ['MediaServer'] 
71
72     def __init__(self, server, *args, **kwargs):
73         self.ROOT_ID = 0
74         self.server = server
75        
76         #streaminghost is the ip address of the dreambox machine, defaults to localhost
77         self.streaminghost = kwargs.get('streaminghost',self.server.coherence.hostname)
78        
79         self.name = kwargs.get('name', 'Dreambox')
80         # timeout between updates in minutes
81         self.refresh = float(kwargs.get('refresh', 1)) * 60
82        
83         #for an explanation of bref see http://dream.reichholf.net/wiki/Enigma2:WebInterface
84         self.bRef = kwargs.get('bRef','1:0:1:5DE:23:46:E080000:0:0:0:')
85        
86         self.rss_url = "http://" + self.streaminghost + "/web/epgnow?bRef=" + urllib.quote(self.bRef)
87        
88         print urllib.quote(self.bRef)
89         self.next_id = 1000
90
91         self.last_updated = None
92         self.container = TVChannelsContainer(None, self.ROOT_ID)
93         self.channels = {}
94         dfr = self.update_data()
95         dfr.addCallback(self.init_completed)
96
97     def get_by_id(self, id):
98        
99         try:
100             id = int(id)
101             if id == self.ROOT_ID:               
102                 return self.container
103             else:
104                 return self.channels[id]
105        
106         except:       
107             return self.container
108
109     def upnp_init(self):
110         if self.server:
111
112             self.server.connection_manager_server.set_variable( \
113                 0, 'SourceProtocolInfo', ['http-get:*:video/mpeg:DLNA_PN=MPEG_PS_PAL',
114                 'http-get:*:video/mpeg:DLNA_PN=MPEG_TS_PAL',])
115
116     def update_data(self):
117         dfr = getPage(self.rss_url)
118         dfr.addCallback(parse_xml)
119         dfr.addCallback(self.parse_data)
120         dfr.addBoth(self.queue_update)
121
122         return dfr
123
124     def parse_data(self, xml_data):
125         root = xml_data.getroot()
126        
127         print len(root)
128         self.container.children = []
129         self.channels = {}
130
131         for y in root:
132             if y.tag == "e2event":
133                 title = y[-1].text + ' | '
134                            
135                 try:
136                     title += y[-5].text
137                     print title
138                
139                 except:
140                     print "some error getting the title"
141                    
142
143                 url = 'http://' + self.streaminghost +':8001/' + y[-2].text
144                 print title, url
145                 channel = TVChannel(self.ROOT_ID, self.next_id, title, url)
146                 self.container.children.append(channel)
147                 self.channels[self.next_id] = channel
148                 self.next_id += 1
149
150         self.container.update_id += 1
151         self.update_id += 1
152
153         if self.server:
154             self.server.content_directory_server.set_variable(0, 'SystemUpdateID', self.update_id)
155             value = (self.ROOT_ID,self.container.update_id)
156             self.server.content_directory_server.set_variable(0, 'ContainerUpdateIDs', value)
157
158     def queue_update(self, error_or_failure):
159         reactor.callLater(self.refresh, self.update_data)