cloudster / api / shelf / console / shell.py

#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


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

  CMD_REGISTRY_OPTIONS = ['list', 'use', 'dismiss']
  CMD_ACCOUNT_OPTIONS = ['connect', 'create', 'list', 'delete']

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


  def do_EOF(self, line):

    print '\nBye!'
    return True

  @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
      client,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)
          client = 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 __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()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.