cli.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 
00004 import os
00005 import shlex
00006 import subprocess
00007 import sys
00008 
00009 import click
00010 from jsk_tools.cltool import percol_select
00011 
00012 from jsk_data.gdrive import delete_gdrive
00013 from jsk_data.gdrive import download_gdrive
00014 from jsk_data.gdrive import info_gdrive
00015 from jsk_data.gdrive import list_gdrive
00016 from jsk_data.gdrive import open_gdrive
00017 from jsk_data.gdrive import upload_gdrive
00018 from jsk_data.ssh import connect_ssh
00019 from jsk_data.ssh import get_user_by_hostname
00020 from jsk_data.util import filename_with_timestamp
00021 from jsk_data.util import google_drive_file_url
00022 
00023 
00024 __all__ = ('cli', 'cmd_get', 'cmd_ls', 'cmd_put', 'cmd_pubinfo')
00025 
00026 
00027 def _get_login_user(host):
00028     username = get_user_by_hostname(host)
00029     username = username or os.environ.get('SSH_USER')
00030     username = username or os.environ['USER']
00031     return username
00032 
00033 
00034 HOST = 'aries.jsk.t.u-tokyo.ac.jp'
00035 DATA_DIR = '/home/jsk/ros/data'
00036 LOGIN_USER = _get_login_user(host=HOST)
00037 
00038 
00039 CONTEXT_SETTINGS = dict(
00040     help_option_names=['-h', '--help'],
00041 )
00042 
00043 
00044 @click.group(context_settings=CONTEXT_SETTINGS)
00045 def cli():
00046     pass
00047 
00048 
00049 @cli.command(name='get', help='Download specified file.')
00050 @click.option('-p', '--public', is_flag=True, help='Handle public files.')
00051 @click.argument('query', default='')
00052 def cmd_get(public, query):
00053     """Download specified file."""
00054     if not query:
00055         if public:
00056             lines = list_gdrive().splitlines()
00057             candidates = [l.split()[1] for l in lines]
00058         else:
00059             candidates = _list_aries_files()
00060         selected = percol_select(candidates)
00061         if len(selected) != 1:
00062             sys.stderr.write('Please select 1 filename.\n')
00063             sys.exit(1)
00064         query = selected[0]
00065         sys.stderr.write('Selected: {0}\n'.format(query))
00066 
00067     if public:
00068         download_gdrive(filename=query)
00069     else:
00070         cmd = 'rsync -avz --progress -e "ssh -o StrictHostKeyChecking=no"\
00071             --bwlimit=100000 {usr}@{host}:{dir}/private/{q} .'
00072         cmd = cmd.format(usr=LOGIN_USER, host=HOST, dir=DATA_DIR, q=query)
00073         subprocess.call(shlex.split(cmd))
00074 
00075 
00076 def _list_aries_files(query=None, ls_options=None):
00077     query = query or ''
00078     ls_options = ls_options or []
00079     with connect_ssh(HOST, LOGIN_USER) as ssh:
00080         cmd = 'ls {opt} {dir}/private/{q}'
00081         cmd = cmd.format(opt=' '.join(ls_options), dir=DATA_DIR, q=query)
00082         _, stdout, _ = ssh.exec_command(cmd)
00083         files = stdout.read().splitlines()
00084     return files
00085 
00086 
00087 @cli.command(name='ls', help='Get list of files.')
00088 @click.option('-p', '--public', is_flag=True, help='Handle public files.')
00089 @click.argument('query', required=False)
00090 @click.option('-s', '--show-size', is_flag=True, help='Display size.')
00091 @click.option('--sort', help='Sort by ..',
00092               type=click.Choice(['time', 'size', 'extension', 'version']))
00093 @click.option('-r', '--reverse', is_flag=True, help='Reverse the order.')
00094 def cmd_ls(public, query, show_size, sort, reverse):
00095     """Get list of files."""
00096     if query is None:
00097         query = ''
00098 
00099     ls_options = []
00100     if show_size:
00101         ls_options.append('--size')
00102         ls_options.append('--human-readable')
00103     if sort is not None:
00104         ls_options.append('--sort={0}'.format(sort))
00105     if reverse:
00106         ls_options.append('--reverse')
00107 
00108     if public:
00109         if ls_options:
00110             sys.stderr.write(
00111                 'WARNING: if public=True, ignores all ls options\n')
00112         sys.stdout.write(list_gdrive())
00113     else:
00114         print('\n'.join(_list_aries_files(query, ls_options)))
00115 
00116 
00117 @cli.command(name='put', help='Upload file to aries.')
00118 @click.argument('filename', required=True, type=click.Path(exists=True))
00119 @click.option(
00120     '-p', '--public', is_flag=True,
00121     help=('Handle public files. It will be uploaded to Google Drive. '
00122           'Go https://drive.google.com/open?id=0B9P1L--7Wd2vUGplQkVLTFBWcFE'))
00123 @click.option(
00124     '--stamped', is_flag=True,
00125     help='Rename file to with prefix of timestamp')
00126 def cmd_put(filename, public, stamped):
00127     """Upload file to aries."""
00128     if stamped:
00129         filename_org = filename
00130         filename = filename_with_timestamp(filename)
00131         if filename_org != filename:
00132             print('Filename is being changed: {0} -> {1}'
00133                   .format(filename_org, filename))
00134             yn = raw_input('Are you sure?[Y/n]: ')
00135             if yn not in 'yY':
00136                 sys.stderr.write('Aborted!')
00137                 sys.exit(1)
00138             os.rename(filename_org, filename)
00139 
00140     if public:
00141         print('Uploading to Google Drive...')
00142         stdout = upload_gdrive(filename)
00143         for line in stdout.splitlines():
00144             if line.startswith('Title:'):
00145                 filename = line.split(' ')[-1].strip()
00146             elif line.startswith('Id:'):
00147                 file_id = line.split(' ')[-1].strip()
00148         print('Done.')
00149         print('You can download it by:')
00150         dl_url = google_drive_file_url(file_id, download=True)
00151         print('$ wget {url} -O {file}'.format(url=dl_url, file=filename))
00152     else:
00153         print('Uploading to aries...')
00154         cmd = 'rsync -avz --progress -e "ssh -o StrictHostKeyChecking=no"\
00155             --bwlimit=100000 {file} {usr}@{host}:{dir}/private/'
00156         cmd = cmd.format(file=filename, usr=LOGIN_USER, host=HOST,
00157                          dir=DATA_DIR)
00158         subprocess.call(shlex.split(cmd))
00159         print('Done.')
00160 
00161 
00162 @cli.command(name='pubinfo', help='Show public data info.')
00163 @click.argument('filename', default='')
00164 @click.option('-d', '--download-cmd', 'show_dl_cmd', is_flag=True,
00165               help='Print out download command')
00166 def cmd_pubinfo(filename, show_dl_cmd):
00167     if not filename:
00168         candidates = list_gdrive().splitlines()
00169         selected = percol_select(candidates)
00170         if len(selected) != 1:
00171             sys.stderr.write('Please select 1 filename.\n')
00172             sys.exit(1)
00173         filename = selected[0].split()[1]
00174 
00175     # FIXME: gdrive does not return full title if it is longer than 40
00176     if len(filename) > 40:
00177         filename = filename[:19] + '...' + filename[-18:]
00178 
00179     stdout = list_gdrive()
00180     for line in stdout.splitlines():
00181         file_id, title = line.split()[:2]
00182         if filename == title:
00183             filename = info_gdrive(id=file_id, only_filename=True)
00184             break
00185     else:
00186         sys.stderr.write('file not found: {0}\n'.format(filename))
00187         sys.stderr.write('Run `jsk_data ls --public` to find files.\n')
00188         return
00189 
00190     dl_url = google_drive_file_url(file_id, download=True)
00191     if show_dl_cmd:
00192         info = 'wget {url} -O {file}'.format(url=dl_url, file=filename)
00193         sys.stdout.write(info)  # no new line for copy with pipe
00194     else:
00195         view_url = google_drive_file_url(file_id)
00196         info = '''\
00197 Id: {id}
00198 Filename: {file}
00199 View URL: {view_url}
00200 Download URL: {dl_url}'''.format(id=file_id, file=filename,
00201                                  view_url=view_url, dl_url=dl_url)
00202         print(info)
00203 
00204 
00205 @cli.command(name='delete', help='Delete specified file.')
00206 @click.option('-p', '--public', is_flag=True, help='Handle public files.')
00207 @click.argument('filename', default='')
00208 def cmd_delete(public, filename):
00209     """Delete specified file."""
00210     if not public:
00211         sys.stderr.write('ERROR: public=False is not supported\n')
00212         sys.exit(1)
00213 
00214     if not filename:
00215         # FIXME: gdrive does not return full title if it is longer than 40
00216         candidates = list_gdrive().splitlines()
00217         selected = percol_select(candidates)
00218         if len(selected) != 1:
00219             sys.stderr.write('Please select 1 filename.\n')
00220             sys.exit(1)
00221         filename = selected[0].split()[1]
00222 
00223     delete_gdrive(filename=filename)
00224 
00225 
00226 @cli.command(name='pubopen', help='Go to see files on browser')
00227 def cmd_pubopen():
00228     open_gdrive()


jsk_data
Author(s):
autogenerated on Fri Sep 8 2017 03:39:16