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 | #!/usr/bin/env python
# 2013-02-20 johnpfeiffer
import o2lib
import sys
import time # TODO: python -mtimeit
import Queue
import collections
# Named tuples assign meaning to each position in a tuple and allow for more readable, self-documenting code.
# They can be used wherever regular tuples are used, and they add the ability to access fields by name instead of position index.
# Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.
class ExampleNamedTuple:
def some_method( self ):
# Create a new sub-tuple named Credential
Credential = collections.namedtuple( 'Credential' , 'username, password' )
credential = Credential( username = 'myuser' , password = 'mypass' )
print 'Username:' , credential.username
print 'Password:' , credential.password
class AccountTreeSetup:
agent = None
start_time = time.time() # performance benchmarking
MAX_FOLDER_COUNT = 5
MAX_FOLDERS_PER_CONTAINER = 2
def __init__( self , app_name , api_url , api_key , user , password ):
self.agent = o2lib.OxygenAdapter( api_key , app_name , api_url )
user_login = self.agent.request_login_url()
self.agent.login_regular_user( user_login.tokenId , user , password ) # throws an Exception if there's a problem
self.agent.validate_login( user_login.tokenId ) # throws an Exception if there's a problem
print 'login in %.3f seconds' % ( time.time() - self.start_time )
def search_container( self , listing , unsearched , target_name , type = None ):
result = None
for current in listing: # search the root level and seed future searches
if current.name == target_name:
if not type: # search does not care about type
result = current
elif type == current.type: # search requires a type match
result = current
else:
if current.type == o2lib.ApiObjectType.SPACE or current.type == o2lib.ApiObjectType.FOLDER:
unsearched.put( current )
else:
if current.type == o2lib.ApiObjectType.SPACE or current.type == o2lib.ApiObjectType.FOLDER:
unsearched.put( current ) # seed future searches
return result , unsearched
def get_by_name( self , target_name , type = None ):
""" returns the first item found which has the matching name, optional filter by type, BFS all items from root"""
result = None
unsearched = Queue.Queue()
listing = self.agent.getChildObjects( None ) #TODO: short circuit if found in initial root search
( result , unsearched ) = self.search_container( listing , unsearched , target_name , type )
while not result and not unsearched.empty(): # while it's not found and there's more to search...
current_container = unsearched.get()
listing = self.agent.getChildObjects( current_container )
( result , unsearched ) = self.search_container( listing , unsearched , target_name , type )
print 'found in %.3f seconds' % ( time.time() - self.start_time )
return result
def create_subtree( self , parent_object ):
""" if it receives None creates them at the user's root (i.e. current user's User Volume) """
total_folder_count = 0
expansion_list = Queue.Queue()
expansion_list.put( parent_object ) # initial seeding
while total_folder_count < self.MAX_FOLDER_COUNT: # completion condition
current_container = expansion_list.get()
#seed the current level
current_container_folder_count = 0
while total_folder_count < self.MAX_FOLDER_COUNT and current_container_folder_count < self.MAX_FOLDERS_PER_CONTAINER:
self.agent.create_folder_object( current_container , str( current_container_folder_count ) )
total_folder_count = total_folder_count + 1 # progress to completion
current_container_folder_count = current_container_folder_count + 1
# prepare for future expansion
listing = self.agent.getChildObjects( current_container ) # should contain the two new folders
for item in listing:
if item.type == o2lib.ApiObjectType.SPACE or item.type == o2lib.ApiObjectType.FOLDER:
expansion_list.put( item )
print 'created %s folders' % total_folder_count
# MAIN ################################################################
def main():
CORRECTUSAGE = 'python account_tree_setup.py app_name https://API.URL apikey user password'
if len( sys.argv ) != 6:
print 'ERROR: incorrect number of arguments, correct usage: %s' % CORRECTUSAGE
sys.exit( 1 )
app_name = sys.argv[1]
api_url = sys.argv[2]
api_key = sys.argv[3]
user = sys.argv[4]
password = sys.argv[5]
print 'app_name = %s , api_url = %s , api_key = %s , user = %s , password = %s' % ( app_name , api_url , api_key , user , password )
oxygen_initialize = AccountTreeSetup( app_name , api_url , api_key , user , password )
try:
result = oxygen_initialize.get_by_name( 'testroot' , o2lib.ApiObjectType.FOLDER )
print 'found %s ' % result
oxygen_initialize.create_subtree( result )
print 'done'
except o2lib.ApiInvalidInputException as error:
sys.stderr.write( 'ERROR: %s ' % str( error ) )
error_detail = o2lib.ApiInvalidInputErrorCode._VALUES_TO_NAMES[ error.errorCode ]
sys.stderr.write( 'REASON: %s ' % str( error_detail ) )
except o2lib.ApiSystemsException as error:
sys.stderr.write( 'ERROR: %s ' % str( error ) )
error_detail = o2lib.ApiSystemsErrorCode._VALUES_TO_NAMES[ error.errorCode ]
sys.stderr.write( 'REASON: %s ' % str( error_detail ) )
except o2lib.ApiUnexpectedException as error:
sys.stderr.write( 'ERROR: %s \n' % str( error ) )
raise
if __name__ == "__main__":
main()
|