forked from abnd90/py-cloudapp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloud_api.py
executable file
·119 lines (100 loc) · 5.07 KB
/
cloud_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import urllib.request, urllib.error, urllib.parse, json, threading, os, queue, logging
from multipart import MultiPartForm
from urllib.parse import urlparse
class RequestWithMethod(urllib.request.Request):
"""Workaround for using DELETE with urllib2"""
def __init__(self, url, method, data=None, headers={},\
origin_req_host=None, unverifiable=False):
self._method = method
urllib.request.Request.__init__(self, url, data=None, headers={},\
origin_req_host=None, unverifiable=False)
def get_method(self):
return self._method
class CloudApi(object):
"""Asynchronus multithreaded library interfacing with the cloudapp api"""
apiUrl = "http://my.cl.ly"
_queue = queue.Queue()
uploadQueue = queue.Queue()
def __init__(self, username, password):
self.setLoginDetails(username, password)
for i in range(3):
t = self.ApiThread()
t.setDaemon(True)
t.start()
t = self.UploadThread()
t.setDaemon(True)
t.start()
def setLoginDetails(self, username, password):
self.userName = username
self.password = password
authHandler = urllib.request.HTTPDigestAuthHandler()
authHandler.add_password("Application", "my.cl.ly", username, password)
opener = urllib.request.build_opener(authHandler)
urllib.request.install_opener(opener)
def getFileList(self, maxItems, callback):
req = urllib.request.Request(self.apiUrl + '/items?page=1&per_page=' + str(maxItems))
req.add_header('Accept', 'application/json')
self._queue.put((req, callback))
def bookmark(self, url, callback = None):
req = urllib.request.Request(self.apiUrl + '/items')
req.add_header('Accept', 'application/json')
req.add_header('Content-Type', 'application/json')
name = urlparse(url).netloc
req.add_data(('{"item":{"name":"%s","redirect_url":"%s"}}' % (name,url)).encode('utf-8'))
self._queue.put((req, callback))
def uploadFile(self, url, callback = None):
self.uploadQueue.put((url, callback))
def delete(self, url, callback = None):
req = RequestWithMethod(url, 'DELETE')
req.add_header('Accept', 'application/json')
self._queue.put((req, callback))
class ApiThread(threading.Thread):
def run(self):
while True:
task = CloudApi._queue.get()
if task:
try:
pagehandle = urllib.request.urlopen(task[0])
self.data = json.loads(pagehandle.read().decode('utf-8'))
if task[1]:
task[1](self.data)
except urllib.error.HTTPError as e:
logging.error("HTTP Error Code:" + str(e.code))
except urllib.error.URLError as e:
logging.error(e.reason)
class UploadThread(threading.Thread):
def getUploadParams(self):
req = urllib.request.Request('http://my.cl.ly/items/new')
req.add_header('Accept', 'application/json')
response = urllib.request.urlopen(req)
return json.loads(response.read().decode('utf-8'))
def run(self):
while True:
task = CloudApi.uploadQueue.get()
if task:
self.url, self.callback = task
uploadParams = self.getUploadParams()
if uploadParams:
try:
form = MultiPartForm()
for name in uploadParams["params"]:
form.addField(name, uploadParams["params"][name])
filePath = urlparse(self.url).path
# fp = open(filePath, 'rb')
form.addFile(filePath)
# form.addFile("file",os.path.basename(filePath) , fp)
body = form.toBytes()
req = urllib.request.Request(uploadParams["url"])
req.add_header('Content-type', form.getContentType())
req.add_header('Content-length', str(len(body)))
req.add_header('Accept', 'application/json')
req.add_data(body)
response = urllib.request.urlopen(req)
if self.callback:
self.callback(json.loads(response.read().decode('utf-8')))
except urllib.error.HTTPError as e:
logging.error("HTTP Error Code:" + str(e.code))
except urllib.error.URLError as e:
logging.error(e.reason)
except IOError as e:
logging.error("IOError when opening file to upload: "+filePath)