Esempio n. 1
0
def get_connected_device():
    from calibre.customize.ui import device_plugins
    from calibre.devices.scanner import DeviceScanner
    dev = None
    scanner = DeviceScanner()
    scanner.scan()
    connected_devices = []
    for d in device_plugins():
        ok, det = scanner.is_device_connected(d)
        if ok:
            dev = d
            dev.reset(log_packets=False, detected_device=det)
            connected_devices.append((det, dev))

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

    for det, d in connected_devices:
        try:
            d.open(det, None)
        except:
            continue
        else:
            dev = d
            break
    return dev
Esempio n. 2
0
def get_connected_device():
    from calibre.customize.ui import device_plugins
    from calibre.devices.scanner import DeviceScanner
    dev = None
    scanner = DeviceScanner()
    scanner.scan()
    connected_devices = []
    for d in device_plugins():
        ok, det = scanner.is_device_connected(d)
        if ok:
            dev = d
            dev.reset(log_packets=False, detected_device=det)
            connected_devices.append((det, dev))

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

    for det, d in connected_devices:
        try:
            d.open(det, None)
        except:
            continue
        else:
            dev = d
            break
    return dev
Esempio n. 3
0
    def _find_device_books(self, book_lookup, log):
        '''Look for the Kindle and return the list of books on it'''
        dev = None
        scanner = DeviceScanner()
        scanner.scan()
        connected_devices = []
        for device in device_plugins():
            dev_connected = scanner.is_device_connected(device)
            if isinstance(dev_connected, tuple):
                device_ok, det = dev_connected
                if device_ok:
                    dev = device
                    connected_devices.append((det, dev))

        if dev is None:
            return None

        for det, device in connected_devices:
            try:
                device.open(det, None)
            except (NotImplementedError, TypeError):
                continue
            else:
                dev = device
                break

        self._num_of_formats_found_on_device = 0
        try:
            books = defaultdict(dict)
            for book in dev.books():
                uuid = getattr(book, 'uuid', None)
                if uuid in book_lookup:
                    book_id = book_lookup[uuid].book_id
                    fmt = book.path.split('.')[-1].lower()
                    if fmt not in self._settings['formats']:
                        continue
                    books[book_id][fmt] = {
                        'device_book': book.path,
                        'device_sdr':
                        '.'.join(book.path.split('.')[:-1]) + '.sdr'
                    }
                    self._num_of_formats_found_on_device += 1
            return books
        except (TypeError, AttributeError):
            self._num_of_formats_found_on_device = -1
            log(('{0} Device found but cannot be accessed. '
                 'It may have been ejected but not unplugged.').format(
                     datetime.now().strftime('%m-%d-%Y %H:%M:%S')))
            return None
    def _find_device_books(self, book_lookup, log):
        '''Look for the Kindle and return the list of books on it'''
        dev = None
        scanner = DeviceScanner()
        scanner.scan()
        connected_devices = []
        for device in device_plugins():
            dev_connected = scanner.is_device_connected(device)
            if isinstance(dev_connected, tuple):
                device_ok, det = dev_connected
                if device_ok:
                    dev = device
                    connected_devices.append((det, dev))

        if dev is None:
            return None

        for det, device in connected_devices:
            try:
                device.open(det, None)
            except (NotImplementedError, TypeError):
                continue
            else:
                dev = device
                break

        self._num_of_formats_found_on_device = 0
        try:
            books = defaultdict(dict)
            for book in dev.books():
                uuid = getattr(book, 'uuid', None)
                if book_lookup.has_key(uuid):
                    book_id = book_lookup[uuid].book_id
                    fmt = book.path.split('.')[-1].lower()
                    if fmt not in self._settings['formats']:
                        continue
                    books[book_id][fmt] = {'device_book': book.path,
                                           'device_sdr': '.'.join(book.path.split('.')[:-1]) + '.sdr'}
                    self._num_of_formats_found_on_device += 1
            return books
        except (TypeError, AttributeError):
            self._num_of_formats_found_on_device = -1
            log(('{0} Device found but cannot be accessed. '
                 'It may have been ejected but not unplugged.').format(datetime.now().strftime('%m-%d-%Y %H:%M:%S')))
            return None
