Exemplo n.º 1
0
def do_list(fields, data, opts):
    from calibre.utils.terminal import geometry, ColoredStream

    separator = ' '
    widths = list(map(lambda x: 0, fields))
    for i in data:
        for j, field in enumerate(fields):
            widths[j] = max(widths[j], max(len(field), len(unicode_type(i[field]))))

    screen_width = geometry()[0]
    if not screen_width:
        screen_width = 80
    field_width = screen_width // len(fields)
    base_widths = list(map(lambda x: min(x + 1, field_width), widths))

    while sum(base_widths) < screen_width:
        adjusted = False
        for i in range(len(widths)):
            if base_widths[i] < widths[i]:
                base_widths[i] += min(
                    screen_width - sum(base_widths), widths[i] - base_widths[i]
                )
                adjusted = True
                break
        if not adjusted:
            break

    widths = list(base_widths)
    titles = map(
        lambda x, y: '%-*s%s' % (x - len(separator), y, separator), widths, fields
    )
    with ColoredStream(sys.stdout, fg='green'):
        prints(''.join(titles))

    wrappers = list(map(lambda x: TextWrapper(x - 1), widths))

    for record in data:
        text = [
            wrappers[i].wrap(unicode_type(record[field]))
            for i, field in enumerate(fields)
        ]
        lines = max(map(len, text))
        for l in range(lines):
            for i, field in enumerate(text):
                ft = text[i][l] if l < len(text[i]) else ''
                filler = '%*s' % (widths[i] - len(ft) - 1, '')
                print(ft.encode('utf-8') + filler.encode('utf-8'), end=separator)
            print()
Exemplo n.º 2
0
def do_list(fields, data, opts):
    from calibre.utils.terminal import geometry, ColoredStream

    separator = ' '
    widths = list(map(lambda x: 0, fields))
    for i in data:
        for j, field in enumerate(fields):
            widths[j] = max(widths[j], max(len(field), len(unicode_type(i[field]))))

    screen_width = geometry()[0]
    if not screen_width:
        screen_width = 80
    field_width = screen_width // len(fields)
    base_widths = map(lambda x: min(x + 1, field_width), widths)

    while sum(base_widths) < screen_width:
        adjusted = False
        for i in range(len(widths)):
            if base_widths[i] < widths[i]:
                base_widths[i] += min(
                    screen_width - sum(base_widths), widths[i] - base_widths[i]
                )
                adjusted = True
                break
        if not adjusted:
            break

    widths = list(base_widths)
    titles = map(
        lambda x, y: '%-*s%s' % (x - len(separator), y, separator), widths, fields
    )
    with ColoredStream(sys.stdout, fg='green'):
        prints(''.join(titles))

    wrappers = map(lambda x: TextWrapper(x - 1), widths)

    for record in data:
        text = [
            wrappers[i].wrap(unicode_type(record[field]))
            for i, field in enumerate(fields)
        ]
        lines = max(map(len, text))
        for l in range(lines):
            for i, field in enumerate(text):
                ft = text[i][l] if l < len(text[i]) else ''
                filler = '%*s' % (widths[i] - len(ft) - 1, '')
                print(ft.encode('utf-8') + filler.encode('utf-8'), end=separator)
            print()
