implement modified page getter which aborts download after 1024byte, feel free to...
[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                 self.deferred.callback(self.buf)
47
48 class StreamInterface:
49     def __init__(self,session,cbListLoaded=None):
50         self.session = session
51         self.cbListLoaded = cbListLoaded
52
53         self.list= [] # contains the streams in this iface
54
55     def getList(self):
56         #loads a list auf Streams into self.list
57         pass
58
59     def getMenuItems(self,selectedStream,generic=False):
60         # this return a list of MenuEntries of actions of this iterface
61         # list=(("item1",func1),("item2",func2), ... )
62         #
63         # generic=True indicates, that items of the returned list are services
64         # in any context (like saving a stream to the favorites)
65         return []
66
67     def OnListLoaded(self):
68         # called from the interface, if list was loaded
69         if self.cbListLoaded is not None:
70             self.cbListLoaded(self.list)
71
72 ###############################################################################
73 class Stream:
74     isfavorite = False
75     def __init__(self,name,description,url,type="mp3"):
76         self.name = name
77         self.description = description
78         self.url = url
79         self.type=type
80     def getName(self):
81         return self.name
82     def getDescription(self):
83         return self.description
84     def setName(self,name):
85         self.name = name
86     def setDescription(self,description):
87         self.description = description
88     def setURL(self,url):
89         self.url = url
90     def getURL(self, callback):
91         self.callback = callback
92         if self.type.lower() == "pls":
93                 self.getPLSContent()
94         else:
95             self.callback(self.url)
96
97     def getPLSContent(self):
98         print "loading PLS of stream ",self.name,self.url
99         getPage(self.url).addCallback(self._gotPLSContent).addErrback(self._errorPLSContent)
100
101     def _gotPLSContent(self, lines):
102                 if lines.startswith("ICY "):
103                         print "PLS expected, but got ICY stream"
104                         self.type = "mp3"
105                         self.callback(self.url)
106
107                 else:
108                         for line in lines.split('\n'):
109                             if line.startswith("File"):
110                                 url = line.split("=")[1].rstrip().strip()
111                                 self.callback(url)
112                                 break
113                             print "Skipping:", line
114
115     def _errorPLSContent(self, data, callback):
116         callback(None)
117
118
119     def setFavorite(self,TrueFalse):
120         self.isfavorite = TrueFalse
121     def isFavorite(self):
122         return self.isfavorite
123     def setType(self,type):
124         self.type=type
125     def getType(self):
126         return self.type
127