#!/usr/bin/env python
# Box Upload
# This code accepts arguments to upload files.
# WARNING!
# This code does not check SSL certificate validity!
# TODO: Implement certificate validation.
# Get the API key by making a Box application here: http://box.com/developers/services/edit/
api_key = 'replace-with-api-key'
import os
import sys
import urllib
import urllib2
import MultipartPostHandler, cookielib # MultipartPostHandler can be found at: http://pypi.python.org/pypi/MultipartPostHandler2
from xml.dom import minidom
def authenticate(api_key):
xml_ticket = minidom.parseString(urllib.urlopen('https://www.box.com/api/1.0/rest?action=get_ticket&api_key='+api_key).read()) # This grabs the XML authentication ticket that we'll be using to generate the auth_token.
status = xml_ticket.firstChild.childNodes[0].firstChild.data # This gets the ticket status to make sure we actually retrieved a valid ticket.
if status == 'get_ticket_ok': # Did we get a valid ticket? If so, continue. If not, the user needs to check their API key.
ticket = xml_ticket.firstChild.childNodes[1].firstChild.data
print 'Please go to https://www.box.com/api/1.0/auth/'+ticket+' and follow the instructions there. Then, press ENTER or RETURN to continue.'
raw_input()
xml_auth_token = minidom.parseString(urllib.urlopen('https://www.box.net/api/1.0/rest?action=get_auth_token&api_key='+api_key+'&ticket='+ticket).read()) # This is the auth token in XML format.
auth_status = xml_auth_token.firstChild.childNodes[0].firstChild.data # Reads the authentication status into "auth_status"
if auth_status == 'get_auth_token_ok':
auth_token = xml_auth_token.firstChild.childNodes[1].firstChild.data
token_path = os.path.expanduser('~/.box_auth_token')
auth_token_file = open(token_path,'w')
auth_token_file.write(auth_token)
auth_token_file.close()
print 'The authentication token has been saved in the file "'+token_path+'". If you remove this file, you will need to reauthenticate.'
print ''
print 'Please run "boxupload" again to initiate your upload.'
return
elif auth_status == 'not_logged_in':
print "I'm sorry, but you haven't authorized me to connect to your account. Please run \"boxupload\" again to restart the authentication process."
elif auth_status == 'get_auth_token_error':
print "I'm sorry, but there was an error in retrieving your authentication token. Please run \"boxupload\" again to restart the authentication process."
else:
print "Error: "+auth_status+". Try reauthenticating."
else:
print 'Error retrieving ticket! Check your API key.'
def get_account_info(api_key,auth_token):
xml_account_info = minidom.parseString(urllib.urlopen('https://www.box.net/api/1.0/rest?action=get_account_info&api_key='+api_key+'&auth_token='+auth_token).read())
status = xml_account_info.firstChild.childNodes[0].firstChild.data
if status == 'get_account_info_ok':
login = str(xml_account_info.firstChild.childNodes[1].childNodes[0].firstChild.data)
email = str(xml_account_info.firstChild.childNodes[1].childNodes[1].firstChild.data)
access_id = int(xml_account_info.firstChild.childNodes[1].childNodes[2].firstChild.data)
user_id = int(xml_account_info.firstChild.childNodes[1].childNodes[3].firstChild.data)
space_amount = int(xml_account_info.firstChild.childNodes[1].childNodes[4].firstChild.data) # Total capacity of the account in bytes
space_used = int(xml_account_info.firstChild.childNodes[1].childNodes[5].firstChild.data) # Data usage of the account in bytes
max_upload_size = int(xml_account_info.firstChild.childNodes[1].childNodes[6].firstChild.data) # Maximum file upload size in bytes
account_info = [login, email, access_id, user_id, space_amount, space_used, max_upload_size] # Turn the data into a list for easy access
return account_info
elif status == 'not_logged_in':
print "I'm sorry, your authentication token is invalid. Try removing your \"auth_token\" file and reauthenticating."
elif status == 'Wrong input':
print "I'm sorry, the API key you are using is mistyped."
def upload(file,auth_token):
if not os.path.exists(file):
print 'ERROR: File \"'+file+'\" was not found!'
return
url = 'https://upload.box.net/api/1.0/upload/'+auth_token+'/0'
cookies = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), MultipartPostHandler.MultipartPostHandler)
params = { "file" : open(file, "rb") }
xml_response = minidom.parseString(opener.open(url, params).read())
upload_status = xml_response.firstChild.childNodes[0].firstChild.data
if upload_status == 'upload_ok':
print "Upload successful!"
else:
print "Upload failure!"
try: # Check for and read auth_token file
token_path = os.path.expanduser('~/.box_auth_token')
auth_token_file = open(token_path,'r')
auth_token = auth_token_file.read()
pass
except IOError as e:
authenticate(api_key) # If there's no auth_token, initiate authentication.
sys.exit(1)
if len(sys.argv) < 2:
print "usage: "+sys.argv[0]+" file_1 [file_2] [file_3] ... [file_n]"
sys.exit(1)
# account_info = get_account_info(api_key,auth_token)
''' # Uncomment for debugging.
print 'Auth token: ' + auth_token
print 'Max upload size: ' + str((account_info[6])/1024.0/1024) + ' MB'
print 'Total capacity: ' + str((account_info[4])/1024.0/1024) + ' MB | Space used: ' + str((account_info[5])/1024.0/1024) + ' MB | Space remaining: ' + str((account_info[4]-account_info[5])/1024.0/1024) + ' MB | Percent free: ' + str(100.0*(account_info[4]-account_info[5])/account_info[4]) + '%'
'''
arguments = sys.argv
arguments.pop(0)
for argv in arguments:
upload(argv,auth_token)