This repository was archived by the owner on Nov 23, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbayfiles.py
More file actions
264 lines (201 loc) · 7.5 KB
/
Copy pathbayfiles.py
File metadata and controls
264 lines (201 loc) · 7.5 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# coding:utf-8
#
import requests
import sys
import os
BASE_URL = "http://api.bayfiles.com/v1"
class FileBasicException(requests.ConnectionError):
"""Exception"""
pass
class FileUploadException(FileBasicException):
"""Exception triggered in upload() method."""
pass
class FileDeleteException(FileBasicException):
"""Exception triggered in delete() method."""
pass
class File(object):
"""
File instance represents the file to send to bayfiles.com.
Keywords arguments:
filepath -- the file to upload to bayfiles.com
account -- a bayfiles.Account instance
"""
def __init__(self, filepath, account=None):
self.metadata = {}
self.filepath = filepath
self.account = account
if not os.path.isfile(self.filepath):
raise Exception('%s is not a file' % (self.filepath))
# ask for an upload URL
self.__register_url()
def __register_url(self):
"""
This function will request an upload url to post the file you need to
store and a progress url that can be polled to know the progress of the
upload.
"""
url = BASE_URL + '/file/uploadUrl'
if self.account and hasattr(self.account, "session"):
url += '?session={0}'.format(self.account.session)
request = requests.get(url)
if not request.ok:
request.raise_for_status()
self.metadata = request.json()
if self.metadata['error'] != u'':
raise FileUploadException(self.metadata['error'])
def __get_sha1hash(self):
"""Return the sha1 hash on the entire content of the file passed."""
# Don't know if it's "right" to import a module in a function
import hashlib
sha1_obj = hashlib.sha1()
with open(self.filepath, 'rb') as file_r:
while True:
buffr = file_r.read(0x100000)
if not buffr:
break
sha1_obj.update(buffr)
sha1hash = sha1_obj.hexdigest()
return sha1hash
def upload(self, validate=True):
"""Upload the file to bayfiles server.
Keywords arguments:
validate -- a boolean, if set to True, it will ensure there was no
corruption during the transfert by comparing the sha1 hash of the local
file and the one computed by bayfile.
Should an error arise an exception FileUploadException is raised.
"""
with open(self.filepath, 'rb') as file_fd:
files = {'file': file_fd}
request = requests.post(self.metadata['uploadUrl'], files=files)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == '':
self.metadata.update(json)
else:
raise FileUploadException(json['error'])
# If we ask the sha1 hash validation
if validate:
sha1hash = self.__get_sha1hash()
if not self.metadata['sha1'] == sha1hash:
raise FileUploadException(
"The file was corrupted during the upload")
def delete(self):
"""Delete the download url and the file stored in bayfiles."""
try:
url = BASE_URL +\
'/file/delete/{0}/{1}'.format(self.metadata['fileId'],
self.metadata['deleteToken'])
request = requests.get(url)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == u'':
return
else:
raise FileDeleteException(json['error'])
except:
raise FileDeleteException(sys.exc_info()[0])
def info(self):
"""Return public information about the file instance."""
try:
url = BASE_URL +\
'/file/info/{0}/{1}'.format(self.metadata['fileId'],
self.metadata['infoToken'])
request = requests.get(url)
if not request.ok:
request.raise_for_status()
return request.json()
except KeyError:
print "Need to call upload() before info()"
class Account(object):
"""
Represent an account on the site bayfiles.com.
Keywords arguments:
username -- a string which is the username of the account
password -- a string which is the password of the account
"""
def __init__(self, username, password):
self.username = username
self.password = password
self.__login()
def __login(self):
"""Authenticate and receive a session identifier."""
url = BASE_URL + '/account/login/{0}/{1}'.format(self.username,
self.password)
try:
request = requests.get(url)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == u'':
self.session = json['session']
else:
raise Exception(json['error'])
except:
raise Exception(sys.exc_info()[0])
def logout(self):
"""Delete the session related to the account on bayfiles.com."""
url = BASE_URL + '/account/logout'
url += '?session={0}'.format(self.session)
try:
request = requests.get(url)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == u'':
self.session = None
return
else:
raise Exception(json['error'])
except:
raise Exception(sys.exc_info()[0])
def info(self):
"""Return a dictionnary with information about the account."""
url = BASE_URL + '/account/info'
url += '?session={0}'.format(self.session)
try:
request = requests.get(url)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == u'':
return json
else:
raise Exception(json['error'])
except:
raise Exception(sys.exc_info()[0])
def edit(self, key, value):
"""Replace value from a key with a new value.
Keywords arguments:
key -- a string, the key to update the value of
value -- a string, the new value for the key
"""
url = BASE_URL + '/account/edit/{0}/{1}'.format(key, value)
url += '?session={0}'.format(self.session)
try:
request = requests.get(url)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == u'':
return json
else:
raise Exception(json['error'])
except:
raise Exception(sys.exc_info()[0])
def files(self):
"""Return a dictionnary with the files belonging to the account."""
url = BASE_URL + '/account/files'
url += '?session={0}'.format(self.session)
try:
request = requests.get(url)
if not request.ok:
request.raise_for_status()
json = request.json()
if json['error'] == u'':
return json
else:
raise Exception(json['error'])
except:
raise Exception(sys.exc_info()[0])