Source

cloudster / api / shelf / console / shell.py

Full commit
Guillermo Szelig… daf20da 


Guillermo Szelig… 5951b8d 
Guillermo Szelig… daf20da 
Guillermo Szelig… 6af9684 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… daf20da 


Guillermo Szelig… 5951b8d 

Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 

Guillermo Szelig… daf20da 
Guillermo Szelig… e2e590e 


Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 

Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… daf20da 


Guillermo Szelig… e2e590e 


Guillermo Szelig… daf20da 
Guillermo Szelig… e2e590e 



Guillermo Szelig… 0e5abe4 
Guillermo Szelig… daf20da 

Guillermo Szelig… e2e590e 

Guillermo Szelig… daf20da 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 0e5abe4 
Guillermo Szelig… daf20da 
Guillermo Szelig… e2e590e 

Guillermo Szelig… daf20da 

Guillermo Szelig… e2e590e 
Guillermo Szelig… daf20da 
Guillermo Szelig… e2e590e 

Guillermo Szelig… daf20da 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 0e5abe4 




















Guillermo Szelig… e2e590e 
Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 155e725 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 155e725 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 155e725 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 0e5abe4 
Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 313e7f5 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 
Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 277c4b1 
Guillermo Szelig… e2e590e 
Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 

Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 

Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 
Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 0e5abe4 
Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 
Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 

Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 

Guillermo Szelig… cf1fe10 
Guillermo Szelig… e2e590e 



Guillermo Szelig… 277c4b1 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 


Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 

Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 



Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 


Guillermo Szelig… 6af9684 
Guillermo Szelig… e2e590e 


Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 
Guillermo Szelig… 5951b8d 
Guillermo Szelig… e2e590e 












































Guillermo Szelig… 0e5abe4 









Guillermo Szelig… e2e590e 









Guillermo Szelig… daf20da 


Guillermo Szelig… e2e590e 

Guillermo Szelig… daf20da 


Guillermo Szelig… e2e590e 
#reference: http://www.doughellmann.com/PyMOTW/cmd/

import cmd

from functools import wraps
from api.shelf.configuration.accounts import AccountsManager
from api.shelf.registry.clients import StorageClientsRegistry

__author__ = 'guillermo'

#http://alex.kavanagh.name/2011/05/exploring-python-decorators/
#http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/
def single_client_command(f):
  @wraps(f)
  def wrapped(*args,**kwds):
#
#     for arg in args:
#       print "another arg:", dir(arg)

    if args[0]._CloudsterShell__client_class is None:
      print 'Non client has been selected'
      return

    return f(*args,**kwds)

  return wrapped

def global_command(requires_session=False):
  pass


