mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Pull from trunk
This commit is contained in:
commit
47ab2595f4
@ -5,7 +5,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
Device drivers.
|
Device drivers.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, time, pprint
|
import sys, time, pprint, operator
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
@ -82,7 +82,9 @@ def debug(ioreg_to_tmp=False, buf=None):
|
|||||||
if iswindows:
|
if iswindows:
|
||||||
drives = win_pnp_drives(debug=True)
|
drives = win_pnp_drives(debug=True)
|
||||||
out('Drives detected:')
|
out('Drives detected:')
|
||||||
out(pprint.pformat(drives))
|
for drive in sorted(drives.keys(),
|
||||||
|
key=operator.attrgetter('order')):
|
||||||
|
prints(u'\t(%d)'%drive.order, drive, '~', drives[drive])
|
||||||
|
|
||||||
ioreg = None
|
ioreg = None
|
||||||
if isosx:
|
if isosx:
|
||||||
|
@ -35,15 +35,6 @@ class README(USBMS):
|
|||||||
|
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
def linux_swap_drives(self, drives):
|
def linux_swap_drives(self, drives):
|
||||||
if len(drives) < 2: return drives
|
if len(drives) < 2: return drives
|
||||||
drives = list(drives)
|
drives = list(drives)
|
||||||
|
@ -48,15 +48,6 @@ class EB600(USBMS):
|
|||||||
EBOOK_DIR_CARD_A = ''
|
EBOOK_DIR_CARD_A = ''
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
|
|
||||||
class COOL_ER(EB600):
|
class COOL_ER(EB600):
|
||||||
|
|
||||||
|
@ -36,12 +36,4 @@ class EDGE(USBMS):
|
|||||||
EBOOK_DIR_MAIN = 'download'
|
EBOOK_DIR_MAIN = 'download'
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
|
@ -36,12 +36,4 @@ class ESLICK(USBMS):
|
|||||||
|
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
|
@ -39,23 +39,6 @@ class HANLINV3(USBMS):
|
|||||||
|
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card > main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
if card and not main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = None
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
def windows_open_callback(self, drives):
|
|
||||||
if 'main' not in drives and 'carda' in drives:
|
|
||||||
drives['main'] = drives.pop('carda')
|
|
||||||
return drives
|
|
||||||
|
|
||||||
def osx_sort_names(self, names):
|
def osx_sort_names(self, names):
|
||||||
main = names.get('main', None)
|
main = names.get('main', None)
|
||||||
@ -129,13 +112,4 @@ class BOOX(HANLINV3):
|
|||||||
EBOOK_DIR_CARD_A = 'MyBooks'
|
EBOOK_DIR_CARD_A = 'MyBooks'
|
||||||
|
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,12 +36,4 @@ class IRIVER_STORY(USBMS):
|
|||||||
|
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_open_callback(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
|
@ -80,11 +80,3 @@ class JETBOOK(USBMS):
|
|||||||
|
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
@ -77,14 +77,6 @@ class NOOK(USBMS):
|
|||||||
with open('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile:
|
with open('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile:
|
||||||
coverfile.write(coverdata)
|
coverfile.write(coverdata)
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
def sanitize_path_components(self, components):
|
def sanitize_path_components(self, components):
|
||||||
return [x.replace('#', '_') for x in components]
|
return [x.replace('#', '_') for x in components]
|
||||||
|
@ -5,7 +5,7 @@ Device scanner that fetches list of devices on system ina platform dependent
|
|||||||
manner.
|
manner.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, os
|
import sys, os, re
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
|
|
||||||
from calibre import iswindows, isosx, plugins, islinux
|
from calibre import iswindows, isosx, plugins, islinux
|
||||||
@ -23,6 +23,14 @@ elif isosx:
|
|||||||
except:
|
except:
|
||||||
raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1])
|
raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1])
|
||||||
|
|
||||||
|
class Drive(str):
|
||||||
|
|
||||||
|
def __new__(self, val, order=0):
|
||||||
|
typ = str.__new__(self, val)
|
||||||
|
typ.order = order
|
||||||
|
return typ
|
||||||
|
|
||||||
|
|
||||||
class WinPNPScanner(object):
|
class WinPNPScanner(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -45,6 +53,13 @@ class WinPNPScanner(object):
|
|||||||
finally:
|
finally:
|
||||||
win32api.SetErrorMode(oldError)
|
win32api.SetErrorMode(oldError)
|
||||||
|
|
||||||
|
def drive_order(self, pnp_id):
|
||||||
|
order = 0
|
||||||
|
match = re.search(r'REV_.*?&(\d+)', pnp_id)
|
||||||
|
if match is not None:
|
||||||
|
order = int(match.group(1))
|
||||||
|
return order
|
||||||
|
|
||||||
def __call__(self, debug=False):
|
def __call__(self, debug=False):
|
||||||
if self.scanner is None:
|
if self.scanner is None:
|
||||||
return {}
|
return {}
|
||||||
@ -66,7 +81,7 @@ class WinPNPScanner(object):
|
|||||||
val = [x.upper() for x in val]
|
val = [x.upper() for x in val]
|
||||||
val = [x for x in val if 'USBSTOR' in x]
|
val = [x for x in val if 'USBSTOR' in x]
|
||||||
if val:
|
if val:
|
||||||
ans[key+':\\'] = val[-1]
|
ans[Drive(key+':\\', order=self.drive_order(val[-1]))] = val[-1]
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
win_pnp_drives = WinPNPScanner()
|
win_pnp_drives = WinPNPScanner()
|
||||||
|
@ -30,14 +30,6 @@ class TECLAST_K3(USBMS):
|
|||||||
EBOOK_DIR_CARD_A = ''
|
EBOOK_DIR_CARD_A = ''
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
main = drives.get('main', None)
|
|
||||||
card = drives.get('carda', None)
|
|
||||||
if card and main and card < main:
|
|
||||||
drives['main'] = card
|
|
||||||
drives['carda'] = main
|
|
||||||
|
|
||||||
return drives
|
|
||||||
|
|
||||||
class NEWSMY(TECLAST_K3):
|
class NEWSMY(TECLAST_K3):
|
||||||
name = 'Newsmy device interface'
|
name = 'Newsmy device interface'
|
||||||
@ -50,9 +42,6 @@ class NEWSMY(TECLAST_K3):
|
|||||||
WINDOWS_MAIN_MEM = 'NEWSMY'
|
WINDOWS_MAIN_MEM = 'NEWSMY'
|
||||||
WINDOWS_CARD_A_MEM = 'USBDISK____SD'
|
WINDOWS_CARD_A_MEM = 'USBDISK____SD'
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
|
||||||
return drives
|
|
||||||
|
|
||||||
class IPAPYRUS(TECLAST_K3):
|
class IPAPYRUS(TECLAST_K3):
|
||||||
|
|
||||||
name = 'iPapyrus device interface'
|
name = 'iPapyrus device interface'
|
||||||
|
@ -11,13 +11,7 @@ intended to be subclassed with the relevant parts implemented for a particular
|
|||||||
device. This class handles device detection.
|
device. This class handles device detection.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os, subprocess, time, re, sys, glob, operator
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import glob
|
|
||||||
|
|
||||||
from itertools import repeat
|
from itertools import repeat
|
||||||
|
|
||||||
from calibre.devices.interface import DevicePlugin
|
from calibre.devices.interface import DevicePlugin
|
||||||
@ -62,6 +56,8 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
BCD = None
|
BCD = None
|
||||||
|
|
||||||
VENDOR_NAME = None
|
VENDOR_NAME = None
|
||||||
|
|
||||||
|
# These can be None, string, list of strings or compiled regex
|
||||||
WINDOWS_MAIN_MEM = None
|
WINDOWS_MAIN_MEM = None
|
||||||
WINDOWS_CARD_A_MEM = None
|
WINDOWS_CARD_A_MEM = None
|
||||||
WINDOWS_CARD_B_MEM = None
|
WINDOWS_CARD_B_MEM = None
|
||||||
@ -246,21 +242,26 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
drives.get('main', None) is None:
|
drives.get('main', None) is None:
|
||||||
drives['main'] = drives.pop('carda')
|
drives['main'] = drives.pop('carda')
|
||||||
|
|
||||||
drives = self.windows_open_callback(drives)
|
|
||||||
|
|
||||||
if drives.get('main', None) is None:
|
if drives.get('main', None) is None:
|
||||||
raise DeviceError(
|
raise DeviceError(
|
||||||
_('Unable to detect the %s disk drive. Try rebooting.') %
|
_('Unable to detect the %s disk drive. Try rebooting.') %
|
||||||
self.__class__.__name__)
|
self.__class__.__name__)
|
||||||
|
|
||||||
|
# Sort drives by their PNP drive numbers if the CARD and MAIN
|
||||||
|
# MEM strings are identical
|
||||||
|
if self.WINDOWS_MAIN_MEM in (self.WINDOWS_CARD_A_MEM,
|
||||||
|
self.WINDOWS_CARD_B_MEM) or \
|
||||||
|
self.WINDOWS_CARD_A_MEM == self.WINDOWS_CARD_B_MEM:
|
||||||
|
letters = sorted(drives.values(), key=operator.attrgetter('order'))
|
||||||
|
drives = {}
|
||||||
|
for which, letter in zip(['main', 'carda', 'cardb'], letters):
|
||||||
|
drives[which] = letter
|
||||||
|
|
||||||
drives = self.windows_sort_drives(drives)
|
drives = self.windows_sort_drives(drives)
|
||||||
self._main_prefix = drives.get('main')
|
self._main_prefix = drives.get('main')
|
||||||
self._card_a_prefix = drives.get('carda', None)
|
self._card_a_prefix = drives.get('carda', None)
|
||||||
self._card_b_prefix = drives.get('cardb', None)
|
self._card_b_prefix = drives.get('cardb', None)
|
||||||
|
|
||||||
def windows_open_callback(self, drives):
|
|
||||||
return drives
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run_ioreg(cls, raw=None):
|
def run_ioreg(cls, raw=None):
|
||||||
if raw is not None:
|
if raw is not None:
|
||||||
|
@ -121,11 +121,27 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
if not pre.text and len(pre) == 0:
|
if not pre.text and len(pre) == 0:
|
||||||
pre.tag = 'div'
|
pre.tag = 'div'
|
||||||
|
|
||||||
|
def upshift_markup(self):
|
||||||
|
'Upgrade markup to comply with XHTML 1.1 where possible'
|
||||||
|
from calibre.ebooks.oeb.base import XPath
|
||||||
|
for x in self.oeb.spine:
|
||||||
|
root = x.data
|
||||||
|
body = XPath('//h:body')(root)
|
||||||
|
if body:
|
||||||
|
body = body[0]
|
||||||
|
|
||||||
|
if not hasattr(body, 'xpath'):
|
||||||
|
continue
|
||||||
|
for u in XPath('//h:u')(root):
|
||||||
|
u.tag = 'span'
|
||||||
|
u.set('style', 'text-decoration:underline')
|
||||||
|
|
||||||
def convert(self, oeb, output_path, input_plugin, opts, log):
|
def convert(self, oeb, output_path, input_plugin, opts, log):
|
||||||
self.log, self.opts, self.oeb = log, opts, oeb
|
self.log, self.opts, self.oeb = log, opts, oeb
|
||||||
|
|
||||||
self.workaround_ade_quirks()
|
self.workaround_ade_quirks()
|
||||||
self.workaround_webkit_quirks()
|
self.workaround_webkit_quirks()
|
||||||
|
self.upshift_markup()
|
||||||
from calibre.ebooks.oeb.transforms.rescale import RescaleImages
|
from calibre.ebooks.oeb.transforms.rescale import RescaleImages
|
||||||
RescaleImages()(oeb, opts)
|
RescaleImages()(oeb, opts)
|
||||||
|
|
||||||
|
@ -530,6 +530,7 @@ class Application(QApplication):
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
opacity: 200;
|
opacity: 200;
|
||||||
background-color: #e1e1ff;
|
background-color: #e1e1ff;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user