From 283e18c0bc8eb4d833d76492d184e1e4c657316a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 17 Dec 2009 12:13:54 -0700 Subject: [PATCH] New recipe for Alberto Montt en dosis diarias by Darko Miletic. Implements #4242 --- resources/recipes/dosisdiarias.recipe | 31 ++++++ src/calibre/devices/__init__.py | 97 ++++++++++++++++++- src/calibre/devices/eb600/driver.py | 6 +- src/calibre/devices/usbms/device.py | 4 +- src/calibre/devices/usbms/driver.py | 2 +- src/calibre/gui2/dialogs/config/__init__.py | 6 ++ src/calibre/gui2/dialogs/config/config.ui | 31 +++--- .../gui2/dialogs/config/device_debug.py | 52 ++++++++++ src/calibre/manual/faq.rst | 19 ++-- 9 files changed, 221 insertions(+), 27 deletions(-) create mode 100644 resources/recipes/dosisdiarias.recipe create mode 100644 src/calibre/gui2/dialogs/config/device_debug.py diff --git a/resources/recipes/dosisdiarias.recipe b/resources/recipes/dosisdiarias.recipe new file mode 100644 index 0000000000..2976428868 --- /dev/null +++ b/resources/recipes/dosisdiarias.recipe @@ -0,0 +1,31 @@ +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic ' +''' +http://www.dosisdiarias.com +''' + +from calibre.web.feeds.recipes import BasicNewsRecipe + +class DosisDiarias(BasicNewsRecipe): + title = 'Alberto Montt en dosis diarias' + __author__ = 'Darko Miletic' + description = 'Mire sin compromiso y si le gusta vuelva' + oldest_article = 5 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = True + encoding = 'utf-8' + publisher = 'Alberto Montt' + category = 'comic, blog, spanish' + language = 'es' + + conversion_options = { + 'comments' : description + ,'tags' : category + ,'language' : language + ,'publisher' : publisher + } + + remove_tags = [dict(name='div',attrs={'class':'feedflare'})] + + feeds = [(u'Dosis diaria', u'http://feeds.feedburner.com/montt' )] diff --git a/src/calibre/devices/__init__.py b/src/calibre/devices/__init__.py index 874de7c070..e0f0208d9b 100644 --- a/src/calibre/devices/__init__.py +++ b/src/calibre/devices/__init__.py @@ -5,7 +5,9 @@ __copyright__ = '2008, Kovid Goyal ' Device drivers. ''' -import time +import sys, os, time, pprint +from functools import partial +from StringIO import StringIO DAY_MAP = dict(Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6) MONTH_MAP = dict(Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9, Oct=10, Nov=11, Dec=12) @@ -24,3 +26,96 @@ def strftime(epoch, zone=time.gmtime): src[0] = INVERSE_DAY_MAP[int(src[0][:-1])]+',' src[2] = INVERSE_MONTH_MAP[int(src[2])] return ' '.join(src) + +def debug(): + from calibre.customize.ui import device_plugins + from calibre.devices.scanner import DeviceScanner + from calibre.constants import iswindows, isosx, __version__ + from calibre import prints + oldo, olde = sys.stdout, sys.stderr + + 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(i) + out('USB devices on system:') + out(pprint.pformat(devices)) + if iswindows: + if iswindows: + import pythoncom + pythoncom.CoInitialize() + try: + wmi = __import__('wmi', globals(), locals(), [], -1) + drives = [] + out('Drives detected:') + out('\t', '(ID, Partitions, Drive letter)') + for drive in wmi.WMI(find_classes=False).Win32_DiskDrive(): + if drive.Partitions == 0: + continue + try: + partition = drive.associators("Win32_DiskDriveToDiskPartition")[0] + logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0] + prefix = logical_disk.DeviceID+os.sep + drives.append((str(drive.PNPDeviceID), drive.Index, prefix)) + except IndexError: + drives.append((str(drive.PNPDeviceID), 'No mount points found')) + for drive in drives: + out('\t', drive) + finally: + pythoncom.CoUninitialize() + + ioreg = None + if isosx: + from calibre.devices.usbms.device import Device + ioreg = Device.run_ioreg() + connected_devices = [] + for dev in device_plugins(): + out('Looking for', dev.__class__.__name__) + connected = s.is_device_connected(dev, debug=True) + if connected: + connected_devices.append(dev) + + errors = {} + success = False + for dev in connected_devices: + out('Device possibly connected:', dev.__class__.name) + out('Trying to open device...', end=' ') + try: + dev.open() + 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: + out(' ') + out('IOREG Output') + out(ioreg) + + return buf.getvalue().decode('utf-8') + finally: + sys.stdout = oldo + sys.stderr = olde + diff --git a/src/calibre/devices/eb600/driver.py b/src/calibre/devices/eb600/driver.py index 28bcd7418e..76789fa675 100644 --- a/src/calibre/devices/eb600/driver.py +++ b/src/calibre/devices/eb600/driver.py @@ -117,7 +117,7 @@ class ITALICA(EB600): name = 'Italica Device Interface' gui_name = 'Italica' - FORMATS = ['epub', 'pdf', 'txt'] + FORMATS = ['epub', 'rtf', 'fb2', 'html', 'prc', 'mobi', 'pdf', 'txt'] VENDOR_NAME = 'ITALICA' WINDOWS_MAIN_MEM = 'EREADER' @@ -125,3 +125,7 @@ class ITALICA(EB600): OSX_MAIN_MEM = 'Italica eReader Media' OSX_CARD_A_MEM = OSX_MAIN_MEM + + MAIN_MEMORY_VOLUME_LABEL = 'Italica Main Memory' + STORAGE_CARD_VOLUME_LABEL = 'Italica Storage Card' + diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index 64ce925530..8ae401591e 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -711,7 +711,9 @@ class Device(DeviceConfig, DevicePlugin): candidates = self.get_main_ebook_dir() if isinstance(candidates, basestring): candidates = [candidates] - candidates = [os.path.join(self._main_prefix, *(x.split('/'))) for x + candidates = [ + ((os.path.join(self._main_prefix, *(x.split('/')))) if x else + self._main_prefix) for x in candidates] existing = [x for x in candidates if os.path.exists(x)] if not existing: diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index 51b1cc7144..8d2416511c 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -63,7 +63,7 @@ class USBMS(CLI, Device): if isinstance(ebook_dirs, basestring): ebook_dirs = [ebook_dirs] for ebook_dir in ebook_dirs: - ebook_dir = os.path.join(prefix, *(ebook_dir.split('/'))) + ebook_dir = os.path.join(prefix, *(ebook_dir.split('/'))) if ebook_dir else prefix if not os.path.exists(ebook_dir): continue # Get all books in the ebook_dir directory if self.SUPPORTS_SUB_DIRS: diff --git a/src/calibre/gui2/dialogs/config/__init__.py b/src/calibre/gui2/dialogs/config/__init__.py index 2e647781c1..ea9ab1af50 100644 --- a/src/calibre/gui2/dialogs/config/__init__.py +++ b/src/calibre/gui2/dialogs/config/__init__.py @@ -457,6 +457,12 @@ class ConfigDialog(ResizableDialog, Ui_Dialog): self.open_config_dir) self.opt_get_social_metadata.setChecked(config['get_social_metadata']) self.opt_enforce_cpu_limit.setChecked(config['enforce_cpu_limit']) + self.device_detection_button.clicked.connect(self.debug_device_detection) + + def debug_device_detection(self): + from calibre.gui2.dialogs.config.device_debug import DebugDevice + d = DebugDevice(self) + d.exec_() def open_config_dir(self): from calibre.utils.config import config_dir diff --git a/src/calibre/gui2/dialogs/config/config.ui b/src/calibre/gui2/dialogs/config/config.ui index fc7c6b6635..77c1d9eccd 100644 --- a/src/calibre/gui2/dialogs/config/config.ui +++ b/src/calibre/gui2/dialogs/config/config.ui @@ -15,7 +15,7 @@ Preferences - + :/images/config.svg:/images/config.svg @@ -148,7 +148,7 @@ ... - + :/images/mimetypes/dir.svg:/images/mimetypes/dir.svg @@ -285,7 +285,7 @@ ... - + :/images/arrow-up.svg:/images/arrow-up.svg @@ -309,7 +309,7 @@ ... - + :/images/arrow-down.svg:/images/arrow-down.svg @@ -473,7 +473,7 @@ ... - + :/images/arrow-up.svg:/images/arrow-up.svg @@ -497,7 +497,7 @@ ... - + :/images/arrow-down.svg:/images/arrow-down.svg @@ -557,7 +557,7 @@ &Add email - + :/images/plus.svg:/images/plus.svg @@ -584,7 +584,7 @@ &Remove email - + :/images/minus.svg:/images/minus.svg @@ -649,21 +649,21 @@ - + &Check database integrity - + &Install command line tools - + Open calibre &configuration directory @@ -677,6 +677,13 @@ + + + + Debug &device detection + + + @@ -966,7 +973,7 @@ ... - + :/images/document_open.svg:/images/document_open.svg diff --git a/src/calibre/gui2/dialogs/config/device_debug.py b/src/calibre/gui2/dialogs/config/device_debug.py new file mode 100644 index 0000000000..ae4a8e4f45 --- /dev/null +++ b/src/calibre/gui2/dialogs/config/device_debug.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import with_statement + +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + +from PyQt4.Qt import QDialog, QVBoxLayout, QPlainTextEdit, QTimer, \ + QDialogButtonBox, QPushButton, QApplication, QIcon + +class DebugDevice(QDialog): + + def __init__(self, parent=None): + QDialog.__init__(self, parent) + self._layout = QVBoxLayout(self) + self.setLayout(self._layout) + self.log = QPlainTextEdit(self) + self._layout.addWidget(self.log) + self.log.setPlainText(_('Getting debug information')+'...') + self.copy = QPushButton(_('Copy to &clipboard')) + self.copy.setDefault(True) + self.setWindowTitle(_('Debug device detection')) + self.setWindowIcon(QIcon(I('debug.svg'))) + self.copy.clicked.connect(self.copy_to_clipboard) + self.ok = QPushButton('&OK') + self.ok.setAutoDefault(False) + self.ok.clicked.connect(self.accept) + self.bbox = QDialogButtonBox(self) + self.bbox.addButton(self.copy, QDialogButtonBox.ActionRole) + self.bbox.addButton(self.ok, QDialogButtonBox.AcceptRole) + self._layout.addWidget(self.bbox) + self.resize(750, 500) + self.bbox.setEnabled(False) + QTimer.singleShot(1000, self.debug) + + def debug(self): + try: + from calibre.devices import debug + raw = debug() + self.log.setPlainText(raw) + finally: + self.bbox.setEnabled(True) + + def copy_to_clipboard(self): + QApplication.clipboard().setText(self.log.toPlainText()) + +if __name__ == '__main__': + app = QApplication([]) + d = DebugDevice() + d.exec_() diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index c15cd20fd2..f40b867a64 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -81,7 +81,7 @@ Device Integration What devices does |app| support? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -At the moment |app| has full support for the SONY PRS 300/500/505/600/700, Barnes & Noble Nook, Cybook Gen 3/Opus, Amazon Kindle 1/2/DX, Netronix EB600, Ectaco Jetbook, BeBook/BeBook Mini, Irex Illiad/DR1000, Foxit eSlick, PocketBook 360, Android phones and the iPhone. In addition, using the :guilabel:`Save to disk` function you can use it with any ebook reader that exports itself as a USB disk. +At the moment |app| has full support for the SONY PRS 300/500/505/600/700, Barnes & Noble Nook, Cybook Gen 3/Opus, Amazon Kindle 1/2/DX, Netronix EB600, Ectaco Jetbook, BeBook/BeBook Mini, Irex Illiad/DR1000, Foxit eSlick, PocketBook 360, Italica, various Android phones and the iPhone. In addition, using the :guilabel:`Save to disk` function you can use it with any ebook reader that exports itself as a USB disk. How can I help get my device supported in |app|? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -91,17 +91,14 @@ We just need some information from you: * What e-book formats does your device support? * Is there a special directory on the device in which all e-book files should be placed? - * We also need the output from running the following command in a terminal, both with the device - connected and without:: + * We also need information about your device that |app| will collect automatically. First, if your + device supports SD cards, insert them. Then connect your device. In calibre go to Preferences->Advanced + and click the "Debug device detection" button. This will create some debug output. Copy it to a file + and repeat the process, this time with your device disconnected. + * Send both the above outputs to us with the other information and we will write a device driver for your + device. - calibre-debug -d - - * If your device supports SD cards, run the above command with the cards inserted. - -To run the above command, on Windows you should use the full path to calibre-debug.exe -On OSX, you should go to Preferences->Advanced and click "Install command line tools". - -Once you send us the output for a particular operating system, support for the device +Once you send us the output for a particular operating system, support for the device in that operating system will appear in the next release of |app|.