325 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python2
 | 
						|
import sys, os
 | 
						|
import ConfigParser
 | 
						|
import requests
 | 
						|
from requests.auth import HTTPBasicAuth
 | 
						|
import  easywebdav
 | 
						|
import easywebdav.__version__ as easywebdavversion
 | 
						|
 | 
						|
__version__= "0.0.2"
 | 
						|
 | 
						|
SERVER = None
 | 
						|
USER = None
 | 
						|
PASSWD = None
 | 
						|
VERIFY_SSL=True
 | 
						|
 | 
						|
#####################################################
 | 
						|
 | 
						|
class CommandNotFound(Exception):
 | 
						|
    pass
 | 
						|
 | 
						|
class ZotSH(object):
 | 
						|
    commands = ['cd','ls','exists','mkdir','mkdirs','rmdir','delete','upload','download',
 | 
						|
                        'host', 'pwd','cat',
 | 
						|
                        'lcd','lpwd', 'lls',
 | 
						|
                        'quit', 'help']
 | 
						|
    def __init__(self, host, session=None, davclient=None):
 | 
						|
        self.sessions = {}
 | 
						|
        self.host = host
 | 
						|
        self.session = session
 | 
						|
        self.davclient = davclient
 | 
						|
        
 | 
						|
 | 
						|
    @property
 | 
						|
    def  host(self):
 | 
						|
        return self._host
 | 
						|
    
 | 
						|
    @host.setter
 | 
						|
    def host(self, host):
 | 
						|
        self._host = host
 | 
						|
        self._hostname = host.replace("https:","").replace("/","")       
 | 
						|
 | 
						|
    @property
 | 
						|
    def  hostname(self):
 | 
						|
        return self._hostname
 | 
						|
    
 | 
						|
    @hostname.setter
 | 
						|
    def hostname(self, hostname):
 | 
						|
        self._host = "https://%s/" % (hostname)
 | 
						|
        self._hostname = hostname 
 | 
						|
    
 | 
						|
    @property
 | 
						|
    def session(self):
 | 
						|
        return self._session
 | 
						|
    
 | 
						|
    @session.setter
 | 
						|
    def session(self, session):
 | 
						|
        self._session = session
 | 
						|
        self.davclient = easywebdav.connect( self.hostname, protocol='https', session=session, path="cloud", verify_ssl=VERIFY_SSL)
 | 
						|
        
 | 
						|
    @property
 | 
						|
    def PS1(self):
 | 
						|
        if self.davclient is None:
 | 
						|
            return "[!]> "
 | 
						|
        return "%s:%s> " % (self.hostname, self.davclient.cwd)
 | 
						|
    
 | 
						|
    def get_host_session(self, host=None):
 | 
						|
        #~ if host is None:
 | 
						|
            #~ host = self.host
 | 
						|
        #~ if not host.startswith("https"):
 | 
						|
            #~ host = "https://%s/" % (host)
 | 
						|
        #~ if host in self.sessions:
 | 
						|
            #~ session = self.sessions[host]
 | 
						|
        #~ else:
 | 
						|
            #~ session = requests.Session()
 | 
						|
            #~ self.sessions[host] = session
 | 
						|
        #~ if not host == SERVER
 | 
						|
            #~ session.params.update({'davguest':1})
 | 
						|
        #~ return session
 | 
						|
        
 | 
						|
        if self.session is None:
 | 
						|
            session = requests.Session()
 | 
						|
            #session.params.update({'davguest':1})
 | 
						|
        else:
 | 
						|
            session = self.session
 | 
						|
        session.params.update({'davguest': (not  host == SERVER) })
 | 
						|
        return session
 | 
						|
    
 | 
						|
    def do(self, command, *args):
 | 
						|
        if not command in self.commands:
 | 
						|
            raise CommandNotFound("Unknow command '%s'" % command)
 | 
						|
        
 | 
						|
        cmd = getattr(self, "cmd_%s"%command, None)
 | 
						|
        if cmd is None:
 | 
						|
            cmd = getattr(self.davclient, command)
 | 
						|
        
 | 
						|
        return cmd(*args)
 | 
						|
        
 | 
						|
    def cmd_exists(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        return self.davclient.exists(args[0])
 | 
						|
    
 | 
						|
    def cmd_mkdir(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        return self.davclient.mkdir(args[0])
 | 
						|
 | 
						|
    def cmd_mkdirs(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        return self.davclient.mkdirs(args[0])
 | 
						|
 
 | 
						|
    def cmd_rmdir(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        return self.davclient.rmdir(args[0])        
 | 
						|
        
 | 
						|
    def cmd_delete(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        return self.davclient.delete(args[0])        
 | 
						|
        
 | 
						|
    def cmd_upload(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        args = list(args)
 | 
						|
        if (len(args)==1):
 | 
						|
            args.append(args[0])
 | 
						|
            
 | 
						|
        return self.davclient.upload(args[0], args[1])        
 | 
						|
 | 
						|
    def cmd_download(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        args = list(args)
 | 
						|
        if (len(args)==1):
 | 
						|
            args.append(args[0])
 | 
						|
            
 | 
						|
        return self.davclient.download(args[0], args[1])        
 | 
						|
        
 | 
						|
    def cmd_host(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        newhostname = args[0]
 | 
						|
        newhost = "https://%s/" % newhostname
 | 
						|
        if newhostname == "~" or newhost == SERVER:
 | 
						|
            # bach to home server
 | 
						|
            self.host = SERVER
 | 
						|
            self.session = self.get_host_session(SERVER)
 | 
						|
            return
 | 
						|
        
 | 
						|
        session_remote = self.get_host_session(newhost)
 | 
						|
        session_home = self.get_host_session(SERVER)
 | 
						|
 | 
						|
        # call /magic on SERVER
 | 
						|
        r = session_home.get( 
 | 
						|
            SERVER + "magic",  
 | 
						|
            params={'dest': newhost},
 | 
						|
            allow_redirects=False,
 | 
						|
            verify=VERIFY_SSL )
 | 
						|
        
 | 
						|
        if not 'location' in r.headers:
 | 
						|
            raise Exception("Cannot start magic auth to '%s'" % newhostname)
 | 
						|
        auth_url = r.headers['location']
 | 
						|
 | 
						|
 | 
						|
        # call auth_url with "test" param
 | 
						|
    
 | 
						|
        r = session_remote.get( 
 | 
						|
            auth_url,
 | 
						|
            params={'test': 1 },
 | 
						|
            verify=VERIFY_SSL )
 | 
						|
 | 
						|
        if r.json()['success']:
 | 
						|
            self.hostname = newhostname
 | 
						|
            self.session = session_remote
 | 
						|
        else:
 | 
						|
            raise Exception("Cannot magic auth to '%s'" % newhostname)
 | 
						|
        
 | 
						|
 | 
						|
    def cmd_pwd(self, *args):
 | 
						|
        return "%s%s" % ( self.davclient.baseurl, self.davclient.cwd )
 | 
						|
 | 
						|
    def cmd_ls(self, *args):
 | 
						|
        extra_args = ["-a", "-l",  "-d"]
 | 
						|
        
 | 
						|
        show_hidden = "-a" in args
 | 
						|
        show_list = "-l" in args
 | 
						|
        show_only_dir = "-d" in args
 | 
						|
        args = [ a for  a in args if not a in extra_args ]
 | 
						|
        
 | 
						|
        
 | 
						|
        r = self.davclient.ls(*args)
 | 
						|
        l = max([ len(str(f.size)) for f in r ] + [7,])
 | 
						|
        
 | 
						|
        def _fmt(type, size, name):
 | 
						|
            if show_list:
 | 
						|
                return "%s %*d %s" % (type, l, f.size , name)
 | 
						|
            else:
 | 
						|
                return name
 | 
						|
        
 | 
						|
        if show_hidden :
 | 
						|
            print _fmt('d', 0, "./")
 | 
						|
            if self.davclient.cwd!="/":
 | 
						|
                print _fmt('d', 0, "../")
 | 
						|
                
 | 
						|
        for f in r:
 | 
						|
            name = f.name.replace("/cloud"+self.davclient.cwd,"")
 | 
						|
            type = "-"
 | 
						|
            if name.endswith("/"):
 | 
						|
                type = "d"
 | 
						|
            if name!="":
 | 
						|
                if show_hidden  or not name.startswith("."):
 | 
						|
                    if not show_only_dir or  type=="d":
 | 
						|
                        print _fmt(type, f.size , name)
 | 
						|
 | 
						|
    def cmd_lpwd(self, *args):
 | 
						|
        return os.getcwd()
 | 
						|
 | 
						|
    def cmd_lcd(self, *args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return
 | 
						|
        os.chdir(args[0])
 | 
						|
    
 | 
						|
    def cmd_lls(self, *args):
 | 
						|
        for f in os.listdir(os.getcwd()):
 | 
						|
            if os.path.isdir(f):
 | 
						|
                f=f+"/"
 | 
						|
            print f
 | 
						|
            
 | 
						|
    def cmd_help(self, *args):
 | 
						|
        print "ZotSH",__version__
 | 
						|
        print 
 | 
						|
        print "Commands:"
 | 
						|
        for c in self.commands:
 | 
						|
            print "\t",c
 | 
						|
        print
 | 
						|
        print "easywebdav", easywebdavversion.__version__, "(mod)"
 | 
						|
        print "requests", requests.__version__
 | 
						|
 | 
						|
    def cmd_cat(self,*args):
 | 
						|
        if (len(args)==0):
 | 
						|
            return        
 | 
						|
        rfile = args[0]
 | 
						|
        resp = self.davclient._send('GET', rfile, (200,))
 | 
						|
        print resp.text
 | 
						|
 | 
						|
def load_conf():
 | 
						|
    global SERVER,USER,PASSWD,VERIFY_SSL
 | 
						|
    homedir = os.getenv("HOME")
 | 
						|
    if homedir is None:
 | 
						|
        homedir = os.path.join(os.getenv("HOMEDRIVE"), os.getenv("HOMEPATH"))
 | 
						|
    
 | 
						|
    optsfile = ".zotshrc"
 | 
						|
    if not os.path.isfile(optsfile):
 | 
						|
        optsfile = os.path.join(homedir, ".zotshrc")
 | 
						|
    
 | 
						|
    if not os.path.isfile(optsfile):
 | 
						|
        print "Please create a configuration file called '.zotshrc':"
 | 
						|
        print "[zotsh]"
 | 
						|
        print "host = https://yourhost.com/"
 | 
						|
        print "username = your_username"
 | 
						|
        print "password = your_password"
 | 
						|
        sys.exit(-1)
 | 
						|
    
 | 
						|
    config = ConfigParser.ConfigParser()
 | 
						|
    config.read(optsfile)
 | 
						|
    SERVER = config.get('zotsh', 'host')
 | 
						|
    USER = config.get('zotsh', 'username')
 | 
						|
    PASSWD = config.get('zotsh', 'password')
 | 
						|
    if config.has_option('zotsh', 'verify_ssl'):
 | 
						|
        VERIFY_SSL = config.getboolean('zotsh', 'verify_ssl')
 | 
						|
 | 
						|
 | 
						|
def zotsh():
 | 
						|
    
 | 
						|
    zotsh = ZotSH( SERVER)
 | 
						|
    
 | 
						|
    session_home = zotsh.get_host_session()
 | 
						|
 | 
						|
    #~ #login on home server
 | 
						|
    print "loggin in..."
 | 
						|
    r = session_home.get( 
 | 
						|
        SERVER + "api/account/verify_credentials",  
 | 
						|
        auth=HTTPBasicAuth(USER, PASSWD), 
 | 
						|
        verify=VERIFY_SSL    )
 | 
						|
 | 
						|
    print "Hi", r.json()['name']
 | 
						|
 | 
						|
    zotsh.session = session_home
 | 
						|
 | 
						|
    # command loop
 | 
						|
    input = raw_input(zotsh.PS1)
 | 
						|
    while (input != "quit"):
 | 
						|
        input = input.strip()
 | 
						|
        if len(input)>0:
 | 
						|
            toks = [ x.strip() for x in input.split(" ") ]
 | 
						|
            
 | 
						|
            command = toks[0]
 | 
						|
            args = toks[1:]
 | 
						|
            try:
 | 
						|
                ret = zotsh.do(command, *args)
 | 
						|
            except easywebdav.client.OperationFailed, e:
 | 
						|
                print e
 | 
						|
            except CommandNotFound, e:
 | 
						|
                print e
 | 
						|
            else:
 | 
						|
                if ret is not None:
 | 
						|
                    print ret
 | 
						|
        
 | 
						|
 | 
						|
        input = raw_input(zotsh.PS1)
 | 
						|
 | 
						|
 | 
						|
    
 | 
						|
 | 
						|
if __name__=="__main__":
 | 
						|
    load_conf()
 | 
						|
    zotsh()
 | 
						|
    sys.exit()
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 |