Exemplo n.º 3
0
def main():
    from calibre.utils.terminal import geometry
    cols = geometry()[0]

    parser = OptionParser(
        usage="usage: %prog [options] command args\n\ncommand " +
        "is one of: info, books, df, ls, cp, mkdir, touch, cat, rm, eject, test_file\n\n"
        + "For help on a particular command: %prog command",
        version=__appname__ + " version: " + __version__)
    parser.add_option(
        "--log-packets",
        help="print out packet stream to stdout. " +
        "The numbers in the left column are byte offsets that allow the packet size to be read off easily.",
        dest="log_packets",
        action="store_true",
        default=False)
    parser.remove_option("-h")
    parser.disable_interspersed_args()  # Allow unrecognized options
    options, args = parser.parse_args()

    if len(args) < 1:
        parser.print_help()
        return 1

    command = args[0]
    args = args[1:]
    dev = None
    scanner = DeviceScanner()
    scanner.scan()
    connected_devices = []

    for d in device_plugins():
        try:
            d.startup()
        except:
            print('Startup failed for device plugin: %s' % d)
        if d.MANAGES_DEVICE_PRESENCE:
            cd = d.detect_managed_devices(scanner.devices)
            if cd is not None:
                connected_devices.append((cd, d))
                dev = d
                break
            continue
        ok, det = scanner.is_device_connected(d)
        if ok:
            dev = d
            dev.reset(log_packets=options.log_packets, detected_device=det)
            connected_devices.append((det, dev))

    if dev is None:
        print('Unable to find a connected ebook reader.', file=sys.stderr)
        shutdown_plugins()
        return 1

    for det, d in connected_devices:
        try:
            d.open(det, None)
        except:
            continue
        else:
            dev = d
            d.specialize_global_preferences(device_prefs)
            break

    try:
        if command == "df":
            total = dev.total_space(end_session=False)
            free = dev.free_space()
            where = ("Memory", "Card A", "Card B")
            print("Filesystem\tSize \tUsed \tAvail \tUse%")
            for i in range(3):
                print("%-10s\t%s\t%s\t%s\t%s" %
                      (where[i], human_readable(
                          total[i]), human_readable(total[i] - free[i]),
                       human_readable(free[i]),
                       unicode_type(0 if total[i] ==
                                    0 else int(100 * (total[i] - free[i]) /
                                               (total[i] * 1.))) + "%"))
        elif command == 'eject':
            dev.eject()
        elif command == "books":
            print("Books in main memory:")
            for book in dev.books():
                print(book)
            print("\nBooks on storage carda:")
            for book in dev.books(oncard='carda'):
                print(book)
            print("\nBooks on storage cardb:")
            for book in dev.books(oncard='cardb'):
                print(book)
        elif command == "mkdir":
            parser = OptionParser(
                usage=
                "usage: %prog mkdir [options] path\nCreate a folder on the device\n\npath must begin with / or card:/"
            )
            if len(args) != 1:
                parser.print_help()
                sys.exit(1)
            dev.mkdir(args[0])
        elif command == "ls":
            parser = OptionParser(
                usage=
                "usage: %prog ls [options] path\nList files on the device\n\npath must begin with / or card:/"
            )
            parser.add_option(
                "-l",
                help=
                "In addition to the name of each file, print the file type, permissions, and  timestamp  (the  modification time, in the local timezone). Times are local.",  # noqa
                dest="ll",
                action="store_true",
                default=False)
            parser.add_option(
                "-R",
                help=
                "Recursively list subfolders encountered. /dev and /proc are omitted",
                dest="recurse",
                action="store_true",
                default=False)
            parser.remove_option("-h")
            parser.add_option("-h",
                              "--human-readable",
                              help="show sizes in human readable format",
                              dest="hrs",
                              action="store_true",
                              default=False)
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            print(ls(dev,
                     args[0],
                     recurse=options.recurse,
                     ll=options.ll,
                     human_readable_size=options.hrs,
                     cols=cols),
                  end=' ')
        elif command == "info":
            info(dev)
        elif command == "cp":
            usage="usage: %prog cp [options] source destination\nCopy files to/from the device\n\n"+\
            "One of source or destination must be a path on the device. \n\nDevice paths have the form\n"+\
            "dev:mountpoint/my/path\n"+\
            "where mountpoint is one of / or carda: or cardb:/\n\n"+\
            "source must point to a file for which you have read permissions\n"+\
            "destination must point to a file or folder for which you have write permissions"
            parser = OptionParser(usage=usage)
            parser.add_option(
                '-f',
                '--force',
                dest='force',
                action='store_true',
                default=False,
                help='Overwrite the destination file if it exists already.')
            options, args = parser.parse_args(args)
            if len(args) != 2:
                parser.print_help()
                return 1
            if args[0].startswith("dev:"):
                outfile = args[1]
                path = args[0][4:]
                if path.endswith("/"):
                    path = path[:-1]
                if os.path.isdir(outfile):
                    outfile = os.path.join(outfile, path[path.rfind("/") + 1:])
                try:
                    outfile = lopen(outfile, "wb")
                except IOError as e:
                    print(e, file=sys.stderr)
                    parser.print_help()
                    return 1
                dev.get_file(path, outfile)
                fsync(outfile)
                outfile.close()
            elif args[1].startswith("dev:"):
                try:
                    infile = lopen(args[0], "rb")
                except IOError as e:
                    print(e, file=sys.stderr)
                    parser.print_help()
                    return 1
                dev.put_file(infile, args[1][4:], replace_file=options.force)
                infile.close()
            else:
                parser.print_help()
                return 1
        elif command == "cat":
            outfile = sys.stdout
            parser = OptionParser(
                usage=
                "usage: %prog cat path\nShow file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/"
            )
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            if args[0].endswith("/"):
                path = args[0][:-1]
            else:
                path = args[0]
            outfile = sys.stdout
            dev.get_file(path, outfile)
        elif command == "rm":
            parser = OptionParser(
                usage=
                "usage: %prog rm path\nDelete files from the device\n\npath should point to a file or empty folder on the device "
                + "and must begin with / or card:/\n\n" +
                "rm will DELETE the file. Be very CAREFUL")
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            dev.rm(args[0])
        elif command == "touch":
            parser = OptionParser(
                usage=
                "usage: %prog touch path\nCreate an empty file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/\n\n"
                +  # noqa
                "Unfortunately, I cant figure out how to update file times on the device, so if path already exists, touch does nothing"
            )
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            dev.touch(args[0])
        elif command == 'test_file':
            parser = OptionParser(usage=(
                "usage: %prog test_file path\n"
                'Open device, copy file specified by path to device and '
                'then eject device.'))
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            path = args[0]
            from calibre.ebooks.metadata.meta import get_metadata
            mi = get_metadata(lopen(path, 'rb'),
                              path.rpartition('.')[-1].lower())
            print(
                dev.upload_books([args[0]], [os.path.basename(args[0])],
                                 end_session=False,
                                 metadata=[mi]))
            dev.eject()
        else:
            parser.print_help()
            if getattr(dev, 'handle', False):
                dev.close()
            return 1
    except DeviceLocked:
        print("The device is locked. Use the --unlock option", file=sys.stderr)
    except (ArgumentError, DeviceError) as e:
        print(e, file=sys.stderr)
        return 1
    finally:
        shutdown_plugins()

    return 0
