add Request-System
[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         \r
23     def getIPAdress(self):\r
24         """    \r
25             socket.gethostbyname() is syncron\r
26             Enigma2 is blocked while process is running    \r
27         """\r
28         return socket.gethostbyname(self.hostname)\r
29 \r
30     def HeaderLoaded(self,headers):\r
31         self.headers = headers\r
32         for i in self.onHeaderLoaded:\r
33             i(headers)\r
34         self.onHeaderLoaded=[]\r
35         \r
36     def RequestError(self,error):\r
37         for i in self.onRequestError:\r
38             i(error)\r
39         self.onRequestError = []\r
40         \r
41     def RequestFinished(self,data):\r
42         for i in self.onRequestFinished:\r
43             i(data)\r
44        \r
45 class Enigma2URLHTTPRequest(Enigma2HTTPRequest):\r
46     def __init__(self,url,method="GET",headerfields={}):\r
47         x= urlparse.urlsplit(url)\r
48         if x[1].rfind(":")>0:\r
49             y = x[1].split(":")\r
50             hostname = y[0]\r
51             port = int(y[1])\r
52         else:\r
53             hostname = x[1]\r
54             port = 80\r
55         path=x[2]\r
56         Enigma2HTTPRequest.__init__(self,hostname,path,port,method=method,headerfields=headerfields)\r
57     \r
58 class Enigma2HTTPProtocol(HTTPClientProtocol):\r
59     headers={}\r
60     headerread=False\r
61     responseFirstLine = True # to indikate, that first line of responseheader was read\r
62 \r
63     def __init__(self,request):\r
64         self.request = request\r
65         HTTPClientProtocol.__init__(self)\r
66         self.setRawMode()\r
67         \r
68     def rawDataReceived(self,line):\r
69         for l in line.split(self.delimiter): \r
70             if self.headerread:\r
71                 self.request.data +=l\r
72             else:\r
73                 if l == "":\r
74                     self.headerread = True\r
75                     self.request.HeaderLoaded(self.headers)\r
76                 else:\r
77                     self.parseHeaderLine(l)\r
78     \r
79     def parseHeaderLine(self,line):\r
80         if self.responseFirstLine is  True:\r
81             (protocoll,responsecode,statuscode) = line.split(" ")\r
82             self.headers["protocoll"] = protocoll\r
83             self.headers["responsecode"] = responsecode\r
84             self.headers["statuscode"] = statuscode\r
85             self.responseFirstLine = False\r
86         elif line.rfind(":"):\r
87             x = line.split(":")\r
88             key = x[0].lstrip().rstrip().lower()\r
89             var = ":".join(x[1:]).lstrip()\r
90             self.headers[key] = var        \r
91         else:\r
92             print "unknown headerline",line\r
93 \r
94     def connectionMade(self):\r
95         self.sendLine("%s %s HTTP/1.0"%(self.request.method,self.request.path))\r
96         self.sendLine("Host: %s"%self.request.hostname)\r
97         for i in self.request.headerfields:\r
98             self.sendLine(i+": "+self.request.headerfields[i])\r
99         self.sendLine("")\r
100 \r
101         \r
102 class Enigma2HTTPClientFactory(ClientFactory):\r
103 \r
104     initialDelay = 20\r
105     maxDelay = 500\r
106     \r
107     def __init__(self,request):\r
108         self.hangup_ok = False\r
109         self.request = request\r
110        \r
111     def startedConnecting(self, connector):\r
112         pass\r
113     \r
114     def buildProtocol(self, addr):\r
115         return Enigma2HTTPProtocol(self.request)\r
116 \r
117     def clientConnectionLost(self, connector, reason):\r
118         if not self.hangup_ok:\r
119             self.request.RequestFinished(self.request.data)\r
120         ClientFactory.clientConnectionLost(self, connector, reason)\r
121         \r
122     def clientConnectionFailed(self, connector, reason):\r
123         if self.errorback is not None:\r
124             self.request.RequestError(reason.getErrorMessage())\r
125         ClientFactory.clientConnectionFailed(self, connector, reason)\r
126 \r
127 def getURL(url,callback=None,errorback=None,headercallback=None,method="GET",headers={}):\r
128     """ \r
129         this will is called with a url\r
130         url = http://www.hostna.me/somewhere/on/the/server <string>\r
131     """\r
132     req = Enigma2URLHTTPRequest(url,method=method,headerfields=headers)\r
133     req.onRequestError.append(errorback)\r
134     req.onRequestFinished.append(callback)\r
135     reactor.connectTCP(req.getIPAdress(),req.port, Enigma2HTTPClientFactory(req))\r
136 \r
137 def getPage(hostname,port,path,method="GET",callback=None,errorback=None):#,headercallback=None,headers={}):\r
138     """ \r
139         this will is called with separte hostname,port,path\r
140         hostname = www.hostna.me <string>\r
141         port = 80 <int>\r
142         path= /somewhere/on/the/server <string>\r
143     """\r
144     req = Enigma2HTTPRequest(hostname,path,port,method=method)#,headerfields=headers)\r
145     req.onRequestError.append(errorback)\r
146     req.onRequestFinished.append(callback)\r
147     reactor.connectTCP(req.getIPAdress(),req.port, Enigma2HTTPClientFactory(req))\r
148 \r
149 def getFile(filename,url,method="GET",callback=None,errorback=None,headercallback=None,headers={}):\r
150     """ \r
151         this will is called with a url and a target file\r
152         fimename = /tmp/target.jpg \r
153         url = http://www.hostna.me/somewhere/on/the/server.jpg <string>\r
154     """\r
155     def save(data):\r
156         try:\r
157             fp = open(filename,"w")\r
158             fp.write(data)\r
159             fp.close()\r
160             if callback is not None:\r
161                 callback()\r
162         except Exception,e:\r
163             if errorback is not None:\r
164                 errorback(e)\r
165     getURL(url,method=method,callback=save,errorback=errorback,headercallback=headercallback,headers=headers)\r