forked from toastwaffle/py-cloudapp
/
cloud_api.py
122 lines (100 loc) · 4.82 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
120
121
import urllib2, json, threading, urlparse, os, Queue
from multipart import MultiPartForm
class RequestWithMethod(urllib2.Request):
"""Workaround for using DELETE with urllib2"""
def __init__(self, url, method, data=None, headers={},\
origin_req_host=None, unverifiable=False):
self._method = method
urllib2.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 = urllib2.HTTPDigestAuthHandler()
authHandler.add_password("Application", "my.cl.ly", username, password)
opener = urllib2.build_opener(authHandler)
urllib2.install_opener(opener)
def getFileList(self, maxItems, callback):
req = urllib2.Request(self.apiUrl + u'/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 = urllib2.Request(self.apiUrl + u'/items')
req.add_header('Accept', 'application/json')
req.add_header('Content-Type', 'application/json')
name = urlparse.urlparse(url).netloc
req.add_data(u'{"item":{"name":"%s","redirect_url":"%s"}}' % (name,url))
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 = urllib2.urlopen(task[0])
self.data = json.load(pagehandle)
if task[1]:
task[1](self.data)
except urllib2.HTTPError, e:
print "HTTP Error Code:" + str(e.code)
except urllib2.URLError, e:
print e.reason
class UploadThread(threading.Thread):
def getUploadParams(self):
req = urllib2.Request('http://my.cl.ly/items/new')
req.add_header('Accept', 'application/json')
response = urllib2.urlopen(req)
return json.load(response)
def run(self):
while True:
task = CloudApi.uploadQueue.get()
if task:
self.url, self.callback = task
uploadParams = self.getUploadParams()
if uploadParams:
try:
filePath = urlparse.urlparse(self.url).path
filename = os.path.basename(filePath)
uploadParams['params']['key'] = uploadParams['params']['key'].replace('${filename}', filename)
form = MultiPartForm()
for name in uploadParams["params"]:
form.addField(name.encode('ascii'), uploadParams["params"][name].encode('ascii'))
fp = open(filePath, 'rb')
form.addFile("file", os.path.basename(filePath), fp)
body = str(form)
req = urllib2.Request(uploadParams["url"].encode('ascii'))
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 = urllib2.urlopen(req)
if self.callback:
self.callback(json.load(response))
except urllib2.HTTPError, e:
print "HTTP Error Code:" + str(e.code)
except urllib2.URLError, e:
print e.reason
except IOError, e:
print "IOError when opening file to upload: "+filePath