fix oops
[enigma2-plugins.git] / netcaster / src / bin / StreamInterface.py
1 from twisted.web.client import HTTPClientFactory, HTTPPageDownloader, _parse
2
3 valid_types = ("MP3","PLS") #list of playable mediatypes
4
5 def getPage(url, contextFactory=None, *args, **kwargs):
6         scheme, host, port, path = _parse(url)
7         factory = LimitedHTTPClientFactory(url, *args, **kwargs)
8         if scheme == 'https':
9                 from twisted.internet import ssl 
10                 if contextFactory is None:
11                         contextFactory = ssl.ClientContextFactory()
12                 reactor.connectSSL(host, port, factory, contextFactory)
13         else:
14                 reactor.connectTCP(host, port, factory)
15         return factory.deferred
16
17 class LimitedHTTPClientFactory(HTTPClientFactory):
18
19         LIMIT = 1024
20
21         protocol = HTTPPageDownloader
22
23         def __init__(self, *args, **kwargs):
24                 HTTPClientFactory.__init__(self, *args, **kwargs)
25                 self.curlength = 0
26                 self.buf = ""
27
28         def buildProtocol(self, addr):
29                 self.p = HTTPClientFactory.buildProtocol(self, addr)
30                 return self.p
31
32         def pageStart(self, p):
33                 pass
34
35         def pagePart(self, d):
36                 if self.status == '200':
37                         self.curlength += len(d)
38                         if self.curlength >= self.LIMIT:
39                                 print "[LimitedHTTPClientFactory] reached limit"
40                                 # XXX: timing out here is pretty hackish imo
41                                 self.p.timeout()
42                                 return
43                 self.buf += d
44
45         def pageEnd(self):
46                 if self.waiting:
47                         self.waiting = 0
48                         self.deferred.callback(self.buf)
49
50 class StreamInterface:
51     def __init__(self,session,cbListLoaded=None):
52         self.session = session
53         self.cbListLoaded = cbListLoaded
54
55         self.list= [] # contains the streams in this iface
56
57     def getList(self):
58         #loads a list auf Streams into self.list
59         pass
60
61     def getMenuItems(self,selectedStream,generic=False):
62         # this return a list of MenuEntries of actions of this iterface
63         # list=(("item1",func1),("item2",func2), ... )
64         #
65         # generic=True indicates, that items of the returned list are services
66         # in any context (like saving a stream to the favorites)
67         return []
68
69     def OnListLoaded(self):
70         # called from the interface, if list was loaded
71         if self.cbListLoaded is not None:
72             self.cbListLoaded(self.list)
73
74 ###############################################################################
75 class Stream:
76     isfavorite = False
77     def __init__(self,name,description,url,type="mp3"):
78         self.name = name
79         self.description = description
80         self.url = url
81         self.type=type
82     def getName(self):
83         return self.name
84     def getDescription(self):
85         return self.description
86     def setName(self,name):
87         self.name = name
88     def setDescription(self,description):
89         self.description = description
90     def setURL(self,url):
91         self.url = url
92     def getURL(self, callback):
93         self.callback = callback
94         if self.type.lower() == "pls":
95                 self.getPLSContent()
96         else:
97             self.callback(self.url)
98
99     def getPLSContent(self):
100         print "loading PLS of stream ",self.name,self.url
101         getPage(self.url).addCallback(self._gotPLSContent).addErrback(self._errorPLSContent)
102
103     def _gotPLSContent(self, lines):
104                 if lines.startswith("ICY "):
105                         print "PLS expected, but got ICY stream"
106                         self.type = "mp3"
107                         self.callback(self.url)
108
109                 else:
110                         for line in lines.split('\n'):
111                             if line.startswith("File"):
112                                 url = line.split("=")[1].rstrip().strip()
113                                 self.callback(url)
114                                 break
115                             print "Skipping:", line
116
117     def _errorPLSContent(self, data, callback):
118         callback(None)
119
120
121     def setFavorite(self,TrueFalse):
122         self.isfavorite = TrueFalse
123     def isFavorite(self):
124         return self.isfavorite
125     def setType(self,type):
126         self.type=type
127     def getType(self):
128         return self.type
129