class CloudsterShell(cmd.Cmd):

  #doc_header = 'doc_header'
  #misc_header = 'misc_header'
  #undoc_header = 'undoc_header'

  __default_prompt = 'cloudster'
  __prompt_delimiter = '>'
  __registry = StorageClientsRegistry()
  __client_class = None
  __client_instance = None


  prompt = __default_prompt + __prompt_delimiter
  intro = "\nCloudster administration console\n"

  CMD_REGISTRY_OPTIONS = ['list', 'use', 'dismiss']
  CMD_ACCOUNT_OPTIONS = ['connect', 'create', 'list', 'delete']
  CMD_STORAGE_OPTIONS = ['join-up']

  def __init__(self):
    cmd.Cmd.__init__(self)


  def do_EOF(self, line):

    print '\nBye!'
    return True

  @single_client_command
  def do_storage(self, operation):

    operation_parts = operation.rsplit(" ")

    if operation_parts[0] == 'join-up':

      #account tangle /LinuxJournal/201101.pdf /home/guillermo/cloudster/201101.pdf

      #1- We should be able to tangle a source dir to a target dir
      #2- We should be able to tangle a file to a target folder (and build the remaining path)

      remote_path = operation_parts[1]
      local_path = operation_parts[2] 

      if self.__client_instance is not None:
        self.__client_instance.read(remote_path,local_path)
      else:
        print 'Not session found'


  @single_client_command
  def do_account(self, operation):

    account_manager = AccountsManager(self.__client_class)

    operation_parts = operation.rsplit(" ")

    if operation_parts[0] == 'create':
      account_fields_descriptor = account_manager.get_configuration_descriptor()

      #1- Asks for all values
      field_values = {}

      for field in account_fields_descriptor:
        value=raw_input(">> " + field.label() + ": ")

        field_values[field.name()]=value

      #2- Creates new account data
      account_data = account_manager.create(field_values)

      #3- If account needs authorization
      self.__client_instance,account_data = account_manager.authorize(account_data)

      #4- Save data into a file
      account_manager.save(account_data)

      print 'Account created successfully'

    elif operation_parts[0] == 'connect':

      #TODO We need to check whether the account is already connected 

      account_unique_id = None

      if len(operation_parts) > 1:
        account_unique_id = operation_parts[1]

      if account_unique_id is None:
        account_unique_id=raw_input(">> Account name: ")

      if account_unique_id is not None and len(account_unique_id) > 0:

        try:
          account_data = account_manager.load(account_unique_id)
          self.__client_instance = account_manager.connect(account_data)

          print 'Account \'%s\' successfully connected' % account_unique_id

        except RuntimeError, e:
          print 'Account information could not be loaded. Reason: %s' % e

      else:
        print 'Account id cannot be empty'

    elif operation_parts[0] == 'list':
      
      for defined_account in account_manager.list():
        print defined_account

    elif operation_parts[0] == 'delete':

      # 1- Confirm whether we have to delete or not the account
      # 2- Disconnect all related files to the account
      # 3- Remove the account file

      account_unique_id = None

      if len(operation_parts) == 2:

        account_unique_id = operation_parts[1]

        if account_unique_id is not None and account_manager.exists(account_unique_id):

          confirmed = ""

          while confirmed is "":

            confirmed = raw_input("Are you sure you want to remove account '%s'? (y/n)" % account_unique_id);

          if confirmed.lower() == 'y':
            account_manager.delete(account_unique_id)

        else:

          print "Account with id '%s' does not exist" % account_unique_id

      else:
        print 'The account unique id was not specified'

      
  @single_client_command
  def do_disconnect(self, operation):
    print 'Connecting....'

  @global_command
  def do_start(self, operation):
    print 'Starting cloudster.....'

  @global_command
  def do_shutdown(self, operation):
    print 'Shuting down cloudster.....'

  def do_client(self, operation):

    operation_parts = operation.rsplit(" ")

    if operation_parts[0] == 'list':

      for storage_client in self.__registry.get_available():
        print storage_client.registry_metadata()

    elif operation_parts[0] == 'use':

      if len(operation_parts) > 1:

        client_id = operation_parts[1]

        try:
          self.__client_class = self.__registry.get_by_id(client_id)
          self.__update_prompt()
        except KeyError:
          print "Client id '%s' couldn't be found" % client_id
      else:
        print 'Client id is missing'

    elif operation_parts[0] == 'dismiss':

      #TODO Close session
      self.__client_class = None
      self.__update_prompt()

  def complete_client(self, text, line, begidx, endidx):
    if not text:
      completions = self.CMD_REGISTRY_OPTIONS[:]
    else:
      completions = [ f
              for f in self.CMD_REGISTRY_OPTIONS
              if f.startswith(text)
      ]
    return completions

  def complete_account(self, text, line, begidx, endidx):
    if not text:
      completions = self.CMD_ACCOUNT_OPTIONS[:]
    else:
      completions = [ f
              for f in self.CMD_ACCOUNT_OPTIONS
              if f.startswith(text)
      ]
    return completions

  def complete_storage(self, text, line, begidx, endidx):
    if not text:
      completions = self.CMD_STORAGE_OPTIONS[:]
    else:
      completions = [ f
              for f in self.CMD_STORAGE_OPTIONS
              if f.startswith(text)
      ]
    return completions

  def __update_prompt(self):

    prompt_string = None

    if self.__client_class is not None:
      prompt_string = self.__default_prompt + '@' + self.__client_class.registry_metadata().unique_id() + self.__prompt_delimiter
    else:
      prompt_string = self.__default_prompt + self.__prompt_delimiter

    self.prompt = prompt_string

def main():

  shell = CloudsterShell()
  shell.cmdloop()


if __name__ == "__main__":
  main()