示例#1
0
def do_rm(self, line):
    """rm [-f|--force] FILE...             Remove one or more files
    rm [-f|--force] PATTERN                Remove multiple files
    rm -r [-f|--force] [FILE|DIRECTORY]... Files and/or directories
    rm -r [-f|--force] PATTERN             Multiple files and/or directories

    Removes files or directories. To remove directories (and
    any contents) -r must be specified.

    """
    args = self.line_to_args(line)
    filenames = args.filename
    # Process PATTERN
    sfn = filenames[0]
    if is_pattern(sfn):
        if len(filenames) > 1:
            eprint("Usage: rm [-r] [-f] PATTERN")
            return
        filenames = process_pattern(self.boards, self.cur_dir, sfn)
        if filenames is None:
            return

    for filename in filenames:
        filename = resolve_path(self.cur_dir, filename)
        if not rm(
                self.boards, filename, recursive=args.recursive,
                force=args.force):
            if not args.force:
                eprint(
                    "Unable to remove '{}' (try -rf if you are sure)".format(
                        filename))
            break
示例#2
0
def do_mkdir(self, line):
    """mkdir DIRECTORY...

       Creates one or more directories.
    """
    args = self.line_to_args(line)
    for filename in args:
        filename = resolve_path(self.cur_dir, filename)
        if not mkdir(self.boards, filename):
            eprint('Unable to create %s' % filename)
示例#3
0
def do_rsync(self, line):
    """rsync [-m|--mirror] [-n|--dry-run] [SRC_DIR [DST_DIR]]

       Synchronize destination directory tree to source directory tree.
    """
    db = self.boards.default
    args = self.line_to_args(line)
    sd = args.src_dst_dir
    if len(sd) > 2:
        eprint("*** More than one destination directory given")
        return
    src_dir = sd[0] if len(sd) > 0 else db.get_config('host_dir', '~/iot49')
    dst_dir = sd[1] if len(sd) > 1 else db.get_config('remote_dir', '/flash')
    src_dir = resolve_path(self.cur_dir, src_dir)
    dst_dir = resolve_path(self.cur_dir, dst_dir)
    if len(sd) < 2:
        qprint("synchronizing {} --> {}".format(src_dir, dst_dir))
    rsync(self.boards, src_dir, dst_dir,
          mirror=not args.mirror, dry_run=args.dry_run, recursed=True)
示例#4
0
def do_ls(self, line):
    """ls [-a] [-l] [FILE|DIRECTORY|PATTERN]...
   PATTERN supports * ? [seq] [!seq] Unix filename matching

       List directory contents.
    """
    args = self.line_to_args(line)
    if len(args.filenames) == 0:
        args.filenames = ['.']
    for idx, fn in enumerate(args.filenames):
        if not is_pattern(fn):
            filename = resolve_path(self.cur_dir, fn)
            stat = auto(self.boards, get_stat, filename)
            mode = stat_mode(stat)
            if not mode_exists(mode):
                err = "Cannot access '{}': No such file or directory"
                eprint(err.format(filename))
                continue
            if not mode_isdir(mode):
                if args.long:
                    print_long(filename, stat, oprint)
                else:
                    oprint(filename)
                continue
            if len(args.filenames) > 1:
                if idx > 0:
                    oprint('')
                oprint("%s:" % filename)
            pattern = '*'
        else:  # A pattern was specified
            filename, pattern = validate_pattern(self.boards, self.cur_dir, fn)
            if filename is None:  # An error was printed
                continue
        files = []
        ldir_stat = auto(self.boards, listdir_stat, filename)
        if ldir_stat is None:
            err = "Cannot access '{}': No such file or directory"
            eprint(err.format(filename))
        else:
            for filename, stat in sorted(ldir_stat,
                                         key=lambda entry: entry[0]):
                if is_visible(filename) or args.all:
                    if fnmatch(filename, pattern):
                        if args.long:
                            print_long(filename, stat, oprint)
                        else:
                            files.append(decorated_filename(filename, stat))
        if len(files) > 0:
            print_cols(sorted(files), oprint,
                       shutil.get_terminal_size().columns)
示例#5
0
def do_cat(self, line):
    """cat FILENAME...

    Concatenates files and sends to stdout.
    """
    # note: when we get around to supporting cat from stdin, we'll need
    #       to write stdin to a temp file, and then copy the file
    #       since we need to know the filesize when copying to the pyboard.
    args = self.line_to_args(line)
    for filename in args:
        filename = resolve_path(self.cur_dir, filename)
        mode = auto(self.boards, get_mode, filename)
        if not mode_exists(mode):
            eprint("Cannot access '%s': No such file" % filename)
            continue
        if not mode_isfile(mode):
            eprint("'%s': is not a file" % filename)
            continue
        cat(self.boards, filename, self.stdout)