Exemplo n.º 4
0
def do_list(dbctx,
            fields,
            afields,
            sort_by,
            ascending,
            search_text,
            line_width,
            separator,
            prefix,
            limit,
            for_machine=False):
    if sort_by is None:
        ascending = True
    ans = dbctx.run('list', fields, sort_by, ascending, search_text, limit)
    try:
        book_ids, data, metadata = ans['book_ids'], ans['data'], ans[
            'metadata']
    except TypeError:
        raise SystemExit(ans)
    fields = list(ans['fields'])
    try:
        fields.remove('id')
    except ValueError:
        pass
    fields = ['id'] + fields
    stringify(data, metadata, for_machine)
    if for_machine:
        raw = json.dumps(list(as_machine_data(book_ids, data, metadata)),
                         indent=2,
                         sort_keys=True)
        if not isinstance(raw, bytes):
            raw = raw.encode('utf-8')
        getattr(sys.stdout, 'buffer', sys.stdout).write(raw)
        return
    from calibre.utils.terminal import ColoredStream, geometry

    output_table = prepare_output_table(fields, book_ids, data, metadata)
    widths = list(map(lambda x: 0, fields))

    for record in output_table:
        for j in range(len(fields)):
            widths[j] = max(widths[j], str_width(record[j]))

    screen_width = geometry()[0] if line_width < 0 else line_width
    if not screen_width:
        screen_width = 80
    field_width = screen_width // len(fields)
    base_widths = list(map(lambda x: min(x + 1, field_width), widths))

    while sum(base_widths) < screen_width:
        adjusted = False
        for i in range(len(widths)):
            if base_widths[i] < widths[i]:
                base_widths[i] += min(screen_width - sum(base_widths),
                                      widths[i] - base_widths[i])
                adjusted = True
                break
        if not adjusted:
            break

    widths = list(base_widths)
    titles = map(lambda x, y: '%-*s%s' % (x - len(separator), y, separator),
                 widths, fields)
    with ColoredStream(sys.stdout, fg='green'):
        prints(''.join(titles))

    wrappers = [
        TextWrapper(x - 1).wrap if x > 1 else lambda y: y for x in widths
    ]

    for record in output_table:
        text = [wrappers[i](record[i]) for i, field in enumerate(fields)]
        lines = max(map(len, text))
        for l in range(lines):
            for i, field in enumerate(text):
                ft = text[i][l] if l < len(text[i]) else u''
                sys.stdout.write(ft.encode('utf-8'))
                if i < len(text) - 1:
                    filler = (u'%*s' % (widths[i] - str_width(ft) - 1, u''))
                    sys.stdout.write((filler + separator).encode('utf-8'))
            print()
