1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """Interact with FileDropper.com"""
19
20 import os.path, re, urllib, urllib2
21 from types import StringTypes
22
23 from BeautifulSoup import BeautifulSoup
24 import poster.encode, poster.streaminghttp
25
26
27 FD_PERM_PUBLIC = 0
28 FD_PERM_PASSWORD = 1
29 FD_PERM_PRIVATE = 2
30
31
32 FD_URL = "http://www.filedropper.com/"
33 FD_LOGIN_URL = FD_URL + "login.php"
34 FD_PREMIUM_URL = FD_URL + "premium.php"
35 FD_UPLOAD_URL = FD_URL + "index.php?xml=true"
36 FD_PERM_URL = FD_PREMIUM_URL + "?action=setpermissions&%(varset)s&id=%(id)d"
37 FD_DELETE_URL = FD_PREMIUM_URL + "?action=delete&id=%d"
38
39
40 FD_MAX_SIZE = 5*(1024**3)
41
42
43 FD_ERROR_NOT_LOGGED_IN = 1
44 FD_ERROR_PERMISSIONS = 2
45 FD_ERROR_FILE_TOO_BIG = 3
46 FD_ERROR_UPLOAD = 4
47 FD_ERROR_INVALID_PASSWORD = 5
48 FD_ERROR_REQUEST = 6
49
50 FD_ERRORS = {
51 FD_ERROR_NOT_LOGGED_IN : "Not logged in",
52 FD_ERROR_PERMISSIONS : "Invalid permissions",
53 FD_ERROR_FILE_TOO_BIG : "File is too big",
54 FD_ERROR_UPLOAD : "Error while uploading a file",
55 FD_ERROR_INVALID_PASSWORD: "Invalid password",
56 FD_ERROR_REQUEST : "Problem with the request",
57 }
58
59
60 FD_RE_LIST = re.compile("^unhide\('(\d+)'\)")
61
64 self.errno = errno
65 self.errmsg = FD_ERRORS[errno]
66
68 return "[FileDropper error %d] %s" % (self.errno, self.errmsg)
69
71 """Builds an empty FileDropper object that may be used for uploading files
72 to FileDropper.com, get details about files in a premium account, change
73 their permission or delete them."""
74
76 self.logged_in = False
77
78
79
80
81
82
83 self.url = urllib2.build_opener(
84 poster.streaminghttp.StreamingHTTPHandler,
85 poster.streaminghttp.StreamingHTTPRedirectHandler,
86 urllib2.HTTPCookieProcessor
87 )
88
90 if self.logged_in:
91 self.logout()
92
93 - def login(self, username, password):
94 """Log into the premium account with the given username and password."""
95
96
97 data = urllib.urlencode({"username": username, "password": password})
98
99
100 res = self.url.open(FD_LOGIN_URL, data)
101
102
103 dst_url = res.geturl()
104
105 self.logged_in = (res.getcode() == 200) and (dst_url == FD_PREMIUM_URL)
106 return self.logged_in
107
115
117 """Get a list of files in the file manager of a premium account.
118
119 The return value is a list of 7-value tuples of the form
120 (file_name, id, downloads, size, date, permissions, public_url)"""
121
122 if not self.logged_in:
123 raise FileDropperException(FD_ERROR_NOT_LOGGED_IN)
124
125
126 html = self.url.open(FD_PREMIUM_URL).read()
127
128
129 soup = BeautifulSoup(html)
130
131
132 tags = [tag.parent for tag in soup.findAll("a", onclick = FD_RE_LIST)]
133 files = []
134 for tag in tags:
135
136 file_name = tag.a.string.strip()
137
138
139 m = FD_RE_LIST.search(tag.a['onclick'])
140 file_id = int(m.group(1))
141
142 div = tag.div
143
144
145 downloads = int(div.contents[2].replace('|', '').strip())
146 size = div.contents[4].replace('|', '').strip()
147 date = div.contents[6].replace(' ', '').strip()
148
149
150 raw_perm = div.find("span", id="fileperms[%d]" % file_id)
151 permissions = -1
152 if raw_perm.span.string == "Private":
153 permissions = FD_PERM_PRIVATE
154 elif raw_perm.span.string == "Public":
155
156 if raw_perm.b is not None:
157 permissions = FD_PERM_PUBLIC
158 else:
159 permissions = FD_PERM_PASSWORD
160 else:
161 raise FileDropperException(FD_ERROR_PERMISSIONS)
162
163
164 public_url = div.find("input", type="text")['value']
165
166 value = (file_name, file_id, downloads, size, date, permissions, public_url)
167 files.append(value)
168
169 return files
170
172 """Upload the specified file"""
173
174
175 if os.path.getsize(filename) > FD_MAX_SIZE:
176 raise FileDropperException(FD_ERROR_FILE_TOO_BIG)
177
178
179 base_name = os.path.basename(filename)
180
181 mp1 = poster.encode.MultipartParam("Filename", base_name)
182 mp2 = poster.encode.MultipartParam("file", filename=base_name, filetype="application/octet-stream", fileobj=open(filename))
183
184 data, headers = poster.encode.multipart_encode([mp1, mp2])
185
186
187 req = urllib2.Request(FD_UPLOAD_URL, data, headers)
188
189
190 res = self.url.open(req)
191
192
193 tmp_url = res.read()
194
195
196
197 try:
198 res = self.url.open(FD_URL + tmp_url[1:])
199 except urllib2.HTTPError, exc:
200 if exc.code == 404:
201 return exc.geturl()
202 else:
203 raise exc
204
205
206 raise FileDropperException(FD_ERROR_UPLOAD)
207
208 - def set_perm(self, file_id, perm, password=None):
249
264
265
266 if __name__ == "__main__":
267 from getpass import getpass
268 import sys
269
270 fd = FileDropper()
271 user = raw_input("Username: ")
272 if user != "":
273 password = getpass()
274 if not fd.login(user, password):
275 print "Login failed"
276
277 print "Current files:"
278 print fd.list()
279 print
280
281 uploaded_file = fd.upload("test.txt")
282 print "Upload: %s" % uploaded_file
283 print
284
285 print "New files:"
286 lst = fd.list()
287 print lst
288 file_id = -1
289 for file_data in lst:
290 if file_data[6] == uploaded_file:
291 file_id = file_data[1]
292 break
293 if file_id == -1:
294 print "Can't find file ID :-("
295 sys.exit(1)
296 print
297
298 print "Making the file private:"
299 fd.set_perm(file_id, FD_PERM_PRIVATE)
300 print fd.list()
301 print
302
303 print "Making the file password-protected:"
304 fd.set_perm(file_id, FD_PERM_PASSWORD, "passtest")
305 print fd.list()
306 print
307
308 print "Making the file public again:"
309 fd.set_perm(file_id, FD_PERM_PUBLIC)
310 print fd.list()
311 print
312
313 print "Making the file private again:"
314 fd.set_perm(file_id, FD_PERM_PRIVATE)
315 print fd.list()
316 print
317
318 print "Deleting the file:"
319 fd.delete(file_id)
320 print fd.list()
321