-
Notifications
You must be signed in to change notification settings - Fork 35
/
sfs
executable file
·155 lines (134 loc) · 5.02 KB
/
sfs
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
#!/usr/bin/env python
"""Snapchat FS
Usage:
sfs list
sfs download_all <target_directory>
sfs download <target_directory> <snap_id> ...
sfs upload <file> ...
sfs (-h | --help)
sfs (-v | --version)
Options:
-h --help Show this screen
-v --version Show the version
"""
from docopt import docopt
import os, getpass, sys
from snapchat_core import constants, SfsSession
from snapchat_fs import *
__author__ = "Alex Clemmer, Chad Brubaker"
__copyright__ = "Copyright 2013, Alex Clemmer and Chad Brubaker"
__credits__ = ["Alex Clemmer", "Chad Brubaker"]
__license__ = "MIT"
__version__ = "0.1"
__maintainer__ = "Alex Clemmer"
__email__ = "[email protected]"
__status__ = "Prototype"
# SETTINGS CONSTANTS -- possible settings found in config file ~/.snapchat_fs
USERNAME = 'USERNAME'
PASSWORD = 'PASSWORD'
# SETTINGS DICTIONARY -- stores defaults found in ~/.snapchat_fs
# contains dummy entries for every possible setting so that we can
# validate whether a setting found in config file is valid based on
# whether it appears in this dictionary
SETTINGS = {
USERNAME: ""
, PASSWORD: ""
}
def initialize_user():
"""
Initializes user if we can't find the config file (which is
~/.snapchat_fs).
This usually involves asking for username and password, building the
config file, and writing these values to the file.
"""
# Welcome message
print "Looks like you haven't used Snapchat FS before."
print "We're going to ask for a username and a password; you can"
print "change these later by messing with the file %s" % \
constants.CONFIG_FILE_PATH
# get username/password
print "Please enter a username:"
username = raw_input()
print "Please enter your password (NOTE: STORED IN PLAINTEXT):"
password = getpass.getpass('')
# Try logging in first before we continue
ss = SfsSession(username, password)
ss.login()
# write username/password to file
with open(constants.CONFIG_FILE_PATH, 'w') as w:
# Store the username in lowercase for consistency.
# Snapchat is case-insensitive with both usernames and emails.
w.write("USERNAME=%s\n" % username.lower())
w.write("PASSWORD=%s\n" % password)
def init_settings_from_config_file():
"""
Create settings dictionary mapping attribute -> value. Contains, e.g.,
username and password.
The attributes are a list of constants at the top of the file, e.g.,
`USERNAME` and `PASSWORD`.
@return Settings dictionary.
"""
# create config file with username/password if it doesn't exist
if not os.path.exists(constants.CONFIG_FILE_PATH):
# can fail and raise a login exception, caught by main()
initialize_user()
# open config file, populate settings dictionary with fields we find
with open(constants.CONFIG_FILE_PATH) as f:
for line in f.readlines():
split_line = line.split("=")
if len(split_line) != 2:
raise Exception("\033[1;31mMalformed line in config file %s\033[0m" \
% line)
field = split_line[0].strip()
value = split_line[1].strip()
# validate that dummy entry exists; if it doesn't, then it's
# not a valid setting
if field in SETTINGS:
SETTINGS[field] = value
else:
raise Exception(
"\033[1;31mUnknown setting in config file %s\033[0m" \
% constants.CONFIG_FILE_PATH)
if SETTINGS[USERNAME] == '' or SETTINGS[PASSWORD] == '':
print "\033[1;31mUsername or password missing from config file %s\033[0m" \
% constants.CONFIG_FILE_PATH
return SETTINGS
def create_dir_if_not_exists(directory):
"""
Simple utility function creates a directory if it doesn't exist.
"""
if not os.path.exists(directory):
os.makedirs(directory)
def cli(arguments):
"""
Processes command line args for Snapchat FS
@arguments Arguments dictionary obtained from docopt the library.
"""
session = SfsSession(SETTINGS[USERNAME], SETTINGS[PASSWORD])
session.login()
if arguments['list']:
list_all_downloadable_sfs_files(session)
if arguments['download_all']:
directory = arguments['<target_directory>']
create_dir_if_not_exists(directory)
download_all_sfs(session, directory)
if arguments['download']:
directory = arguments['<target_directory>']
snap_ids = arguments['<snap_id>']
create_dir_if_not_exists(directory)
download_by_id(session, directory, snap_ids)
if arguments['upload']:
for filename in arguments['<file>']:
upload_sfs_file(session, filename)
def main():
global SETTINGS
try:
init_settings_from_config_file()
arguments = docopt(__doc__, version=constants.VERSION)
cli(arguments)
except Exception as e:
print util.red("Error:"),
print e
exit()
if __name__ == '__main__':
main()