Exemplo n.º 5
0
def do_list(
    dbctx,
    fields,
    afields,
    sort_by,
    ascending,
    search_text,
    line_width,
    separator,
    prefix,
    limit,
    for_machine=False
):
    if sort_by is None:
        ascending = True
    ans = dbctx.run('list', fields, sort_by, ascending, search_text, limit)
    try:
        book_ids, data, metadata = ans['book_ids'], ans['data'], ans['metadata']
    except TypeError:
        raise SystemExit(ans)
    fields = list(ans['fields'])
    try:
        fields.remove('id')
    except ValueError:
        pass
    fields = ['id'] + fields
    stringify(data, metadata, for_machine)
    if for_machine:
        raw = json.dumps(
            list(as_machine_data(book_ids, data, metadata)),
            indent=2,
            sort_keys=True
        )
        if not isinstance(raw, bytes):
            raw = raw.encode('utf-8')
        getattr(sys.stdout, 'buffer', sys.stdout).write(raw)
        return
    from calibre.utils.terminal import ColoredStream, geometry

    output_table = prepare_output_table(fields, book_ids, data, metadata)
    widths = list(map(lambda x: 0, fields))

    for record in output_table:
        for j in range(len(fields)):
            widths[j] = max(widths[j], str_width(record[j]))

    screen_width = geometry()[0] if line_width < 0 else line_width
    if not screen_width:
        screen_width = 80
    field_width = screen_width // len(fields)
    base_widths = map(lambda x: min(x + 1, field_width), widths)

    while sum(base_widths) < screen_width:
        adjusted = False
        for i in range(len(widths)):
            if base_widths[i] < widths[i]:
                base_widths[i] += min(
                    screen_width - sum(base_widths), widths[i] - base_widths[i]
                )
                adjusted = True
                break
        if not adjusted:
            break

    widths = list(base_widths)
    titles = map(
        lambda x, y: '%-*s%s' % (x - len(separator), y, separator), widths,
        fields
    )
    with ColoredStream(sys.stdout, fg='green'):
        prints(''.join(titles))

    wrappers = [TextWrapper(x - 1).wrap if x > 1 else lambda y: y for x in widths]

    for record in output_table:
        text = [
            wrappers[i](record[i]) for i, field in enumerate(fields)
        ]
        lines = max(map(len, text))
        for l in range(lines):
            for i, field in enumerate(text):
                ft = text[i][l] if l < len(text[i]) else u''
                sys.stdout.write(ft.encode('utf-8'))
                if i < len(text) - 1:
                    filler = (u'%*s' % (widths[i] - str_width(ft) - 1, u''))
                    sys.stdout.write((filler + separator).encode('utf-8'))
            print()
