error_dialog(self, _('Invalid template'), '<p>' + _('The template "%s" is invalid:') % tmpl + '<br>' + str(err), show=True) return False # }}} if __name__ == '__main__': from calibre.gui2 import Application from calibre.devices.kobo.driver import KOBOTOUCH from calibre.devices.scanner import DeviceScanner s = DeviceScanner() s.scan() app = Application([]) debug_print("KOBOTOUCH:", KOBOTOUCH) dev = KOBOTOUCH(None) # dev.startup() # cd = dev.detect_managed_devices(s.devices) # dev.open(cd, 'test') cw = dev.config_widget() d = QDialog() d.l = QVBoxLayout() d.setLayout(d.l) d.l.addWidget(cw) bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) d.l.addWidget(bb)
return parent def develop(): from calibre.devices.scanner import DeviceScanner scanner = DeviceScanner() scanner.scan() dev = MTP_DEVICE(None) dev.startup() try: cd = dev.detect_managed_devices(scanner.devices) if cd is None: raise RuntimeError('No MTP device found') dev.open(cd, 'develop') pprint.pprint(dev.dev.storage_info) dev.filesystem_cache finally: dev.shutdown() if __name__ == '__main__': dev = MTP_DEVICE(None) dev.startup() from calibre.devices.scanner import DeviceScanner scanner = DeviceScanner() scanner.scan() devs = scanner.devices dev.debug_managed_device_detection(devs, sys.stdout) dev.set_debug_level(dev.LIBMTP_DEBUG_ALL) dev.shutdown()
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 OSError 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 OSError 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
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() 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() finally: sys.stdout = oldo sys.stderr = olde if plugins is None: for d in devplugins: try: d.shutdown() except: pass