示例#6
0
def do_cd(self, line):
    """cd DIRECTORY

       Changes the current directory. ~ expansion is supported, and cd -
       goes to the previous directory.
    """
    args = self.line_to_args(line)
    if len(args) == 0:
        dirname = '~'
    else:
        if args[0] == '-':
            dirname = self.prev_dir
        else:
            dirname = args[0]
    dirname = resolve_path(self.cur_dir, dirname)

    mode = auto(self.boards, get_mode, dirname)
    if mode_isdir(mode):
        self.prev_dir = self.cur_dir
        self.cur_dir = dirname
        auto(self.boards, chdir, dirname)
    else:
        eprint("Directory '%s' does not exist" % dirname)
示例#7
0
def do_edit(self, line):
    """edit FILE

       Copies the file locally, launches an editor to edit the file.
       When the editor exits, if the file was modified then its copied
       back.

       You can specify the editor used with the --editor command line
       option when you start shell49, or by using the SHELL49_EDITOR or VISUAL
       or EDITOR environment variable. If none of those are set, then
       vi will be used.
    """
    if len(line) == 0:
        eprint("Must provide a filename")
        return
    filename = resolve_path(self.cur_dir, line)
    dev, dev_filename = self.boards.get_dev_and_path(filename)
    mode = auto(self.boards, get_mode, filename)
    if mode_exists(mode) and mode_isdir(mode):
        eprint("Unable to edit directory '{}'".format(filename))
        return
    if dev is None:
        # File is local
        os.system("{} '{}'".format(self.editor, filename))
    else:
        # File is remote
        with tempfile.TemporaryDirectory() as temp_dir:
            local_filename = os.path.join(temp_dir, os.path.basename(filename))
            if mode_exists(mode):
                print('Retrieving {} ...'.format(filename))
                cp(filename, local_filename)
            old_stat = get_stat(local_filename)
            os.system("{} '{}'".format(self.editor, local_filename))
            new_stat = get_stat(local_filename)
            if old_stat != new_stat:
                print('Updating {} ...'.format(filename))
                cp(local_filename, filename)
示例#8
0
def do_cp(self, line):
    """cp SOURCE DEST               Copy a single SOURCE file to DEST file.
    cp SOURCE... DIRECTORY          Copy multiple SOURCE files to a directory.
    cp [-r] PATTERN DIRECTORY       Copy matching files to DIRECTORY.
    cp [-r|--recursive] [SOURCE|SOURCE_DIR]... DIRECTORY

       The destination must be a directory except in the case of
       copying a single file. To copy directories -r must be specified.
       This will cause directories and their contents to be recursively
       copied.
    """
    args = self.line_to_args(line)
    if len(args.filenames) < 2:
        eprint('Missing destination file')
        return
    dst_dirname = resolve_path(self.cur_dir, args.filenames[-1])
    dst_mode = auto(self.boards, get_mode, dst_dirname)
    d_dst = {}  # Destination directory: lookup stat by basename
    if args.recursive:
        dst_files = auto(self.boards, listdir_stat, dst_dirname)
        if dst_files is None:
            err = "cp: target {} is not a directory"
            eprint(err.format(dst_dirname))
            return
        for name, stat in dst_files:
            d_dst[name] = stat

    src_filenames = args.filenames[:-1]

    # Process PATTERN
    sfn = src_filenames[0]
    if is_pattern(sfn):
        if len(src_filenames) > 1:
            eprint("Usage: cp [-r] PATTERN DIRECTORY")
            return
        src_filenames = process_pattern(self.boards, self.cur_dir, sfn)
        if src_filenames is None:
            return

    for src_filename in src_filenames:
        if is_pattern(src_filename):
            eprint("Only one pattern permitted.")
            return
        src_filename = resolve_path(self.cur_dir, src_filename)
        src_mode = auto(self.boards, get_mode, src_filename)
        if not mode_exists(src_mode):
            eprint("File '{}' doesn't exist".format(src_filename))
            return
        if mode_isdir(src_mode):
            if args.recursive:  # Copying a directory
                src_basename = os.path.basename(src_filename)
                dst_filename = os.path.join(dst_dirname, src_basename)
                if src_basename in d_dst:
                    dst_stat = d_dst[src_basename]
                    dst_mode = stat_mode(dst_stat)
                    if not mode_isdir(dst_mode):
                        err = "Destination {} is not a directory"
                        eprint(err.format(dst_filename))
                        return
                else:
                    if not mkdir(dst_filename):
                        err = "Unable to create directory {}"
                        eprint(err.format(dst_filename))
                        return

                rsync(src_filename, dst_filename, mirror=False, dry_run=False,
                      print_func=lambda *args: None, recursed=False)
            else:
                eprint("Omitting directory {}".format(src_filename))
            continue
        if mode_isdir(dst_mode):
            dst_filename = os.path.join(
                dst_dirname, os.path.basename(src_filename))
        else:
            dst_filename = dst_dirname
        if not cp(self.boards, src_filename, dst_filename):
            err = "Unable to copy '{}' to '{}'"
            eprint(err.format(src_filename, dst_filename))
            break