Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented better aligment in sfs list CHOICE #2 #10

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sfs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Usage:
sfs download_all <target_directory>
sfs download <target_directory> <snap_id> ...
sfs upload <file> ...
sfs delete <snap_id> ...
sfs (-h | --help)
sfs (-v | --version)

Expand Down Expand Up @@ -139,6 +140,9 @@ def cli(arguments):
if arguments['upload']:
for filename in arguments['<file>']:
upload_sfs_file(session, filename)
if arguments['delete']:
for id in arguments['<snap_id>']:
delete_sfs_file(session, id)

def main():
global SETTINGS
Expand Down
51 changes: 50 additions & 1 deletion snapchat_core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import constants
from friend import Friend
from snaps import Snap, SentSnap, ReceivedSnap
import json

__author__ = "Alex Clemmer, Chad Brubaker"
__copyright__ = "Copyright 2013, Alex Clemmer and Chad Brubaker"
Expand All @@ -28,7 +29,9 @@
CLIENT_ID = 'id'
COUNTRY_CODE = 'country_code'
DISPLAY = 'display'
EVENTS = 'events'
FRIENDS = 'friends'
JSON = 'json'
MEDIA_ID = 'media_id'
NAME = 'name'
PASSWORD = 'password'
Expand Down Expand Up @@ -141,6 +144,52 @@ def send_image_to(self, recipient, media_id, time = 10
result = SnapchatSession._post_or_fail(constants.SEND_RESOURCE
, params)

# Thank you very much to gibsonsec for their API docs[1]
# and thank you to php-snapchat[2] for their reference implementation
# [1] http://gibsonsec.org/snapchat/fulldisclosure/#sending-updates-bqupdate_snaps
# [2] https://github.com/dstelljes/php-snapchat/blob/master/src/snapchat.php#L750
def delete_image(self, snap_id):
"""
Deletes an image from Snapchat
@snap_id The ID of the snap to be deleted
"""
# time.time() is the number of seconds since epoch represented as a float:
# <seconds since epoch>.<fractions of seconds>
snap_info = {
snap_id: {
't' : int(time.time())
, 'c' : 0
, 'replayed' : 0
}
}
# Say we viewed the snap 10 seconds ago and it expired just now,
# i.e., we viewed the snap for 10 seconds
event_one = {
'mEventName' : 'SNAP_VIEW'
, 'mTimestamp' : int(time.time())-10
, 'mParams' : {'id': snap_id}
}
event_two = {
'mEventName' : 'SNAP_EXPIRED'
, 'mTimestamp' : int(time.time())
, 'mParams' : {'id': snap_id}
}

events = [event_one, event_two]
timestamp = SnapchatSession._generate_timestamp()
# We must use json.dumps() because the API take strings as values,
# not JSON dicts
req_params = {
EVENTS : json.dumps(events)
, JSON : json.dumps(snap_info)
, TIMESTAMP : timestamp
, USERNAME : self.username
, REQ_TOKEN : SnapchatSession._generate_req_token(
self.session_token, timestamp)
}
result = SnapchatSession._post_or_fail(constants.UPDATE_SNAPS_RESOURCE
, req_params)

def get_snaps(self, filter_func=lambda snap: True):
"""
Returns array of Snaps sent to current user, represented as a list
Expand Down Expand Up @@ -235,7 +284,7 @@ def _post_or_fail(resource, request_params, files=None):
the POST request. Formatted like: {'data': ('file', data)}
"""
uri = "%s%s" % (constants.ROOT_URL, resource)
result = requests.post(uri, request_params, files = files)
result = requests.post(uri, request_params, files = files, verify=True)
if result.status_code != 200:
raise Exception("POST request failed with status code %d" %
(result.status_code))
Expand Down
1 change: 1 addition & 0 deletions snapchat_core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
SEND_RESOURCE = "/bq/send"
UPLOAD_RESOURCE = "/bq/upload"
BLOB_RESOURCE = "/bq/blob"
UPDATE_SNAPS_RESOURCE = "/bq/update_snaps"

# we pass this token to the service to "authenticate" that we're supposed
# to be able to log in
Expand Down
2 changes: 1 addition & 1 deletion snapchat_fs/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from snapchatfs import list_all_downloadable_sfs_files, download_all_sfs, download_by_id, upload_sfs_file
from snapchatfs import list_all_downloadable_sfs_files, download_all_sfs, download_by_id, upload_sfs_file, delete_sfs_file
29 changes: 26 additions & 3 deletions snapchat_fs/snapchatfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,23 @@ def list_all_downloadable_sfs_files(session):
"""
files = all_downloadable_sfs_files(session)

print '\t'.join([util.bold('Filename'), util.bold('Content hash'), util.bold('Snap ID')])
max_filename_len = 0
# Apparently snap IDs can have different lengths
max_id_len = 0
for filename, _, _, snap in files:
max_filename_len = max(max_filename_len, len(filename))
max_id_len = max(max_id_len, len(snap.id))
# Center the headers
print util.bold('{:^{width}} ').format('Filename'
, width=max_filename_len) +\
util.bold('{:^{width}} ').format('Content hash'
, width=23) +\
util.bold('{:^{width}} ').format('Snap ID'
, width=max_id_len)
for filename, content_hash, received_id, snap in files:
print '%s\t%s...%s\t%s' % (filename, content_hash[:17]
, content_hash[-3:], snap.id)
print '{:<{f_width}} {}...{} {}'.format(filename, content_hash[:17]
, content_hash[-3:], snap.id
, f_width=max_filename_len)

def upload_sfs_file(session, filename):
"""
Expand All @@ -167,3 +180,13 @@ def upload_sfs_file(session, filename):
sfs_id = session.generate_sfs_id(basename, data)
session.upload_image(data, sfs_id)
session.send_image_to(session.username, sfs_id)

def delete_sfs_file(session, snap_id):
"""
Deletes a file from Snapchat FS.

@session An SfsSession object that has been logged in.
@snap_id The ID of the snap to delete
"""
session.delete_image(snap_id)
print util.green('Deleted file with ID ') + (snap_id)