-
Notifications
You must be signed in to change notification settings - Fork 3
/
gett.py
executable file
·271 lines (237 loc) · 10.2 KB
/
gett.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
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
265
266
267
268
269
270
271
#!/usr/bin/env python
# coding: utf-8
"""
gettup - A command-line file sharing utility for ge.tt
usage:
$ gett > show help
$ gett file1 file2 file3 > upload files (in same share)
$ gett *.py > linux globs (upload)
$ gett *.py -p > parallelize uploads
$ gett *.py -z > zips the files and uploads
$ gett *.py -s sharename > upload file in the specific share
$ gett *.py -s sharename -t title > gives the title to the new share
$ gett --list > show list of shares
$ gett -d share1 share2 share3 > deletes the shares
$ gett -r url1 url2 url 3 > deletes the file url
$ gett -q {etc} > quiet mode
$ gett -i sharename > get share info
"""
import requests
import json
import sys
import argparse
import os
import signal
# GETT URLS
LOGIN_URL = "http://open.ge.tt/1/users/login"
SHARE_URL = "http://open.ge.tt/1/shares/create?accesstoken="
VERBOSE = True
def signal_handler(signal, frame):
""" graceful exit on keyboard interrupt """
sys.exit(0)
def logg(msg):
""" print to screen based on VERBOSE toggling """
if VERBOSE: print msg
def refresh_access_token():
""" re-fetches fresh access tokens using the refresh token and writes to the config file """
logg("Updating expired tokens ...")
refreshtoken = read_config('refreshtoken')
r = requests.post(LOGIN_URL, data=json.dumps({'refreshtoken': refreshtoken }))
if r.status_code != 200:
print "Error: Cannot fetch tokens. Try deleting the ~/.gett.cfg file and re-trying"
sys.exit(0)
accesstoken, refreshtoken = r.json().get('accesstoken'), r.json().get('refreshtoken')
write_config({'accesstoken': accesstoken, 'refreshtoken': refreshtoken})
def get_shares():
""" gets the list of all shares using an accesstoken and prints on screen """
accesstoken = get_access_token()
logg("Fetching shares ...")
get_share_url = "http://open.ge.tt/1/shares?accesstoken=" + accesstoken
r = requests.get(get_share_url)
shares = r.json()
if r.status_code != 200:
refresh_access_token()
return get_shares()
if not shares:
print "You don't have any shares. Create a new share by uploading a file"
else:
for shr in shares:
print "%d file(s) in share: %s (%s)" % \
(len(shr['files']), shr['sharename'], shr['getturl'])
def get_share_info(sharename):
""" retrives the information of files stored in a specific share """
logg("Fetching share info ...")
get_share_url = "http://open.ge.tt/1/shares/" + sharename
r = requests.get(get_share_url)
share_info = r.json()
if r.status_code != 200:
print "Error: Share not found"
return
print "Share: %s | gett url: %s | total files: %d" % (sharename, share_info['getturl'], len(share_info['files']))
for f in share_info['files']:
print f['getturl'], humanize(f['size']), f['filename']
def delete_file(sharename, fileid):
""" deletes a file in a specific share and a fileId """
logg("Deleting file ...")
accesstoken = get_access_token()
destroy_url = "http://open.ge.tt/1/files/%s/%s/destroy?accesstoken=%s" % \
(sharename, fileid, accesstoken)
r = requests.post(destroy_url)
if r.status_code != 200:
refresh_access_token()
return delete_file(sharename, fileid)
print "File has been successfully destroyed"
def delete_url(url):
""" deletes the file corresponding to the URL """
fields = url.split('/')
if len(fields) != 6:
print "Error: Invalid url format"
return
delete_file(fields[3], fields[-1])
def create_share(title=None):
""" creates a new share with an optional title and returns the share id """
accesstoken = get_access_token()
logg("Constructing a new share ...")
if title:
r = requests.post(SHARE_URL + accesstoken, data=json.dumps({'title': title}))
else:
r = requests.post(SHARE_URL + accesstoken)
if r.status_code != 200:
refresh_access_token()
return create_share()
return r.json().get('sharename')
def destroy_share(sharename):
logg("Destroying share ...")
accesstoken = get_access_token()
url = "http://open.ge.tt/1/shares/%s/destroy?accesstoken=%s" % (sharename, accesstoken)
r = requests.post(url)
if r.status_code == 200:
print "%s share has been destroyed" % sharename
elif r.status_code == 403:
print "%s share doesn't belong to authenticated user" % sharename
else:
refresh_access_token()
return destroy_share(sharename)
def upload_file(sharename, filename):
""" upload a file in share with the sharename """
accesstoken = get_access_token()
file_url = "http://open.ge.tt/1/files/%s/create?accesstoken=%s" % (sharename, accesstoken)
logg("Setting up a file name ...")
r = requests.post(file_url, data=json.dumps({"filename": filename }))
if r.status_code != 200:
refresh_access_token()
return upload_file(sharename, filename)
gett_url = r.json().get('getturl')
post_upload_url = r.json()['upload']['posturl']
logg("Uploading the file...")
r = requests.post(post_upload_url, files={'file': open(filename, 'rb')})
if r.status_code == 200:
print "Upload successful. Here's your url: %s" % gett_url
else:
print "Error: " + r.json().get('error')
def config_file():
""" returns the location (~/.gett.cfg) of the config file in user's home dir """
home = os.getenv('USERPROFILE') or os.getenv('HOME')
return os.path.join(home, '.gett.cfg')
def read_config(token):
""" reads token values from the configuration file """
file_location = config_file()
if sys.version_info[0] == 3:
import configparser as cp
else:
import ConfigParser as cp
config = cp.RawConfigParser()
if not config.read(file_location) or not config.has_section('TOKENS') \
or not config.has_option('TOKENS', token):
return None
return config.get('TOKENS', token)
def write_config(fields):
""" writes a set of fields into the config file """
if sys.version_info[0] == 3:
import configparser as cp
else:
import ConfigParser as cp
config = cp.RawConfigParser()
config.add_section("TOKENS")
for k in fields:
config.set("TOKENS", k, fields[k])
file_location = config_file()
with open(file_location, 'wb') as configfile:
config.write(configfile)
def bulk_upload(files, sharename=None, title=None):
""" wrapper for uploading more than one files into a share(with optional title) """
sharename = sharename or create_share(title)
for f in files:
print "Uploading file: " + f
upload_file(sharename, f)
logg("----------------------------------------")
def setup_tokens():
""" fetch fresh tokens using user's credentials """
email = raw_input("Please enter your Ge.tt email: ").strip()
password = raw_input("Please enter your Ge.tt password: ").strip()
apikey = raw_input("Please enter your API KEY: ").strip()
logg("Validating credentials ...")
r = requests.post(LOGIN_URL, data=json.dumps({'email': email, 'password': password,
'apikey': apikey}))
accesstoken, refreshtoken = r.json().get('accesstoken'), r.json().get('refreshtoken')
if not accesstoken or not refreshtoken:
print "Error! Your credentials failed validation. Exiting program"
sys.exit(0)
logg("Credentials verified ...")
write_config({'accesstoken': accesstoken, 'refreshtoken': refreshtoken})
return accesstoken
def get_access_token():
""" retrieves access token either from the config file or from the user """
return read_config('accesstoken') or setup_tokens()
def humanize(nbytes):
""" returns the file size in human readable format """
for (exp, unit) in ((9, 'GB'), (6, 'MB'), (3, 'KB'), (0, 'B')):
if nbytes >= 10**exp:
break
return "%.2f %s" % (float(nbytes)/10**exp, unit)
def main():
""" ENTRY METHOD """
signal.signal(signal.SIGINT, signal_handler)
parser = argparse.ArgumentParser(description="Upload files to ge.tt via the command line",
epilog="For more information, examples & source code visit http://github.com/prakhar1989/gettup")
# FILE UPLOADS
file_uploads = parser.add_argument_group("File Uploads")
file_uploads.add_argument("files", metavar="files", nargs="*",
help="list of files you want to upload")
file_uploads.add_argument("-s", "--share", metavar="share_id",
help="upload files to a particular share")
file_uploads.add_argument("-t", "--title", metavar='share_title',
help='title for the new share')
# SHARE RELATED COMMANDS
share_group = parser.add_argument_group('Share Related')
share_group.add_argument("-i", '--info', metavar="share_id",
help="get info for a specific share")
share_group.add_argument('-d', '--delete', metavar="share_id", nargs="+",
help="delete a share & all files in it")
share_group.add_argument('-l', '--list', action="store_true",
help="Lists all shares in your account")
share_group.add_argument('-r', '--remove', metavar="file_url", nargs="+",
help="Delete a list of files with associated urls")
# MISC COMMANDS
misc_group = parser.add_argument_group('Other actions')
misc_group.add_argument('-q', '--quiet', action="store_true",
help="Toggle verbose off (default is on)")
args = parser.parse_args()
global VERBOSE
VERBOSE = not args.quiet
if args.info:
get_share_info(args.info)
if args.list:
get_shares()
if args.delete:
for sharename in args.delete:
destroy_share(sharename)
if args.remove:
for url in args.remove:
delete_url(url)
if args.files:
bulk_upload(args.files, sharename=args.share, title=args.title)
if len(sys.argv) == 1:
parser.print_help()
if __name__ == "__main__":
main()