Esempio n. 5
0
def debug(ioreg_to_tmp=False, buf=None, plugins=None, disabled_plugins=None):
    '''
    If plugins is None, then this method calls startup and shutdown on the
    device plugins. So if you are using it in a context where startup could
    already have been called (for example in the main GUI), pass in the list of
    device plugins as the plugins parameter.
    '''
    import textwrap
    from calibre.customize.ui import device_plugins, disabled_device_plugins
    from calibre.debug import print_basic_debug_info
    from calibre.devices.scanner import DeviceScanner
    from calibre.constants import iswindows, ismacos
    from calibre import prints
    from polyglot.io import PolyglotStringIO
    oldo, olde = sys.stdout, sys.stderr

    if buf is None:
        buf = PolyglotStringIO()
    sys.stdout = sys.stderr = buf
    out = partial(prints, file=buf)

    devplugins = device_plugins() if plugins is None else plugins
    devplugins = list(sorted(devplugins, key=lambda x: x.__class__.__name__))
    if plugins is None:
        for d in devplugins:
            try:
                d.startup()
            except:
                out('Startup failed for device plugin: %s' % d)

    if disabled_plugins is None:
        disabled_plugins = list(disabled_device_plugins())

    try:
        print_basic_debug_info(out=buf)
        s = DeviceScanner()
        s.scan()
        devices = (s.devices)
        if not iswindows:
            devices = [list(x) for x in devices]
            for d in devices:
                for i in range(3):
                    d[i] = hex(d[i])
        out('USB devices on system:')
        out(pprint.pformat(devices))

        ioreg = None
        if ismacos:
            from calibre.devices.usbms.device import Device
            mount = '\n'.join(
                repr(x) for x in Device.osx_run_mount().splitlines())
            drives = pprint.pformat(Device.osx_get_usb_drives())
            ioreg = 'Output from mount:\n' + mount + '\n\n'
            ioreg += 'Output from osx_get_usb_drives:\n' + drives + '\n\n'
            ioreg += Device.run_ioreg().decode('utf-8')
        connected_devices = []
        if disabled_plugins:
            out(
                '\nDisabled plugins:',
                textwrap.fill(' '.join(
                    [x.__class__.__name__ for x in disabled_plugins])))
            out(' ')
        else:
            out('\nNo disabled plugins')
        found_dev = False
        for dev in devplugins:
            if not dev.MANAGES_DEVICE_PRESENCE:
                continue
            out('Looking for devices of type:', dev.__class__.__name__)
            if dev.debug_managed_device_detection(s.devices, buf):
                found_dev = True
                break
            out(' ')

        if not found_dev:
            out('Looking for devices...')
            for dev in devplugins:
                if dev.MANAGES_DEVICE_PRESENCE:
                    continue
                connected, det = s.is_device_connected(dev, debug=True)
                if connected:
                    out('\t\tDetected possible device', dev.__class__.__name__)
                    connected_devices.append((dev, det))

            out(' ')
            errors = {}
            success = False
            out('Devices possibly connected:', end=' ')
            for dev, det in connected_devices:
                out(dev.name, end=', ')
            if not connected_devices:
                out('None', end='')
            out(' ')
            for dev, det in connected_devices:
                out('Trying to open', dev.name, '...', end=' ')
                dev.do_device_debug = True
                try:
                    dev.reset(detected_device=det)
                    dev.open(det, None)
                    out('OK')
                except:
                    import traceback
                    errors[dev] = traceback.format_exc()
                    out('failed')
                    continue
                dev.do_device_debug = False
                success = True
                if hasattr(dev, '_main_prefix'):
                    out('Main memory:', repr(dev._main_prefix))
                out('Total space:', dev.total_space())
                break
            if not success and errors:
                out('Opening of the following devices failed')
                for dev, msg in errors.items():
                    out(dev)
                    out(msg)
                    out(' ')

            if ioreg is not None:
                ioreg = 'IOREG Output\n' + ioreg
                out(' ')
                if ioreg_to_tmp:
                    lopen('/tmp/ioreg.txt', 'w').write(ioreg)
                    out('Dont forget to send the contents of /tmp/ioreg.txt')
                    out('You can open it with the command: open /tmp/ioreg.txt'
                        )
                else:
                    out(ioreg)

        if hasattr(buf, 'getvalue'):
            return buf.getvalue()
    finally:
        sys.stdout = oldo
        sys.stderr = olde
        if plugins is None:
            for d in devplugins:
                try:
                    d.shutdown()
                except:
                    pass