Exemplo n.º 6
0
def main():
    from calibre.utils.terminal import geometry
    cols = geometry()[0]

    parser = OptionParser(usage="usage: %prog [options] command args\n\ncommand "+
            "is one of: info, books, df, ls, cp, mkdir, touch, cat, rm, eject, test_file\n\n"+
    "For help on a particular command: %prog command", version=__appname__+" version: " + __version__)
    parser.add_option("--log-packets", help="print out packet stream to stdout. "+\
                    "The numbers in the left column are byte offsets that allow the packet size to be read off easily.",
    dest="log_packets", action="store_true", default=False)
    parser.remove_option("-h")
    parser.disable_interspersed_args() # Allow unrecognized options
    options, args = parser.parse_args()

    if len(args) < 1:
        parser.print_help()
        return 1

    command = args[0]
    args = args[1:]
    dev = None
    scanner = DeviceScanner()
    scanner.scan()
    connected_devices = []

    for d in device_plugins():
        try:
            d.startup()
        except:
            print ('Startup failed for device plugin: %s'%d)
        if d.MANAGES_DEVICE_PRESENCE:
            cd = d.detect_managed_devices(scanner.devices)
            if cd is not None:
                connected_devices.append((cd, d))
                dev = d
                break
            continue
        ok, det = scanner.is_device_connected(d)
        if ok:
            dev = d
            dev.reset(log_packets=options.log_packets, detected_device=det)
            connected_devices.append((det, dev))

    if dev is None:
        print >>sys.stderr, 'Unable to find a connected ebook reader.'
        shutdown_plugins()
        return 1

    for det, d in connected_devices:
        try:
            d.open(det, None)
        except:
            continue
        else:
            dev = d
            d.specialize_global_preferences(device_prefs)
            break


    try:
        if command == "df":
            total = dev.total_space(end_session=False)
            free = dev.free_space()
            where = ("Memory", "Card A", "Card B")
            print "Filesystem\tSize \tUsed \tAvail \tUse%"
            for i in range(3):
                print "%-10s\t%s\t%s\t%s\t%s"%(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]),\
                                                                            str(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+"%")
        elif command == 'eject':
            dev.eject()
        elif command == "books":
            print "Books in main memory:"
            for book in dev.books():
                print book
            print "\nBooks on storage carda:"
            for book in dev.books(oncard='carda'): print book
            print "\nBooks on storage cardb:"
            for book in dev.books(oncard='cardb'): print book
        elif command == "mkdir":
            parser = OptionParser(usage="usage: %prog mkdir [options] path\nCreate a directory on the device\n\npath must begin with / or card:/")
            if len(args) != 1:
                parser.print_help()
                sys.exit(1)
            dev.mkdir(args[0])
        elif command == "ls":
            parser = OptionParser(usage="usage: %prog ls [options] path\nList files on the device\n\npath must begin with / or card:/")
            parser.add_option("-l", help="In addition to the name of each file, print the file type, permissions, and  timestamp  (the  modification time, in the local timezone). Times are local.", dest="ll", action="store_true", default=False)
            parser.add_option("-R", help="Recursively list subdirectories encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False)
            parser.remove_option("-h")
            parser.add_option("-h", "--human-readable", help="show sizes in human readable format", dest="hrs", action="store_true", default=False)
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            print ls(dev, args[0], recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols),
        elif command == "info":
            info(dev)
        elif command == "cp":
            usage="usage: %prog cp [options] source destination\nCopy files to/from the device\n\n"+\
            "One of source or destination must be a path on the device. \n\nDevice paths have the form\n"+\
            "dev:mountpoint/my/path\n"+\
            "where mountpoint is one of / or card:/\n\n"+\
            "source must point to a file for which you have read permissions\n"+\
            "destination must point to a file or directory for which you have write permissions"
            parser = OptionParser(usage=usage)
            parser.add_option('-f', '--force', dest='force', action='store_true', default=False,
                              help='Overwrite the destination file if it exists already.')
            options, args = parser.parse_args(args)
            if len(args) != 2:
                parser.print_help()
                return 1
            if args[0].startswith("dev:"):
                outfile = args[1]
                path = args[0][7:]
                if path.endswith("/"): path = path[:-1]
                if os.path.isdir(outfile):
                    outfile = os.path.join(outfile, path[path.rfind("/")+1:])
                try:
                    outfile = open(outfile, "wb")
                except IOError as e:
                    print >> sys.stderr, e
                    parser.print_help()
                    return 1
                dev.get_file(path, outfile)
                outfile.close()
            elif args[1].startswith("dev:"):
                try:
                    infile = open(args[0], "rb")
                except IOError as e:
                    print >> sys.stderr, e
                    parser.print_help()
                    return 1
                try:
                    dev.put_file(infile, args[1][7:])
                except PathError as err:
                    if options.force and 'exists' in str(err):
                        dev.del_file(err.path, False)
                        dev.put_file(infile, args[1][7:])
                    else:
                        raise
                infile.close()
            else:
                parser.print_help()
                return 1
        elif command == "cat":
            outfile = sys.stdout
            parser = OptionParser(usage="usage: %prog cat path\nShow file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/")
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            if args[0].endswith("/"): path = args[0][:-1]
            else: path = args[0]
            outfile = sys.stdout
            dev.get_file(path, outfile)
        elif command == "rm":
            parser = OptionParser(usage="usage: %prog rm path\nDelete files from the device\n\npath should point to a file or empty directory on the device "+\
                                  "and must begin with / or card:/\n\n"+\
                                  "rm will DELETE the file. Be very CAREFUL")
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            dev.rm(args[0])
        elif command == "touch":
            parser = OptionParser(usage="usage: %prog touch path\nCreate an empty file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/\n\n"+
            "Unfortunately, I cant figure out how to update file times on the device, so if path already exists, touch does nothing" )
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            dev.touch(args[0])
        elif command == 'test_file':
            parser = OptionParser(usage=("usage: %prog test_file path\n"
                'Open device, copy file specified by path to device and '
                'then eject device.'))
            options, args = parser.parse_args(args)
            if len(args) != 1:
                parser.print_help()
                return 1
            path = args[0]
            from calibre.ebooks.metadata.meta import get_metadata
            mi = get_metadata(open(path, 'rb'), path.rpartition('.')[-1].lower())
            print dev.upload_books([args[0]], [os.path.basename(args[0])],
                    end_session=False, metadata=[mi])
            dev.eject()
        else:
            parser.print_help()
            if getattr(dev, 'handle', False): dev.close()
            return 1
    except DeviceLocked:
        print >> sys.stderr, "The device is locked. Use the --unlock option"
    except (ArgumentError, DeviceError) as e:
        print >>sys.stderr, e
        return 1
    finally:
        shutdown_plugins()

    return 0