fix Bug with Coverart, wrong paramcount on onImageLoaded
[enigma2-plugins.git] / lastfm / src / httpclient.py
1 from twisted.internet import reactor\r
2 from twisted.internet.protocol import ClientFactory,connectionDone\r
3 from twisted.web2.client.http import HTTPClientProtocol\r
4 from twisted.internet import error \r
5 import urlparse\r
6 \r
7 import socket\r
8 \r
9 class Enigma2HTTPRequest:\r
10         \r
11     def __init__(self,hostname,path,port,method="GET",headerfields={}):\r
12         self.hostname=hostname\r
13         self.port=port\r
14         self.path=path\r
15         self.method=method\r
16         self.headerfields = headerfields\r
17         self.onRequestFinished = []\r
18         self.onRequestError = []\r
19         self.onHeaderLoaded = []\r
20         \r
21         self.data=""\r
22         self.readsize = 0\r
23         self.headers= {}\r
24         \r
25     def _DataRecived(self,data):\r
26         self.readsize += len(data)\r
27         self.data += data\r
28             \r
29     def getIPAdress(self):\r
30         """    \r
31             socket.gethostbyname() is syncron\r
32             Enigma2 is blocked while process is running    \r
33         """\r
34         return socket.gethostbyname(self.hostname)\r
35 \r
36     def HeaderLoaded(self,headers):\r
37         self.headers = headers\r
38         for i in self.onHeaderLoaded:\r
39             if i is not None:\r
40                 i(headers)\r
41         self.onHeaderLoaded=[]\r
42         \r
43     def RequestError(self,error):\r
44         for i in self.onRequestError:\r
45             if i is not None:\r
46                 i(error)\r
47         self.onRequestError = []\r
48         \r
49     def RequestFinished(self,data):\r
50         for i in self.onRequestFinished:\r
51             if i is not None:\r
52                 i(data)\r
53        \r
54 class Enigma2URLHTTPRequest(Enigma2HTTPRequest):\r
55     def __init__(self,url,method="GET",headerfields={}):\r
56         x= urlparse.urlsplit(url)\r
57         if x[1].rfind(":")>0:\r
58             y = x[1].split(":")\r
59             hostname = y[0]\r
60             port = int(y[1])\r
61         else:\r
62             hostname = x[1]\r
63             port = 80\r
64         path=x[2]\r
65         Enigma2HTTPRequest.__init__(self,hostname,path,port,method=method,headerfields=headerfields)\r
66 \r
67 class Enigma2FileHTTPRequest(Enigma2URLHTTPRequest):\r
68     def __init__(self,targetfile,url,method="GET",headerfields={}):\r
69         Enigma2URLHTTPRequest.__init__(self,url,method=method,headerfields=headerfields)\r
70         self.filehandle = open(targetfile,"w")\r
71         self.onRequestFinished.append(self.close)\r
72         self.onRequestError.append(self.close)\r
73     def close(self,dummy):\r
74         self.filehandle.close()\r
75     \r
76     def _DataRecived(self,data):\r
77         self.readsize += len(data)\r
78         self.filehandle.write(data)\r
79         \r
80             \r
81         \r
82         \r
83 class Enigma2HTTPProtocol(HTTPClientProtocol):\r
84 \r
85     def __init__(self,request):\r
86         self.request = request\r
87         self.headers={}\r
88         self.headerread=False\r
89         self.responseFirstLine = True # to indikate, that first line of responseheader was read\r
90         HTTPClientProtocol.__init__(self)\r
91         self.setRawMode()\r
92         \r
93     def rawDataReceived(self,line):\r
94         for l in line.split(self.delimiter): \r
95             if self.headerread:\r
96                 self.request._DataRecived(l)\r
97             else:\r
98                 if l == "":\r
99                     self.headerread = True\r
100                     self.request.HeaderLoaded(self.headers)\r
101                 else:\r
102                     self.parseHeaderLine(l)\r
103     \r
104     def parseHeaderLine(self,line):\r
105         if self.responseFirstLine is  True:\r
106             (protocoll,responsecode,statuscode) = line.split(" ")\r
107             self.headers["protocoll"] = protocoll\r
108             self.headers["responsecode"] = responsecode\r
109             self.headers["statuscode"] = statuscode\r
110             self.responseFirstLine = False\r
111         elif line.rfind(":"):\r
112             x = line.split(":")\r
113             key = x[0].lstrip().rstrip().lower()\r
114             var = ":".join(x[1:]).lstrip()\r
115             self.headers[key] = var        \r
116         else:\r
117             print "unknown headerline",line\r
118 \r
119     def connectionMade(self):\r
120         self.sendLine("%s %s HTTP/1.0"%(self.request.method,self.request.path))\r
121         self.sendLine("Host: %s"%self.request.hostname)\r
122         for i in self.request.headerfields:\r
123             self.sendLine(i+": "+self.request.headerfields[i])\r
124         self.sendLine("")\r
125 \r
126         \r
127 class Enigma2HTTPClientFactory(ClientFactory):\r
128 \r
129     initialDelay = 20\r
130     maxDelay = 500\r
131     \r
132     def __init__(self,request):\r
133         self.hangup_ok = False\r
134         self.request = request\r
135        \r
136     def startedConnecting(self, connector):\r
137         pass\r
138     \r
139     def buildProtocol(self, addr):\r
140         return Enigma2HTTPProtocol(self.request)\r
141 \r
142     def clientConnectionLost(self, connector, reason):\r
143         if not self.hangup_ok:\r
144             self.request.RequestFinished(self.request.data)\r
145         ClientFactory.clientConnectionLost(self, connector, reason)\r
146         \r
147     def clientConnectionFailed(self, connector, reason):\r
148         if self.errorback is not None:\r
149             self.request.RequestError(reason.getErrorMessage())\r
150         ClientFactory.clientConnectionFailed(self, connector, reason)\r
151 \r
152 def getURL(url,callback=None,errorback=None,headercallback=None,method="GET",headers={}):\r
153     """ \r
154         this will is called with a url\r
155         url = http://www.hostna.me/somewhere/on/the/server <string>\r
156     """\r
157     req = Enigma2URLHTTPRequest(url,method=method,headerfields=headers)\r
158     req.onRequestError.append(errorback)\r
159     req.onHeaderLoaded.append(headercallback)\r
160     req.onRequestFinished.append(callback)\r
161     reactor.connectTCP(req.getIPAdress(),req.port, Enigma2HTTPClientFactory(req))\r
162     return req\r
163 \r
164 def getPage(hostname,port,path,method="GET",callback=None,errorback=None,headercallback=None,headers={}):\r
165     """ \r
166         this will is called with separte hostname,port,path\r
167         hostname = www.hostna.me <string>\r
168         port = 80 <int>\r
169         path= /somewhere/on/the/server <string>\r
170     """\r
171     req = Enigma2HTTPRequest(hostname,path,port,method=method,headerfields=headers)\r
172     req.onRequestError.append(errorback)\r
173     req.onRequestFinished.append(callback)\r
174     reactor.connectTCP(req.getIPAdress(),req.port, Enigma2HTTPClientFactory(req))\r
175     return req\r
176 \r
177 def getFile(filename,url,method="GET",callback=None,errorback=None,headercallback=None,headers={}):\r
178     """ \r
179         this will is called with a url and a target file\r
180         fimename = /tmp/target.jpg \r
181         url = http://www.hostna.me/somewhere/on/the/server.jpg <string>\r
182     """\r
183     req = Enigma2FileHTTPRequest(filename,url,method=method,headerfields=headers)\r
184     req.onRequestError.append(errorback)\r
185     req.onHeaderLoaded.append(headercallback)\r
186     req.onRequestFinished.append(callback)\r
187     reactor.connectTCP(req.getIPAdress(),req.port, Enigma2HTTPClientFactory(req))\r
188     return req\r