Source

cloudster / api / storages / adapters / box / adapter.py

__author__ = 'guillermo'

from api.storages.adapters.box import events
from api.storages.clients.box import session, client
from api.storages.adapters import skeleton
from api.shelf.registry.metadata import ClientRegistryMetadata

from api.storages.adapters import elements

class BoxClient(skeleton.StorageAdapter):

	@staticmethod
	def registry_metadata():

		metadata = ClientRegistryMetadata('box', BoxAccountData)

		return metadata

	def __init__(self, account_data):

		skeleton.StorageAdapter.__init__(self)

		self.__account_data = account_data

	def obtainAccessToken(self, sess):

		auth_page = sess.get_authorization_page()

		print 'You should redirect user to ' + auth_page

		raw_input()

		return sess.get_auth_token()

	def connect(self):

		boxSession = session.BoxSession(self.__account_data.appKey())

		if not self.__account_data.isAccessGranted():
			self.__account_data.assignAccessToken(self.obtainAccessToken(boxSession))
		else:
			boxSession.set_auth_token(self.__account_data.oauthTokenSecret())

		self._client = client.BoxClient(boxSession)

	def write(self, target_full_path, source_file, overwrite=True):
		self._client.upload(target_full_path, source_file)

	def read(self, full_remote_path, target_file_path=None):

		remote_file = self._client.download(full_remote_path)

		if target_file_path is not None:

			f = open(target_file_path,'wb')

			meta = remote_file.info()
			file_size = int(meta.getheaders("Content-Length")[0])

			print "Downloading: %s Bytes: %s" % (target_file_path, file_size)

			file_size_dl = 0
			block_sz = 1024*1024

			while True:
				buffer = remote_file.read(block_sz)

				if not buffer:
					break

				file_size_dl += len(buffer)
				f.write(buffer)

				status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
				status += chr(8)*(len(status)+1)

				print status

			f.close()
		else:
			return remote_file

	def list(self, full_element_path):
		remote_info = self._client.get_metadata(full_element_path)

		content = []

		if remote_info['type'] == client.BoxClient.ELEMENT_TYPE_FOLDER:
			for item in remote_info['item_collection']['entries']:
				if item['type'] == client.BoxClient.ELEMENT_TYPE_FOLDER:
					content.append(elements.StorageFolder(remote_info['name'], None, remote_info['id']))
				elif item['type'] == client.BoxClient.ELEMENT_TYPE_FILE:
					content.append(elements.StorageFile(remote_info['name'],None,remote_info['id']))
		else:
			content.append(elements.StorageFile(remote_info['path'],remote_info['modified_at'],remote_info['id']))

		return content

	def remove(self, full_path):
		self._client.delete(full_path)

	def events(self, history_pointer=client.BoxClient.DEFAULT_STREAM_POSITION):
		iterator = events.BoxEventsIterator(self._client, history_pointer)
		translator = events.BoxEventTranslator()

		return events.BoxEventsBrowser(iterator, translator)


class BoxAccountData(skeleton.StorageAccountData):

	def __init__(self, account_data):

		skeleton.StorageAccountData.__init__(self)

		parsed_data = skeleton.StorageAccountData.parse(self, account_data)

		self._appKey = parsed_data["appKey"]
		self._oauth_token = None
		self._oauth_token_secret = None

		if "OAuthToken" in parsed_data:
			self._oauth_token = parsed_data["OAuthToken"]

		if "OAuthTokenSecret" in parsed_data:
			self._oauth_token_secret = parsed_data["OAuthTokenSecret"]

	@skeleton.account_field('box','appKey', 'Application key', skeleton.AccountFieldDescriptor.FIELD_TYPE_STRING)
	def appKey(self):
		return self._appKey

	def assignAccessToken(self, access_token):
		self._oauth_token = access_token.key
		self._oauth_token_secret = access_token.secret

	@skeleton.account_field('box','OAuthToken', 'OAuth application token', skeleton.AccountFieldDescriptor.FIELD_TYPE_STRING)
	def oauthToken(self):
		return self._oauth_token

	def oauthTokenSecret(self):
		return self._oauth_token_secret

	def isAccessGranted(self):
		return self._oauth_token_secret is not None and self._oauth_token is not None

	@staticmethod
	def get_configuration_fields():
		return skeleton.StorageAccountData._list_account_field('box')

	@staticmethod
	def create_descriptor(properties=None,interactiveMode=False):
		print 'Interactive creation ....'

	def jsonize(self):
		return dict({'appKey': self._appKey, 'OAuthToken' : self._oauth_token, 'OAuthTokenSecret': self._oauth_token_secret})