Esempio 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('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
Esempio n. 7
0
def debug(ioreg_to_tmp=False, buf=None, plugins=None,
        disabled_plugins=None):
    '''
    If plugins is None, then this method calls startup and shutdown on the
    device plugins. So if you are using it in a context where startup could
    already have been called (for example in the main GUI), pass in the list of
    device plugins as the plugins parameter.
    '''
    import textwrap
    from calibre.customize.ui import device_plugins, disabled_device_plugins
    from calibre.debug import print_basic_debug_info
    from calibre.devices.scanner import DeviceScanner
    from calibre.constants import iswindows, isosx
    from calibre import prints
    from polyglot.io import PolyglotBytesIO
    oldo, olde = sys.stdout, sys.stderr

    if buf is None:
        buf = PolyglotBytesIO()
    sys.stdout = sys.stderr = buf
    out = partial(prints, file=buf)

    devplugins = device_plugins() if plugins is None else plugins
    devplugins = list(sorted(devplugins, key=lambda x: x.__class__.__name__))
    if plugins is None:
        for d in devplugins:
            try:
                d.startup()
            except:
                out('Startup failed for device plugin: %s'%d)

    if disabled_plugins is None:
        disabled_plugins = list(disabled_device_plugins())

    try:
        print_basic_debug_info(out=buf)
        s = DeviceScanner()
        s.scan()
        devices = (s.devices)
        if not iswindows:
            devices = [list(x) for x in devices]
            for d in devices:
                for i in range(3):
                    d[i] = hex(d[i])
        out('USB devices on system:')
        out(pprint.pformat(devices))

        ioreg = None
        if isosx:
            from calibre.devices.usbms.device import Device
            mount = '\n'.join(repr(x) for x in Device.osx_run_mount().splitlines())
            drives = pprint.pformat(Device.osx_get_usb_drives())
            ioreg = 'Output from mount:\n'+mount+'\n\n'
            ioreg += 'Output from osx_get_usb_drives:\n'+drives+'\n\n'
            ioreg += Device.run_ioreg()
        connected_devices = []
        if disabled_plugins:
            out('\nDisabled plugins:', textwrap.fill(' '.join([x.__class__.__name__ for x in
                disabled_plugins])))
            out(' ')
        else:
            out('\nNo disabled plugins')
        found_dev = False
        for dev in devplugins:
            if not dev.MANAGES_DEVICE_PRESENCE:
                continue
            out('Looking for devices of type:', dev.__class__.__name__)
            if dev.debug_managed_device_detection(s.devices, buf):
                found_dev = True
                break
            out(' ')

        if not found_dev:
            out('Looking for devices...')
            for dev in devplugins:
                if dev.MANAGES_DEVICE_PRESENCE:
                    continue
                connected, det = s.is_device_connected(dev, debug=True)
                if connected:
                    out('\t\tDetected possible device', dev.__class__.__name__)
                    connected_devices.append((dev, det))

            out(' ')
            errors = {}
            success = False
            out('Devices possibly connected:', end=' ')
            for dev, det in connected_devices:
                out(dev.name, end=', ')
            if not connected_devices:
                out('None', end='')
            out(' ')
            for dev, det in connected_devices:
                out('Trying to open', dev.name, '...', end=' ')
                dev.do_device_debug = True
                try:
                    dev.reset(detected_device=det)
                    dev.open(det, None)
                    out('OK')
                except:
                    import traceback
                    errors[dev] = traceback.format_exc()
                    out('failed')
                    continue
                dev.do_device_debug = False
                success = True
                if hasattr(dev, '_main_prefix'):
                    out('Main memory:', repr(dev._main_prefix))
                out('Total space:', dev.total_space())
                break
            if not success and errors:
                out('Opening of the following devices failed')
                for dev,msg in errors.items():
                    out(dev)
                    out(msg)
                    out(' ')

            if ioreg is not None:
                ioreg = 'IOREG Output\n'+ioreg
                out(' ')
                if ioreg_to_tmp:
                    lopen('/tmp/ioreg.txt', 'wb').write(ioreg)
                    out('Dont forget to send the contents of /tmp/ioreg.txt')
                    out('You can open it with the command: open /tmp/ioreg.txt')
                else:
                    out(ioreg)

        if hasattr(buf, 'getvalue'):
            return buf.getvalue().decode('utf-8', 'replace')
    finally:
        sys.stdout = oldo
        sys.stderr = olde
        if plugins is None:
            for d in devplugins:
                try:
                    d.shutdown()
                except:
                    pass
Esempio n. 8
0
def debug(ioreg_to_tmp=False, buf=None):
    import textwrap
    from calibre.customize.ui import device_plugins
    from calibre.devices.scanner import DeviceScanner, win_pnp_drives
    from calibre.constants import iswindows, isosx, __version__
    from calibre import prints
    oldo, olde = sys.stdout, sys.stderr

    if buf is None:
        buf = StringIO()
    sys.stdout = sys.stderr = buf

    try:
        out = partial(prints, file=buf)
        out('Version:', __version__)
        s = DeviceScanner()
        s.scan()
        devices = (s.devices)
        if not iswindows:
            devices = [list(x) for x in devices]
            for d in devices:
                for i in range(3):
                    d[i] = hex(d[i])
        out('USB devices on system:')
        out(pprint.pformat(devices))
        if iswindows:
            drives = win_pnp_drives(debug=True)
            out('Drives detected:')
            for drive in sorted(drives.keys(),
                    key=operator.attrgetter('order')):
                prints(u'\t(%d)'%drive.order, drive, '~', drives[drive])

        ioreg = None
        if isosx:
            from calibre.devices.usbms.device import Device
            mount = repr(Device.osx_run_mount())
            drives = pprint.pformat(Device.osx_get_usb_drives())
            ioreg = 'Output from mount:\n'+mount+'\n\n'
            ioreg += 'Output from osx_get_usb_drives:\n'+drives+'\n\n'
            ioreg += Device.run_ioreg()
        connected_devices = []
        devplugins = list(sorted(device_plugins(), cmp=lambda
                x,y:cmp(x.__class__.__name__, y.__class__.__name__)))
        out('Available plugins:', textwrap.fill(' '.join([x.__class__.__name__ for x in
            devplugins])))
        out(' ')
        out('Looking for devices...')
        for dev in devplugins:
            connected, det = s.is_device_connected(dev, debug=True)
            if connected:
                out('\t\tDetected possible device', dev.__class__.__name__)
                connected_devices.append((dev, det))

        out(' ')
        errors = {}
        success = False
        out('Devices possibly connected:', end=' ')
        for dev, det in connected_devices:
            out(dev.name, end=', ')
        if not connected_devices:
            out('None', end='')
        out(' ')
        for dev, det in connected_devices:
            out('Trying to open', dev.name, '...', end=' ')
            try:
                dev.reset(detected_device=det)
                dev.open(det, None)
                out('OK')
            except:
                import traceback
                errors[dev] = traceback.format_exc()
                out('failed')
                continue
            success = True
            if hasattr(dev, '_main_prefix'):
                out('Main memory:', repr(dev._main_prefix))
            out('Total space:', dev.total_space())
            break
        if not success and errors:
            out('Opening of the following devices failed')
            for dev,msg in errors.items():
                out(dev)
                out(msg)
                out(' ')

        if ioreg is not None:
            ioreg = 'IOREG Output\n'+ioreg
            out(' ')
            if ioreg_to_tmp:
                open('/tmp/ioreg.txt', 'wb').write(ioreg)
                out('Dont forget to send the contents of /tmp/ioreg.txt')
                out('You can open it with the command: open /tmp/ioreg.txt')
            else:
                out(ioreg)

        if hasattr(buf, 'getvalue'):
            return buf.getvalue().decode('utf-8')
    finally:
        sys.stdout = oldo
        sys.stderr = olde
Esempio n. 9
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
Esempio n. 10
0
def debug(ioreg_to_tmp=False, buf=None):
    import textwrap
    from calibre.customize.ui import device_plugins
    from calibre.devices.scanner import DeviceScanner, win_pnp_drives
    from calibre.constants import iswindows, isosx, __version__
    from calibre import prints
    oldo, olde = sys.stdout, sys.stderr

    if buf is None:
        buf = StringIO()
    sys.stdout = sys.stderr = buf

    try:
        out = partial(prints, file=buf)
        out('Version:', __version__)
        s = DeviceScanner()
        s.scan()
        devices = (s.devices)
        if not iswindows:
            devices = [list(x) for x in devices]
            for d in devices:
                for i in range(3):
                    d[i] = hex(d[i])
        out('USB devices on system:')
        out(pprint.pformat(devices))
        if iswindows:
            drives = win_pnp_drives(debug=True)
            out('Drives detected:')
            for drive in sorted(drives.keys(),
                                key=operator.attrgetter('order')):
                prints(u'\t(%d)' % drive.order, drive, '~', drives[drive])

        ioreg = None
        if isosx:
            from calibre.devices.usbms.device import Device
            mount = repr(Device.osx_run_mount())
            drives = pprint.pformat(Device.osx_get_usb_drives())
            ioreg = 'Output from mount:\n' + mount + '\n\n'
            ioreg += 'Output from osx_get_usb_drives:\n' + drives + '\n\n'
            ioreg += Device.run_ioreg()
        connected_devices = []
        devplugins = list(
            sorted(device_plugins(),
                   cmp=lambda x, y: cmp(x.__class__.__name__, y.__class__.
                                        __name__)))
        out(
            'Available plugins:',
            textwrap.fill(' '.join([x.__class__.__name__
                                    for x in devplugins])))
        out(' ')
        out('Looking for devices...')
        for dev in devplugins:
            connected, det = s.is_device_connected(dev, debug=True)
            if connected:
                out('\t\tDetected possible device', dev.__class__.__name__)
                connected_devices.append((dev, det))

        out(' ')
        errors = {}
        success = False
        out('Devices possibly connected:', end=' ')
        for dev, det in connected_devices:
            out(dev.name, end=', ')
        if not connected_devices:
            out('None', end='')
        out(' ')
        for dev, det in connected_devices:
            out('Trying to open', dev.name, '...', end=' ')
            try:
                dev.reset(detected_device=det)
                dev.open(det, None)
                out('OK')
            except:
                import traceback
                errors[dev] = traceback.format_exc()
                out('failed')
                continue
            success = True
            if hasattr(dev, '_main_prefix'):
                out('Main memory:', repr(dev._main_prefix))
            out('Total space:', dev.total_space())
            break
        if not success and errors:
            out('Opening of the following devices failed')
            for dev, msg in errors.items():
                out(dev)
                out(msg)
                out(' ')

        if ioreg is not None:
            ioreg = 'IOREG Output\n' + ioreg
            out(' ')
            if ioreg_to_tmp:
                open('/tmp/ioreg.txt', 'wb').write(ioreg)
                out('Dont forget to send the contents of /tmp/ioreg.txt')
                out('You can open it with the command: open /tmp/ioreg.txt')
            else:
                out(ioreg)

        if hasattr(buf, 'getvalue'):
            return buf.getvalue().decode('utf-8')
    finally:
        sys.stdout = oldo
        sys.stderr = olde