#!/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)