mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Sync to trunk.
This commit is contained in:
commit
b61f5fcd3b
@ -4,6 +4,41 @@
|
||||
# for important features/bug fixes.
|
||||
# Also, each release can have new and improved recipes.
|
||||
|
||||
- version: 0.6.31
|
||||
date: 2009-12-27
|
||||
|
||||
new features:
|
||||
- title: "Support for the SONY PRS 900 and the Airis dBook"
|
||||
type: major
|
||||
|
||||
- title: "Device detection on OS X now directly queries the IOKit registry instead of parsing the output of the ioreg command."
|
||||
description: >
|
||||
"The logic for device detection in OS X is very similar to that in linux. This means that if a windows driver
|
||||
for a device is written, it should work with no modification on both OS X and Linux."
|
||||
|
||||
bug fixes:
|
||||
- title: "Fix a major regression in the 0.6.30 news download system that caused a lot of recipes to fail"
|
||||
|
||||
- title: "Make PRS 500 driver thread safe."
|
||||
tickets: [4307]
|
||||
|
||||
- title: "Fix ebook viewer not working when launched as standalone program to view PDF files on windows"
|
||||
|
||||
- title: "PDB Output: Fix italics"
|
||||
|
||||
|
||||
new recipes:
|
||||
|
||||
- title: The Hartford Courant
|
||||
author: Being
|
||||
|
||||
- title: National Post
|
||||
author: Nick Redding
|
||||
|
||||
- title: The Columbus Dispatch
|
||||
author: kwetal
|
||||
|
||||
|
||||
- version: 0.6.30
|
||||
date: 2009-12-26
|
||||
|
||||
|
90
resources/recipes/hartford_courant.recipe
Normal file
90
resources/recipes/hartford_courant.recipe
Normal file
@ -0,0 +1,90 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class ChicagoTribune(BasicNewsRecipe):
|
||||
|
||||
title = 'The Hartford Courant'
|
||||
__author__ = 'Being and Sujata Raman'
|
||||
description = 'Politics, local and business news from Hartford'
|
||||
language = 'en'
|
||||
|
||||
use_embedded_content = False
|
||||
no_stylesheets = True
|
||||
remove_javascript = True
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'class':["story","entry-asset asset hentry"]}),
|
||||
dict(name='div', attrs={'id':["pagebody","story","maincontentcontainer"]}),
|
||||
]
|
||||
remove_tags_after = [ {'class':['photo_article',]} ]
|
||||
|
||||
remove_tags = [{'id':["moduleArticleTools","content-bottom","rail","articleRelates module","toolSet","relatedrailcontent","div-wrapper","beta","atp-comments","footer"]},
|
||||
{'class':["clearfix","relatedTitle","articleRelates module","asset-footer","tools","comments","featurePromo","featurePromo fp-topjobs brownBackground","clearfix fullSpan brownBackground","curvedContent"]},
|
||||
dict(name='font',attrs={'id':["cr-other-headlines"]})]
|
||||
extra_css = '''
|
||||
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
|
||||
h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
|
||||
.byline {font-family:Arial,Helvetica,sans-serif; font-size:xx-small;}
|
||||
.date {font-family:Arial,Helvetica,sans-serif; font-size:xx-small;}
|
||||
p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||
.copyright {font-family:Arial,Helvetica,sans-serif;font-size:xx-small;text-align:center}
|
||||
.story{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||
.entry-asset asset hentry{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||
.pagebody{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||
.maincontentcontainer{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||
.story-body{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
|
||||
'''
|
||||
feeds = [
|
||||
('Breaking News', 'http://feeds.feedburner.com/courant-breaking-news/'),
|
||||
('Nation/World News', 'http://feeds.feedburner.com/courant-nation-world/'),
|
||||
('Connecticut News', 'http://feeds.feedburner.com/courant-connecticut-news/'),
|
||||
('Hartford News', 'http://feeds.feedburner.com/courant-hartford/'),
|
||||
('West Hartford News', 'http://feeds.feedburner.com/courant-west-hartford/'),
|
||||
('Bristol', 'http://feeds.feedburner.com/courant-bristol/'),
|
||||
('Politics', 'http://feeds.feedburner.com/courant-politics/'),
|
||||
('Opinion', 'http://feeds.feedburner.com/courant-opinion/'),
|
||||
('Editorials', 'http://feeds.feedburner.com/courant-editorials/'),
|
||||
('Letters', 'http://feeds.feedburner.com/courant-letters/'),
|
||||
('Bob Englehart', 'http://feeds2.feedburner.com/BobEnglehartEnglehartsView'),
|
||||
('Business', 'http://feeds.feedburner.com/courant-business/'),
|
||||
('Sports', 'http://feeds.feedburner.com/courant-sports/'),
|
||||
('Features', 'http://feeds.feedburner.com/courant-features/'),
|
||||
('Consumer', 'http://feeds.feedburner.com/courant-consumer/'),
|
||||
('Shopping', 'http://feeds.feedburner.com/courant-shopping/'),
|
||||
('Arts & Theater', 'http://feeds.feedburner.com/courant-entertainment/'),
|
||||
('Entertainment', 'http://feeds.feedburner.com/courant-stage/'),
|
||||
('Music', 'http://feeds.feedburner.com/courant-music/'),
|
||||
('TV', 'http://feeds.feedburner.com/courant-tv/'),
|
||||
('Movies', 'http://feeds.feedburner.com/courant-movies/'),
|
||||
#('Metromix headlines', 'http://feeds.feedburner.com/metromix/topheadlines/'),
|
||||
#('Metromix events', 'http://feeds.feedburner.com/metromix/events/'),
|
||||
#('Metromix restaurants', 'http://feeds.feedburner.com/metromix/restaurants/'),
|
||||
('Outdoors', 'http://feeds.feedburner.com/courant-outdoors/'),
|
||||
('Peter Marteka', 'http://feeds.feedburner.com/courant-marteka-column/'),
|
||||
('Susan Campbell', 'http://feeds.feedburner.com/courant-campbell-column/'),
|
||||
('Helen Ubinas', 'http://feeds.feedburner.com/courant-helen-ubinas-column/'),
|
||||
('Jim Shea', 'http://feeds.feedburner.com/courant-jim-shea-column/'),
|
||||
('Tom Condon', 'http://feeds.feedburner.com/courant-tom-condon-column/'),
|
||||
('Colin McEnroe', 'http://feeds.feedburner.com/courant-colin-mcenroe-column/'),
|
||||
]
|
||||
|
||||
|
||||
def get_article_url(self, article):
|
||||
print article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
||||
return article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
||||
|
||||
|
||||
def postprocess_html(self, soup, first_fetch):
|
||||
for t in soup.findAll(['table', 'tr', 'td']):
|
||||
t.name = 'div'
|
||||
|
||||
for tag in soup.findAll('form', dict(attrs={'name':["comments_form"]})):
|
||||
tag.extract()
|
||||
for tag in soup.findAll('font', dict(attrs={'id':["cr-other-headlines"]})):
|
||||
tag.extract()
|
||||
|
||||
return soup
|
20
resources/recipes/national_post.recipe
Normal file
20
resources/recipes/national_post.recipe
Normal file
@ -0,0 +1,20 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class AdvancedUserRecipe1261379503(BasicNewsRecipe):
|
||||
title = u'National Post'
|
||||
language = 'en_CA'
|
||||
__author__ = 'Nick Redding'
|
||||
description = u"News from Canada"
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 25
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'id':'content'})]
|
||||
remove_tags = [dict(name='div', attrs={'class':'story-tools'}),dict(name='div', attrs={'class':'newsblock'}),dict(name='p', attrs={'class':'border-top'}),dict(name='div', attrs={'id':'footer'})]
|
||||
|
||||
feeds = [(u'News Headlines', u'http://www.nationalpost.com/scripts/sp6query.aspx?catalog=ntnp&type=stry&tags=section| news'),
|
||||
(u'FP Headlines', u'http://www.nationalpost.com/scripts/sp6query.aspx?catalog=ntnp&type=stry&tags=section| financial%20post|storytype|business'),
|
||||
(u'Arts & Life Headlines', u'http://www.nationalpost.com/scripts/sp6query.aspx?catalog=ntnp&type=stry&tags=section| arts%20%26%20life|storytype|news'),
|
||||
(u'Canada News', u'http://www.nationalpost.com/scripts/sp6query.aspx?catalog=ntnp&type=stry&tags=storytyp e|webcanada&feed=rss'),
|
||||
(u'World News', u'http://www.nationalpost.com/scripts/sp6query.aspx?catalog=ntnp&type=stry&tags=storytyp e|webworld&feed=rss'),(u'Editorial', u'http://www.nationalpost.com/scripts/sp6query.aspx?catalog=ntnp&type=stry&tags=section| editorial'),
|
||||
(u'FP Opinion', u'http://www.nationalpost.com/scripts/columnists.aspx?publication=national+post&columnty pe=fp')]
|
||||
|
@ -72,7 +72,7 @@ class Translations(POT):
|
||||
if os.path.exists(pycountry):
|
||||
iso639 = self.j(pycountry, 'iso639.mo')
|
||||
dest = self.j(self.d(dest), self.b(iso639))
|
||||
if self.newer(dest, iso639):
|
||||
if self.newer(dest, iso639) and os.path.exists(iso639):
|
||||
self.info('\tCopying ISO 639 translations')
|
||||
shutil.copy2(iso639, dest)
|
||||
else:
|
||||
|
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.6.30'
|
||||
__version__ = '0.6.31'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
import re
|
||||
@ -24,6 +24,7 @@ isosx = 'darwin' in sys.platform.lower()
|
||||
isnewosx = isosx and getattr(sys, 'new_app_bundle', False)
|
||||
islinux = not(iswindows or isosx)
|
||||
isfrozen = hasattr(sys, 'frozen')
|
||||
isunix = isosx or islinux
|
||||
|
||||
try:
|
||||
preferred_encoding = locale.getpreferredencoding()
|
||||
|
@ -257,6 +257,7 @@ class SonyReader900Output(SonyReaderOutput):
|
||||
description = _('This profile is intended for the SONY PRS-900.')
|
||||
|
||||
screen_size = (600, 999)
|
||||
comic_screen_size = screen_size
|
||||
|
||||
class JetBook5Output(OutputProfile):
|
||||
|
||||
|
@ -62,7 +62,7 @@ def migrate(old, new):
|
||||
|
||||
def debug_device_driver():
|
||||
from calibre.devices import debug
|
||||
print debug()
|
||||
debug(ioreg_to_tmp=True, buf=sys.stdout)
|
||||
if iswindows:
|
||||
raw_input('Press Enter to continue...')
|
||||
|
||||
|
@ -27,13 +27,14 @@ def strftime(epoch, zone=time.gmtime):
|
||||
src[2] = INVERSE_MONTH_MAP[int(src[2])]
|
||||
return ' '.join(src)
|
||||
|
||||
def debug():
|
||||
def debug(ioreg_to_tmp=False, buf=None):
|
||||
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
|
||||
|
||||
if buf is None:
|
||||
buf = StringIO()
|
||||
sys.stdout = sys.stderr = buf
|
||||
try:
|
||||
@ -82,16 +83,17 @@ def debug():
|
||||
connected_devices = []
|
||||
for dev in device_plugins():
|
||||
out('Looking for', dev.__class__.__name__)
|
||||
connected = s.is_device_connected(dev, debug=True)
|
||||
connected, det = s.is_device_connected(dev, debug=True)
|
||||
if connected:
|
||||
connected_devices.append(dev)
|
||||
connected_devices.append((dev, det))
|
||||
|
||||
errors = {}
|
||||
success = False
|
||||
for dev in connected_devices:
|
||||
for dev, det in connected_devices:
|
||||
out('Device possibly connected:', dev.__class__.name)
|
||||
out('Trying to open device...', end=' ')
|
||||
try:
|
||||
dev.reset(detected_device=det)
|
||||
dev.open()
|
||||
out('OK')
|
||||
except:
|
||||
@ -112,10 +114,16 @@ def debug():
|
||||
out(' ')
|
||||
|
||||
if ioreg is not None:
|
||||
ioreg = 'IOREG Output\n'+ioreg
|
||||
out(' ')
|
||||
out('IOREG Output')
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ Device driver for Bookeen's Cybook Gen 3
|
||||
|
||||
import os
|
||||
|
||||
from calibre import islinux
|
||||
from calibre.constants import isunix
|
||||
from calibre.devices.usbms.driver import USBMS
|
||||
import calibre.devices.cybookg3.t2b as t2b
|
||||
|
||||
@ -55,7 +55,7 @@ class CYBOOKG3(USBMS):
|
||||
|
||||
@classmethod
|
||||
def can_handle(cls, device_info, debug=False):
|
||||
if islinux:
|
||||
if isunix:
|
||||
return device_info[3] == 'Bookeen' and device_info[4] == 'Cybook Gen3'
|
||||
return True
|
||||
|
||||
@ -87,6 +87,6 @@ class CYBOOK_OPUS(CYBOOKG3):
|
||||
|
||||
@classmethod
|
||||
def can_handle(cls, device_info, debug=False):
|
||||
if islinux:
|
||||
if isunix:
|
||||
return device_info[3] == 'Bookeen'
|
||||
return True
|
||||
|
@ -104,12 +104,12 @@ class DevicePlugin(Plugin):
|
||||
@classmethod
|
||||
def is_usb_connected(cls, devices_on_system, debug=False):
|
||||
'''
|
||||
Return True if a device handled by this plugin is currently connected.
|
||||
Return True, device_info if a device handled by this plugin is currently connected.
|
||||
|
||||
:param devices_on_system: List of devices currently connected
|
||||
'''
|
||||
if iswindows:
|
||||
return cls.is_usb_connected_windows(devices_on_system, debug=debug)
|
||||
return cls.is_usb_connected_windows(devices_on_system, debug=debug), None
|
||||
|
||||
vendors_on_system = set([x[0] for x in devices_on_system])
|
||||
vendors = cls.VENDOR_ID if hasattr(cls.VENDOR_ID, '__len__') else [cls.VENDOR_ID]
|
||||
@ -134,18 +134,20 @@ class DevicePlugin(Plugin):
|
||||
if debug:
|
||||
cls.print_usb_device_info(dev)
|
||||
if cls.can_handle(dev, debug=debug):
|
||||
return True
|
||||
return False
|
||||
return True, dev
|
||||
return False, None
|
||||
|
||||
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None) :
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None,
|
||||
detected_device=None) :
|
||||
"""
|
||||
@param key: The key to unlock the device
|
||||
@param log_packets: If true the packet stream to/from the device is logged
|
||||
@param report_progress: Function that is called with a % progress
|
||||
:key: The key to unlock the device
|
||||
:log_packets: If true the packet stream to/from the device is logged
|
||||
:report_progress: Function that is called with a % progress
|
||||
(number between 0 and 100) for various tasks
|
||||
If it is called with -1 that means that the
|
||||
task does not have any progress information
|
||||
:detected_device: Device information from the device scanner
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
@ -206,9 +206,10 @@ def main():
|
||||
scanner.scan()
|
||||
connected_devices = []
|
||||
for d in device_plugins():
|
||||
if scanner.is_device_connected(d):
|
||||
ok, det = scanner.is_device_connected(d)
|
||||
if ok:
|
||||
dev = d
|
||||
dev.reset(log_packets=options.log_packets)
|
||||
dev.reset(log_packets=options.log_packets, detected_device=det)
|
||||
connected_devices.append(dev)
|
||||
|
||||
if dev is None:
|
||||
|
@ -39,6 +39,7 @@ from tempfile import TemporaryFile
|
||||
from array import array
|
||||
from functools import wraps
|
||||
from StringIO import StringIO
|
||||
from threading import RLock
|
||||
|
||||
from calibre.devices.interface import DevicePlugin
|
||||
from calibre.devices.libusb import Error as USBError
|
||||
@ -52,6 +53,7 @@ from calibre.devices.usbms.deviceconfig import DeviceConfig
|
||||
# Protocol versions this driver has been tested with
|
||||
KNOWN_USB_PROTOCOL_VERSIONS = [0x3030303030303130L]
|
||||
|
||||
lock = RLock()
|
||||
|
||||
class File(object):
|
||||
"""
|
||||
@ -161,9 +163,12 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
"""
|
||||
@wraps(func)
|
||||
def run_session(*args, **kwargs):
|
||||
with lock:
|
||||
dev = args[0]
|
||||
res = None
|
||||
try:
|
||||
if not hasattr(dev, 'in_session'):
|
||||
dev.reset()
|
||||
if not dev.handle:
|
||||
dev.open()
|
||||
if not getattr(dev, 'in_session', False):
|
||||
@ -194,7 +199,8 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
|
||||
return run_session
|
||||
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None) :
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None,
|
||||
detected_device=None) :
|
||||
"""
|
||||
@param key: The key to unlock the device
|
||||
@param log_packets: If true the packet stream to/from the device is logged
|
||||
@ -203,6 +209,7 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
If it is called with -1 that means that the
|
||||
task does not have any progress information
|
||||
"""
|
||||
with lock:
|
||||
self.device = get_device_by_id(self.VENDOR_ID, self.PRODUCT_ID)
|
||||
# Handle that is used to communicate with device. Setup in L{open}
|
||||
self.handle = None
|
||||
@ -243,8 +250,9 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
Also initialize the device.
|
||||
See the source code for the sequence of initialization commands.
|
||||
"""
|
||||
with lock:
|
||||
if not hasattr(self, 'key'):
|
||||
self.key = '-1\0\0\0\0\0\0'
|
||||
self.reset()
|
||||
self.device = get_device_by_id(self.VENDOR_ID, self.PRODUCT_ID)
|
||||
if not self.device:
|
||||
raise DeviceError()
|
||||
@ -294,6 +302,7 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
|
||||
def close(self):
|
||||
""" Release device interface """
|
||||
with lock:
|
||||
try:
|
||||
self.handle.reset()
|
||||
self.handle.release_interface(self.INTERFACE_ID)
|
||||
@ -312,6 +321,7 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
@param timeout: The time to wait for a response from the
|
||||
device, in milliseconds. If there is no response, a L{usb.USBError} is raised.
|
||||
"""
|
||||
with lock:
|
||||
if self.log_packets:
|
||||
self.log_packet(command, "Command")
|
||||
bytes_sent = self.handle.control_msg(0x40, 0x80, command)
|
||||
@ -346,6 +356,7 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
@param packet_size: Size of packets to be sent to device.
|
||||
C{data} is broken up into packets to be sent to device.
|
||||
"""
|
||||
with lock:
|
||||
def bulk_write_packet(packet):
|
||||
self.handle.bulk_write(self.BULK_OUT_EP, packet)
|
||||
if self.log_packets:
|
||||
@ -394,6 +405,7 @@ class PRS500(DeviceConfig, DevicePlugin):
|
||||
@return: A list of packets read from the device.
|
||||
Each packet is of type data_type
|
||||
"""
|
||||
with lock:
|
||||
msize = self.bulk_read_max_packet_size
|
||||
def bulk_read_packet(data_type=Answer, size=0x1000):
|
||||
rsize = size
|
||||
|
@ -22,9 +22,32 @@ from itertools import repeat
|
||||
from calibre.devices.interface import DevicePlugin
|
||||
from calibre.devices.errors import DeviceError, FreeSpaceError
|
||||
from calibre.devices.usbms.deviceconfig import DeviceConfig
|
||||
from calibre import iswindows, islinux, isosx, __appname__
|
||||
from calibre.constants import iswindows, islinux, isosx, __appname__, plugins
|
||||
from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to
|
||||
|
||||
if isosx:
|
||||
usbobserver, usbobserver_err = plugins['usbobserver']
|
||||
|
||||
class USBDevice:
|
||||
|
||||
def __init__(self, dev):
|
||||
self.idVendor = dev[0]
|
||||
self.idProduct = dev[1]
|
||||
self.bcdDevice = dev[2]
|
||||
self.manufacturer = dev[3]
|
||||
self.product = dev[4]
|
||||
self.serial = dev[5]
|
||||
|
||||
def match_serial(self, serial):
|
||||
return self.serial and self.serial == serial
|
||||
|
||||
def match_numbers(self, vid, pid, bcd):
|
||||
return self.idVendor == vid and self.idProduct == pid and self.bcdDevice == bcd
|
||||
|
||||
def match_strings(self, vid, pid, bcd, man, prod):
|
||||
return self.match_numbers(vid, pid, bcd) and \
|
||||
self.manufacturer == man and self.product == prod
|
||||
|
||||
class Device(DeviceConfig, DevicePlugin):
|
||||
|
||||
'''
|
||||
@ -108,8 +131,13 @@ class Device(DeviceConfig, DevicePlugin):
|
||||
FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
|
||||
FDI_BCD_TEMPLATE = '<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">'
|
||||
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None) :
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None,
|
||||
detected_device=None):
|
||||
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
|
||||
try:
|
||||
self.detected_device = USBDevice(detected_device)
|
||||
except: # On windows detected_device is None
|
||||
self.detected_device = None
|
||||
|
||||
@classmethod
|
||||
def get_gui_name(cls):
|
||||
@ -391,29 +419,82 @@ class Device(DeviceConfig, DevicePlugin):
|
||||
raise
|
||||
time.sleep(2)
|
||||
|
||||
def open_osx(self):
|
||||
mount = self.osx_run_mount()
|
||||
names = self.get_osx_mountpoints()
|
||||
dev_pat = r'/dev/%s(\w*)\s+on\s+([^\(]+)\s+'
|
||||
if 'main' not in names.keys():
|
||||
raise DeviceError(_('Unable to detect the %s disk drive. Try rebooting.')%self.__class__.__name__)
|
||||
main_pat = dev_pat % names['main']
|
||||
main_match = re.search(main_pat, mount)
|
||||
if main_match is None:
|
||||
raise DeviceError(_('Unable to detect the %s mount point. Try rebooting.')%self.__class__.__name__)
|
||||
self._main_prefix = main_match.group(2) + os.sep
|
||||
card_a_pat = names['carda'] if 'carda' in names.keys() else None
|
||||
card_b_pat = names['cardb'] if 'cardb' in names.keys() else None
|
||||
|
||||
def get_card_prefix(pat):
|
||||
if pat is not None:
|
||||
pat = dev_pat % pat
|
||||
return re.search(pat, mount).group(2) + os.sep
|
||||
def _osx_bsd_names(self):
|
||||
if usbobserver_err:
|
||||
raise RuntimeError('Failed to load usbobserver: '+usbobserver_err)
|
||||
drives = usbobserver.get_usb_drives()
|
||||
matches = []
|
||||
d = self.detected_device
|
||||
if d.serial:
|
||||
for path, vid, pid, bcd, ven, prod, serial in drives:
|
||||
if d.match_serial(serial):
|
||||
matches.append(path)
|
||||
if not matches:
|
||||
if d.manufacturer and d.product:
|
||||
for path, vid, pid, bcd, man, prod, serial in drives:
|
||||
if d.match_strings(vid, pid, bcd, man, prod):
|
||||
matches.append(path)
|
||||
else:
|
||||
return None
|
||||
for path, vid, pid, bcd, man, prod, serial in drives:
|
||||
if d.match_numbers(vid, pid, bcd):
|
||||
matches.append(path)
|
||||
if not matches:
|
||||
raise DeviceError(
|
||||
'Could not detect BSD names for %s. Try rebooting.' % self.name)
|
||||
|
||||
self._card_a_prefix = get_card_prefix(card_a_pat)
|
||||
self._card_b_prefix = get_card_prefix(card_b_pat)
|
||||
pat = re.compile(r'(?P<m>\d+)([a-z]+(?P<p>\d+)){0,1}')
|
||||
def nums(x):
|
||||
m = pat.search(x)
|
||||
if m is None:
|
||||
return (10000, 0)
|
||||
g = m.groupdict()
|
||||
if g['p'] is None:
|
||||
g['p'] = 0
|
||||
return map(int, (g.get('m'), g.get('p')))
|
||||
|
||||
def dcmp(x, y):
|
||||
x = x.rpartition('/')[-1]
|
||||
y = y.rpartition('/')[-1]
|
||||
x, y = nums(x), nums(y)
|
||||
ans = cmp(x[0], y[0])
|
||||
if ans == 0:
|
||||
ans = cmp(x[1], y[1])
|
||||
return ans
|
||||
|
||||
matches.sort(cmp=dcmp)
|
||||
drives = {'main':matches[0]}
|
||||
if len(matches) > 1:
|
||||
drives['carda'] = matches[1]
|
||||
if len(matches) > 2:
|
||||
drives['cardb'] = matches[2]
|
||||
|
||||
return drives
|
||||
|
||||
def osx_bsd_names(self):
|
||||
try:
|
||||
return self._osx_bsd_names()
|
||||
except:
|
||||
time.sleep(2)
|
||||
return self._osx_bsd_names()
|
||||
|
||||
def open_osx(self):
|
||||
drives = self.osx_bsd_names()
|
||||
bsd_drives = dict(**drives)
|
||||
drives = self.osx_sort_names(drives)
|
||||
mount_map = usbobserver.get_mounted_filesystems()
|
||||
for k, v in drives.items():
|
||||
drives[k] = mount_map.get(v, None)
|
||||
if drives['main'] is None:
|
||||
print bsd_drives, mount_map, drives
|
||||
raise DeviceError(_('Unable to detect the %s mount point. Try rebooting.')%self.__class__.__name__)
|
||||
self._main_prefix = drives['main']+os.sep
|
||||
def get_card_prefix(c):
|
||||
ans = drives.get(c, None)
|
||||
if ans is not None:
|
||||
ans += os.sep
|
||||
return ans
|
||||
self._card_a_prefix = get_card_prefix('carda')
|
||||
self._card_b_prefix = get_card_prefix('cardb')
|
||||
|
||||
def find_device_nodes(self):
|
||||
|
||||
|
@ -33,10 +33,6 @@ class USBMS(CLI, Device):
|
||||
FORMATS = []
|
||||
CAN_SET_METADATA = False
|
||||
|
||||
def reset(self, key='-1', log_packets=False, report_progress=None):
|
||||
Device.reset(self, key=key, log_packets=log_packets,
|
||||
report_progress=report_progress)
|
||||
|
||||
def get_device_information(self, end_session=True):
|
||||
self.report_progress(1.0, _('Get device information...'))
|
||||
return (self.__class__.__name__, '', '', '')
|
||||
|
@ -24,31 +24,74 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <CoreFoundation/CFNumber.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <mach/mach.h>
|
||||
#include <IOKit/storage/IOMedia.h>
|
||||
#include <IOKit/IOBSD.h>
|
||||
#include <IOKit/usb/USBSpec.h>
|
||||
|
||||
CFStringRef USB_PROPS[3] = { CFSTR("USB Vendor Name"), CFSTR("USB Product Name"), CFSTR("USB Serial Number") };
|
||||
#include <mach/mach.h>
|
||||
#include <sys/param.h>
|
||||
#include <paths.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#ifndef kUSBVendorString
|
||||
#define kUSBVendorString "USB Vendor Name"
|
||||
#endif
|
||||
|
||||
#ifndef kUSBProductString
|
||||
#define kUSBProductString "USB Product Name"
|
||||
#endif
|
||||
|
||||
#ifndef kUSBSerialNumberString
|
||||
#define kUSBSerialNumberString "USB Serial Number"
|
||||
#endif
|
||||
|
||||
#define NUKE(x) Py_XDECREF(x); x = NULL;
|
||||
|
||||
static PyObject*
|
||||
get_iokit_string_property(io_service_t dev, int prop) {
|
||||
usbobserver_get_iokit_string_property(io_service_t dev, CFStringRef prop) {
|
||||
CFTypeRef PropRef;
|
||||
char buf[500];
|
||||
|
||||
PropRef = IORegistryEntryCreateCFProperty(dev, USB_PROPS[prop], kCFAllocatorDefault, 0);
|
||||
PropRef = IORegistryEntryCreateCFProperty(dev, prop, kCFAllocatorDefault, 0);
|
||||
if (PropRef) {
|
||||
if(!CFStringGetCString(PropRef, buf, 500, kCFStringEncodingUTF8)) buf[0] = '\0';
|
||||
CFRelease(PropRef);
|
||||
} else buf[0] = '\0';
|
||||
|
||||
return PyUnicode_DecodeUTF8(buf, strlen(buf), "replace");
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
usbobserver_get_iokit_number_property(io_service_t dev, CFStringRef prop) {
|
||||
CFTypeRef PropRef;
|
||||
long val = 0;
|
||||
|
||||
PropRef = IORegistryEntryCreateCFProperty(dev, prop, kCFAllocatorDefault, 0);
|
||||
if (PropRef) {
|
||||
CFNumberGetValue((CFNumberRef)PropRef, kCFNumberLongType, &val);
|
||||
CFRelease(PropRef);
|
||||
}
|
||||
|
||||
return PyLong_FromLong(val);
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
||||
|
||||
CFMutableDictionaryRef matchingDict;
|
||||
kern_return_t kr;
|
||||
PyObject *devices, *device;
|
||||
io_service_t usbDevice;
|
||||
PyObject *vendor, *product, *bcd;
|
||||
PyObject *manufacturer, *productn, *serial;
|
||||
|
||||
|
||||
|
||||
//Set up matching dictionary for class IOUSBDevice and its subclasses
|
||||
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
|
||||
@ -58,78 +101,206 @@ usbobserver_get_usb_devices(PyObject *self, PyObject *args) {
|
||||
}
|
||||
|
||||
io_iterator_t iter;
|
||||
IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
|
||||
io_service_t usbDevice;
|
||||
IOCFPlugInInterface **plugInInterface = NULL;
|
||||
SInt32 score;
|
||||
IOUSBDeviceInterface182 **dev = NULL;
|
||||
UInt16 vendor, product, bcd;
|
||||
PyObject *manufacturer, *productn, *serial;
|
||||
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
|
||||
if (KERN_SUCCESS != kr) {
|
||||
printf("IOServiceGetMatchingServices returned 0x%08x\n", kr);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Could not run IO Matching");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *devices, *device;
|
||||
devices = PyList_New(0);
|
||||
if (devices == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
while ((usbDevice = IOIteratorNext(iter))) {
|
||||
plugInInterface = NULL; dev = NULL;
|
||||
//Create an intermediate plugin
|
||||
kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score);
|
||||
if ((kIOReturnSuccess != kr) || !plugInInterface) {
|
||||
printf("Unable to create a plug-in (%08x)\n", kr); continue;
|
||||
}
|
||||
//Now create the device interface
|
||||
HRESULT result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&dev);
|
||||
|
||||
if (result || !dev) {
|
||||
printf("Couldn't create a device interface (%08x)\n", (int) result);
|
||||
continue;
|
||||
}
|
||||
vendor = usbobserver_get_iokit_number_property(usbDevice, CFSTR(kUSBVendorID));
|
||||
product = usbobserver_get_iokit_number_property(usbDevice, CFSTR(kUSBProductID));
|
||||
bcd = usbobserver_get_iokit_number_property(usbDevice, CFSTR(kUSBDeviceReleaseNumber));
|
||||
manufacturer = usbobserver_get_iokit_string_property(usbDevice, CFSTR(kUSBVendorString));
|
||||
productn = usbobserver_get_iokit_string_property(usbDevice, CFSTR(kUSBProductString));
|
||||
serial = usbobserver_get_iokit_string_property(usbDevice, CFSTR(kUSBSerialNumberString));
|
||||
if (usbDevice) IOObjectRelease(usbDevice);
|
||||
|
||||
kr = (*dev)->GetDeviceVendor(dev, &vendor);
|
||||
kr = (*dev)->GetDeviceProduct(dev, &product);
|
||||
kr = (*dev)->GetDeviceReleaseNumber(dev, &bcd);
|
||||
if (vendor != NULL && product != NULL && bcd != NULL) {
|
||||
|
||||
manufacturer = get_iokit_string_property(usbDevice, 0);
|
||||
if (manufacturer == NULL) manufacturer = Py_None;
|
||||
productn = get_iokit_string_property(usbDevice, 1);
|
||||
if (productn == NULL) productn = Py_None;
|
||||
serial = get_iokit_string_property(usbDevice, 2);
|
||||
if (serial == NULL) serial = Py_None;
|
||||
if (manufacturer == NULL) { manufacturer = Py_None; Py_INCREF(Py_None); }
|
||||
if (productn == NULL) { productn = Py_None; Py_INCREF(Py_None); }
|
||||
if (serial == NULL) { serial = Py_None; Py_INCREF(Py_None); }
|
||||
|
||||
device = Py_BuildValue("(iiiNNN)", vendor, product, bcd, manufacturer, productn, serial);
|
||||
if (device == NULL) {
|
||||
IOObjectRelease(usbDevice);
|
||||
(*plugInInterface)->Release(plugInInterface);
|
||||
(*dev)->Release(dev);
|
||||
Py_DECREF(devices);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
if (PyList_Append(devices, device) == -1) {
|
||||
IOObjectRelease(usbDevice);
|
||||
(*plugInInterface)->Release(plugInInterface);
|
||||
(*dev)->Release(dev);
|
||||
Py_DECREF(devices);
|
||||
Py_DECREF(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IOObjectRelease(usbDevice);
|
||||
(*plugInInterface)->Release(plugInInterface);
|
||||
(*dev)->Release(dev);
|
||||
device = Py_BuildValue("(OOOOOO)", vendor, product, bcd, manufacturer, productn, serial);
|
||||
if (device != NULL) {
|
||||
PyList_Append(devices, device);
|
||||
Py_DECREF(device);
|
||||
}
|
||||
}
|
||||
|
||||
NUKE(vendor); NUKE(product); NUKE(bcd); NUKE(manufacturer);
|
||||
NUKE(productn); NUKE(serial);
|
||||
}
|
||||
|
||||
if (iter) IOObjectRelease(iter);
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
usbobserver_get_bsd_path(io_object_t dev) {
|
||||
char cpath[ MAXPATHLEN ];
|
||||
CFTypeRef PropRef;
|
||||
size_t dev_path_length;
|
||||
|
||||
cpath[0] = '\0';
|
||||
PropRef = IORegistryEntryCreateCFProperty(dev, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
|
||||
if (!PropRef) return NULL;
|
||||
strcpy(cpath, _PATH_DEV);
|
||||
dev_path_length = strlen(cpath);
|
||||
|
||||
if (!CFStringGetCString(PropRef,
|
||||
cpath + dev_path_length,
|
||||
MAXPATHLEN - dev_path_length,
|
||||
kCFStringEncodingUTF8)) return NULL;
|
||||
|
||||
return PyUnicode_DecodeUTF8(cpath, strlen(cpath), "replace");
|
||||
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
usbobserver_find_prop(io_registry_entry_t e, CFStringRef key, int is_string )
|
||||
{
|
||||
char buf[500]; long val = 0;
|
||||
PyObject *ans;
|
||||
IOOptionBits bits = kIORegistryIterateRecursively | kIORegistryIterateParents;
|
||||
CFTypeRef PropRef = IORegistryEntrySearchCFProperty( e, kIOServicePlane, key, NULL, bits );
|
||||
|
||||
if (!PropRef) return NULL;
|
||||
buf[0] = '\0';
|
||||
|
||||
if(is_string) {
|
||||
CFStringGetCString(PropRef, buf, 500, kCFStringEncodingUTF8);
|
||||
ans = PyUnicode_DecodeUTF8(buf, strlen(buf), "replace");
|
||||
} else {
|
||||
CFNumberGetValue((CFNumberRef)PropRef, kCFNumberLongType, &val);
|
||||
ans = PyLong_FromLong(val);
|
||||
}
|
||||
|
||||
CFRelease(PropRef);
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
usbobserver_get_usb_drives(PyObject *self, PyObject *args) {
|
||||
CFMutableDictionaryRef matchingDict;
|
||||
kern_return_t kr = KERN_FAILURE;
|
||||
io_iterator_t iter;
|
||||
io_object_t next;
|
||||
PyObject *ans = NULL, *bsd_path = NULL, *t = NULL, *vid, *pid, *bcd, *manufacturer, *product, *serial;
|
||||
|
||||
//Set up matching dictionary for class IOMedia and its subclasses
|
||||
matchingDict = IOServiceMatching(kIOMediaClass);
|
||||
if (!matchingDict) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Couldn't create a Media matching dictionary");
|
||||
return NULL;
|
||||
}
|
||||
// Only want writable and ejectable leaf nodes
|
||||
CFDictionarySetValue(matchingDict, CFSTR(kIOMediaWritableKey), kCFBooleanTrue);
|
||||
CFDictionarySetValue(matchingDict, CFSTR(kIOMediaLeafKey), kCFBooleanTrue);
|
||||
CFDictionarySetValue(matchingDict, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue);
|
||||
|
||||
ans = PyList_New(0);
|
||||
if (ans == NULL) return PyErr_NoMemory();
|
||||
|
||||
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
|
||||
if (KERN_SUCCESS != kr) {
|
||||
printf("IOServiceGetMatchingServices returned 0x%08x\n", kr);
|
||||
PyErr_SetString(PyExc_RuntimeError, "Could not run IO Matching");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((next = IOIteratorNext(iter))) {
|
||||
bsd_path = usbobserver_get_bsd_path(next);
|
||||
vid = usbobserver_find_prop(next, CFSTR(kUSBVendorID), 0);
|
||||
pid = usbobserver_find_prop(next, CFSTR(kUSBProductID), 0);
|
||||
bcd = usbobserver_find_prop(next, CFSTR(kUSBDeviceReleaseNumber), 0);
|
||||
manufacturer = usbobserver_find_prop(next, CFSTR(kUSBVendorString), 1);
|
||||
product = usbobserver_find_prop(next, CFSTR(kUSBProductString), 1);
|
||||
serial = usbobserver_find_prop(next, CFSTR(kUSBSerialNumberString), 1);
|
||||
|
||||
IOObjectRelease(next);
|
||||
|
||||
if (bsd_path != NULL && vid != NULL && pid != NULL && bcd != NULL) {
|
||||
if (manufacturer == NULL) { manufacturer = Py_None; Py_INCREF(Py_None); }
|
||||
if (product == NULL) { product = Py_None; Py_INCREF(Py_None); }
|
||||
if (serial == NULL) { serial = Py_None; Py_INCREF(Py_None); }
|
||||
|
||||
t = Py_BuildValue("(OOOOOOO)", bsd_path, vid, pid, bcd, manufacturer, product, serial);
|
||||
if (t != NULL) {
|
||||
PyList_Append(ans, t);
|
||||
Py_DECREF(t); t = NULL;
|
||||
}
|
||||
}
|
||||
NUKE(bsd_path); NUKE(vid); NUKE(pid); NUKE(bcd);
|
||||
NUKE(manufacturer); NUKE(product); NUKE(serial);
|
||||
}
|
||||
|
||||
if (iter) IOObjectRelease(iter);
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
usbobserver_get_mounted_filesystems(PyObject *self, PyObject *args) {
|
||||
struct statfs *buf, t;
|
||||
int num, i;
|
||||
PyObject *ans, *key, *val;
|
||||
|
||||
num = getfsstat(NULL, 0, MNT_NOWAIT);
|
||||
if (num == -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Initial call to getfsstat failed");
|
||||
return NULL;
|
||||
}
|
||||
ans = PyDict_New();
|
||||
if (ans == NULL) return PyErr_NoMemory();
|
||||
|
||||
buf = (struct statfs*)calloc(num, sizeof(struct statfs));
|
||||
if (buf == NULL) return PyErr_NoMemory();
|
||||
|
||||
num = getfsstat(buf, num*sizeof(struct statfs), MNT_NOWAIT);
|
||||
if (num == -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Call to getfsstat failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < num; i++) {
|
||||
t = buf[i];
|
||||
key = PyBytes_FromString(t.f_mntfromname);
|
||||
val = PyBytes_FromString(t.f_mntonname);
|
||||
if (key != NULL && val != NULL) {
|
||||
PyDict_SetItem(ans, key, val);
|
||||
}
|
||||
NUKE(key); NUKE(val);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
return ans;
|
||||
|
||||
}
|
||||
|
||||
static PyMethodDef usbobserver_methods[] = {
|
||||
{"get_usb_devices", usbobserver_get_usb_devices, METH_VARARGS,
|
||||
"Get list of connected USB devices. Returns a list of tuples. Each tuple is of the form (vendor_id, product_id)."
|
||||
"Get list of connected USB devices. Returns a list of tuples. Each tuple is of the form (vendor_id, product_id, bcd, manufacturer, product, serial number)."
|
||||
},
|
||||
{"get_usb_drives", usbobserver_get_usb_drives, METH_VARARGS,
|
||||
"Get list of mounted drives. Returns a list of tuples, each of the form (name, bsd_path)."
|
||||
},
|
||||
{"get_mounted_filesystems", usbobserver_get_mounted_filesystems, METH_VARARGS,
|
||||
"Get mapping of mounted filesystems. Mapping is from BSD name to mount point."
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,7 @@ import subprocess
|
||||
from functools import partial
|
||||
|
||||
from calibre.ebooks import ConversionError, DRMError
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre import isosx, iswindows, islinux
|
||||
from calibre import CurrentDir
|
||||
|
||||
@ -45,8 +46,10 @@ def pdftohtml(output_dir, pdf_path, no_images):
|
||||
if no_images:
|
||||
cmd.append('-i')
|
||||
|
||||
logf = PersistentTemporaryFile('pdftohtml_log')
|
||||
try:
|
||||
p = popen(cmd, stderr=subprocess.PIPE)
|
||||
p = popen(cmd, stderr=logf._fd, stdout=logf._fd,
|
||||
stdin=subprocess.PIPE)
|
||||
except OSError, err:
|
||||
if err.errno == 2:
|
||||
raise ConversionError(_('Could not find pdftohtml, check it is in your PATH'))
|
||||
@ -62,10 +65,13 @@ def pdftohtml(output_dir, pdf_path, no_images):
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
|
||||
logf.flush()
|
||||
logf.close()
|
||||
out = open(logf.name, 'rb').read()
|
||||
if ret != 0:
|
||||
err = p.stderr.read()
|
||||
raise ConversionError(err)
|
||||
raise ConversionError(out)
|
||||
print "pdftohtml log:"
|
||||
print out
|
||||
if not os.path.exists(index) or os.stat(index).st_size < 100:
|
||||
raise DRMError()
|
||||
|
||||
|
@ -94,8 +94,8 @@ class DeviceManager(Thread):
|
||||
import pythoncom
|
||||
pythoncom.CoInitialize()
|
||||
try:
|
||||
for dev in connected_devices:
|
||||
dev.reset()
|
||||
for dev, detected_device in connected_devices:
|
||||
dev.reset(detected_device=detected_device)
|
||||
try:
|
||||
dev.open()
|
||||
except:
|
||||
@ -116,10 +116,10 @@ class DeviceManager(Thread):
|
||||
self.scanner.scan()
|
||||
connected_devices = []
|
||||
for device in self.devices:
|
||||
connected = self.scanner.is_device_connected(device[0])
|
||||
connected, detected_device = self.scanner.is_device_connected(device[0])
|
||||
if connected and not device[1] and not device[2]:
|
||||
# If connected and not showing in GUI and not ejected
|
||||
connected_devices.append(device[0])
|
||||
connected_devices.append((device[0], detected_device))
|
||||
device[1] = True
|
||||
elif not connected and device[1]:
|
||||
# Disconnected but showing in GUI
|
||||
|
@ -92,6 +92,12 @@ class Sony505(Sony500):
|
||||
name = 'SONY Reader Pocket/Touch Edition'
|
||||
id = 'prs505'
|
||||
|
||||
class Sony900(Sony505):
|
||||
|
||||
name = 'SONY Reader Daily Edition'
|
||||
id = 'prs900'
|
||||
output_profile = 'sony900'
|
||||
|
||||
class Nook(Sony505):
|
||||
id = 'nook'
|
||||
name = 'Nook'
|
||||
|
@ -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, 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.
|
||||
At the moment |app| has full support for the SONY PRS 300/500/505/600/700/900, 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, eClicto, Iriver Story, Airis dBook, 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|?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -7,14 +7,14 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-12-25 04:54+0000\n"
|
||||
"PO-Revision-Date: 2009-12-25 19:11+0000\n"
|
||||
"POT-Creation-Date: 2009-12-26 16:57+0000\n"
|
||||
"PO-Revision-Date: 2009-12-26 16:45+0000\n"
|
||||
"Last-Translator: Kovid Goyal <Unknown>\n"
|
||||
"Language-Team: Arabic <ar@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-26 04:31+0000\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-27 04:31+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41
|
||||
@ -64,8 +64,8 @@ msgstr "لا يفعل شيءً"
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:79
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:121
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:593
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:783
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:594
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:784
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:896
|
||||
@ -132,7 +132,7 @@ msgstr "لا يفعل شيءً"
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:645
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:717
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:764
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:107
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
||||
@ -7361,10 +7361,18 @@ msgid "English (TH)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:103
|
||||
msgid "Dutch (NL)"
|
||||
msgid "English (CY)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
msgid "German (AT)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
msgid "Dutch (NL)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:106
|
||||
msgid "Dutch (BE)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre 0.6.30\n"
|
||||
"POT-Creation-Date: 2009-12-26 08:40+MST\n"
|
||||
"PO-Revision-Date: 2009-12-26 08:40+MST\n"
|
||||
"Project-Id-Version: calibre 0.6.31\n"
|
||||
"POT-Creation-Date: 2009-12-27 16:02+MST\n"
|
||||
"PO-Revision-Date: 2009-12-27 16:02+MST\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: LANGUAGE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -22,11 +22,13 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:44
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:94
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:54
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/books.py:58
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/books.py:199
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:789
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:792
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:206
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:870
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:873
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:202
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/comic/input.py:414
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:67
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/input.py:69
|
||||
@ -236,72 +238,90 @@ msgid "This profile tries to provide sane defaults and is useful if you know not
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:56
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:208
|
||||
msgid "This profile is intended for the SONY PRS line. The 500/505/700 etc."
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:235
|
||||
msgid "This profile is intended for the SONY PRS line. The 500/505/600/700 etc."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:69
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:243
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:68
|
||||
msgid "This profile is intended for the SONY PRS 300."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:77
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:257
|
||||
msgid "This profile is intended for the SONY PRS-900."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:85
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:287
|
||||
msgid "This profile is intended for the Microsoft Reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:80
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:254
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:96
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:298
|
||||
msgid "This profile is intended for the Mobipocket books."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:93
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:267
|
||||
msgid "This profile is intended for the Hanlin V3/V5 and its clones."
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:109
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:311
|
||||
msgid "This profile is intended for the Hanlin V3 and its clones."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:105
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:279
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:121
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:323
|
||||
msgid "This profile is intended for the Hanlin V5 and its clones."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:131
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:331
|
||||
msgid "This profile is intended for the Cybook G3."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:118
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:292
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:144
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:344
|
||||
msgid "This profile is intended for the Cybook Opus."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:130
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:303
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:156
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:355
|
||||
msgid "This profile is intended for the Amazon Kindle."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:142
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:336
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:168
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:388
|
||||
msgid "This profile is intended for the Irex Illiad."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:154
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:349
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:180
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:401
|
||||
msgid "This profile is intended for the IRex Digital Reader 1000."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:168
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:363
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:194
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:415
|
||||
msgid "This profile is intended for the B&N Nook."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:186
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:213
|
||||
msgid "Output profile"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:190
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:217
|
||||
msgid "This profile tries to provide sane defaults and is useful if you want to produce a document intended to be read at a computer or on a range of devices."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:220
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:248
|
||||
msgid "This profile is intended for the SONY PRS-300."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:266
|
||||
msgid "This profile is intended for the 5-inch JetBook."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:231
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:275
|
||||
msgid "This profile is intended for the SONY PRS line. The 500/505/700 etc, in landscape mode. Mainly useful for comics."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:320
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:372
|
||||
msgid "This profile is intended for the Amazon Kindle DX."
|
||||
msgstr ""
|
||||
|
||||
@ -369,33 +389,21 @@ msgstr ""
|
||||
msgid "Comma separated list of directories to send e-books to on the device. The first one that exists will be used"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/bebook/driver.py:19
|
||||
msgid "Communicate with the BeBook eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/bebook/driver.py:95
|
||||
msgid "Communicate with the BeBook Mini eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/blackberry/driver.py:12
|
||||
msgid "Communicate with the Blackberry smart phone."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/blackberry/driver.py:13
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/nuut2/driver.py:18
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:88
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:90
|
||||
msgid "Kovid Goyal"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/boox/driver.py:17
|
||||
msgid "Communicate with the BOOX eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:21
|
||||
msgid "Communicate with the Cybook Gen 3 eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:68
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/cybookg3/driver.py:67
|
||||
msgid "Communicate with the Cybook Opus eBook reader."
|
||||
msgstr ""
|
||||
|
||||
@ -407,6 +415,18 @@ msgstr ""
|
||||
msgid "Communicate with the ESlick eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/hanlin/driver.py:19
|
||||
msgid "Communicate with Hanlin V3 eBook readers."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/hanlin/driver.py:95
|
||||
msgid "Communicate with Hanlin V5 eBook readers."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/hanlin/driver.py:113
|
||||
msgid "Communicate with the BOOX eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/iliad/driver.py:16
|
||||
msgid "Communicate with the IRex Iliad eBook reader."
|
||||
msgstr ""
|
||||
@ -437,8 +457,8 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:78
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:134
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:136
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:120
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:122
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:116
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:118
|
||||
msgid "Transferring books to device..."
|
||||
msgstr ""
|
||||
|
||||
@ -474,7 +494,7 @@ msgstr ""
|
||||
msgid "Communicate with the Nuut2 eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:87
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs500/driver.py:89
|
||||
msgid "Communicate with the Sony PRS-500 eBook reader."
|
||||
msgstr ""
|
||||
|
||||
@ -483,12 +503,12 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:100
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:103
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:114
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:49
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:52
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:55
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:75
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:85
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:94
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:48
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:71
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:81
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:90
|
||||
msgid "Getting list of books on device..."
|
||||
msgstr ""
|
||||
|
||||
@ -498,64 +518,63 @@ msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:167
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:174
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:148
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:163
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:144
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:159
|
||||
msgid "Removing books from device..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:202
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:178
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:174
|
||||
msgid "Sending metadata to device..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:208
|
||||
msgid "Communicate with the Sony PRS-600/700 eBook reader."
|
||||
msgid "Communicate with the Sony PRS-600/700/900 eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:308
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:399
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:336
|
||||
msgid "Unable to detect the %s disk drive. Try rebooting."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:403
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:489
|
||||
msgid "Unable to detect the %s mount point. Try rebooting."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:470
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:551
|
||||
msgid "Unable to detect the %s disk drive."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:563
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:644
|
||||
msgid "Could not find mount helper: %s."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:575
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:656
|
||||
msgid "Unable to detect the %s disk drive. Your kernel is probably exporting a deprecated version of SYSFS."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:583
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:664
|
||||
msgid "Unable to mount main memory (Error code: %d)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:720
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:722
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:801
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:803
|
||||
msgid "The reader has no storage card in this slot."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:724
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:805
|
||||
msgid "Selected slot: %s is not supported."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:757
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:838
|
||||
msgid "There is insufficient free space in main memory"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:759
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:761
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:840
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:842
|
||||
msgid "There is insufficient free space on the storage card"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:772
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:853
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:232
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:125
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1065
|
||||
@ -594,17 +613,17 @@ msgstr ""
|
||||
msgid "Communicate with an eBook reader."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:41
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:37
|
||||
msgid "Get device information..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:136
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:144
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:132
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:140
|
||||
msgid "Adding books to device metadata listing..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:167
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:172
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:163
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:168
|
||||
msgid "Removing books from device metadata listing..."
|
||||
msgstr ""
|
||||
|
||||
@ -1902,7 +1921,7 @@ msgstr ""
|
||||
msgid "The orientation of the page. Default is portrait. Choices are %s"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftohtml.py:52
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pdf/pdftohtml.py:55
|
||||
msgid "Could not find pdftohtml, check it is in your PATH"
|
||||
msgstr ""
|
||||
|
||||
@ -2048,7 +2067,7 @@ msgid "Limit max simultaneous jobs to number of CPUs"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:127
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:404
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:410
|
||||
msgid "Copied"
|
||||
msgstr ""
|
||||
|
||||
@ -3459,7 +3478,7 @@ msgid "Failed to start content server"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:698
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:514
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:520
|
||||
msgid "Select location for books"
|
||||
msgstr ""
|
||||
|
||||
@ -5354,7 +5373,7 @@ msgid "Bad database location"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:471
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:522
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:528
|
||||
msgid "Calibre Library"
|
||||
msgstr ""
|
||||
|
||||
@ -6119,40 +6138,40 @@ msgstr ""
|
||||
msgid "Title Case"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:295
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:301
|
||||
msgid "If you use the WordPlayer e-book app on your Android phone, you can access your calibre book collection directly on the device. To do this you have to turn on the content server."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:299
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:305
|
||||
msgid "Remember to leave calibre running as the server only runs as long as calibre is running."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:301
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:307
|
||||
msgid "You have to add the URL http://myhostname:8080 as your calibre library in WordPlayer. Here myhostname should be the fully qualified hostname or the IP address of the computer calibre is running on."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:378
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:384
|
||||
msgid "Moving library..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:394
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:395
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:400
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:401
|
||||
msgid "Failed to move library"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:449
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:455
|
||||
msgid "Invalid database"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:450
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:456
|
||||
msgid "<p>An invalid library already exists at %s, delete it before trying to move the existing library.<br>Error: %s"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:461
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:467
|
||||
msgid "Could not move library"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:589
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:595
|
||||
msgid "welcome wizard"
|
||||
msgstr ""
|
||||
|
||||
@ -6970,50 +6989,50 @@ msgstr ""
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:455
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:459
|
||||
msgid ""
|
||||
"%prog URL\n"
|
||||
"\n"
|
||||
"Where URL is for example http://google.com"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:458
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:462
|
||||
msgid "Base directory into which URL is saved. Default is %default"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:461
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:465
|
||||
msgid "Timeout in seconds to wait for a response from the server. Default: %default s"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:464
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:468
|
||||
msgid "Maximum number of levels to recurse i.e. depth of links to follow. Default %default"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:467
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:471
|
||||
msgid "The maximum number of files to download. This only applies to files from <a href> tags. Default is %default"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:469
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:473
|
||||
msgid "Minimum interval in seconds between consecutive fetches. Default is %default s"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:471
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:475
|
||||
msgid "The character encoding for the websites you are trying to download. The default is to try and guess the encoding."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:473
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:477
|
||||
msgid "Only links that match this regular expression will be followed. This option can be specified multiple times, in which case as long as a link matches any one regexp, it will be followed. By default all links are followed."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:475
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:479
|
||||
msgid "Any link that matches this regular expression will be ignored. This option can be specified multiple times, in which case as long as any regexp matches a link, it will be ignored.By default, no links are ignored. If both --filter-regexp and --match-regexp are specified, then --filter-regexp is applied first."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:477
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:481
|
||||
msgid "Do not download CSS stylesheets."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:478
|
||||
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:482
|
||||
msgid "Show detailed output information. Useful for debugging"
|
||||
msgstr ""
|
||||
|
||||
|
@ -7,14 +7,14 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: de\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-25 04:54+0000\n"
|
||||
"PO-Revision-Date: 2009-12-25 21:08+0000\n"
|
||||
"POT-Creation-Date: 2009-12-26 16:57+0000\n"
|
||||
"PO-Revision-Date: 2009-12-26 20:24+0000\n"
|
||||
"Last-Translator: S. Dorscht <Unknown>\n"
|
||||
"Language-Team: American English <kde-i18n-doc@lists.kde.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-26 04:32+0000\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-27 04:31+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
@ -65,8 +65,8 @@ msgstr "Macht absolut gar nichts"
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:79
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:121
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:593
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:783
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:594
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:784
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:896
|
||||
@ -133,7 +133,7 @@ msgstr "Macht absolut gar nichts"
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:645
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:717
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:764
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:107
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
||||
@ -8227,10 +8227,18 @@ msgid "English (TH)"
|
||||
msgstr "Englisch (TH)"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:103
|
||||
msgid "English (CY)"
|
||||
msgstr "Englisch (CY)"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
msgid "German (AT)"
|
||||
msgstr "Deutsch (AT)"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
msgid "Dutch (NL)"
|
||||
msgstr "Holländisch (NL)"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:106
|
||||
msgid "Dutch (BE)"
|
||||
msgstr "Holländisch (BE)"
|
||||
|
||||
|
@ -10,14 +10,14 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: es\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-25 04:54+0000\n"
|
||||
"PO-Revision-Date: 2009-12-26 01:25+0000\n"
|
||||
"POT-Creation-Date: 2009-12-26 16:57+0000\n"
|
||||
"PO-Revision-Date: 2009-12-26 16:48+0000\n"
|
||||
"Last-Translator: mosteo <alejandro@mosteo.com>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-26 04:33+0000\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-27 04:32+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:41
|
||||
@ -67,8 +67,8 @@ msgstr "No hacer nada en absoluto"
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:79
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:121
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:593
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:783
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:594
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:784
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:896
|
||||
@ -135,7 +135,7 @@ msgstr "No hacer nada en absoluto"
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:645
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:717
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:764
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:107
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
||||
@ -8181,10 +8181,18 @@ msgid "English (TH)"
|
||||
msgstr "Inglés (TH)"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:103
|
||||
msgid "English (CY)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
msgid "German (AT)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
msgid "Dutch (NL)"
|
||||
msgstr "Neerlandés (NL)"
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:106
|
||||
msgid "Dutch (BE)"
|
||||
msgstr "Neerlandés (BE)"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,14 +7,14 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-12-25 04:54+0000\n"
|
||||
"PO-Revision-Date: 2009-12-25 19:14+0000\n"
|
||||
"POT-Creation-Date: 2009-12-26 16:57+0000\n"
|
||||
"PO-Revision-Date: 2009-12-26 16:50+0000\n"
|
||||
"Last-Translator: Kovid Goyal <Unknown>\n"
|
||||
"Language-Team: Latvian <ivars_a@inbox.lv>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-26 04:32+0000\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-27 04:31+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
"X-Poedit-Country: LATVIA\n"
|
||||
"X-Poedit-Language: Latvian\n"
|
||||
@ -66,8 +66,8 @@ msgstr "Pilnīgi neko nedara"
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:79
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:121
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:593
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:783
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:594
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:784
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:896
|
||||
@ -134,7 +134,7 @@ msgstr "Pilnīgi neko nedara"
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:645
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:717
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:764
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:107
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
||||
@ -7354,10 +7354,18 @@ msgid "English (TH)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:103
|
||||
msgid "Dutch (NL)"
|
||||
msgid "English (CY)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
msgid "German (AT)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
msgid "Dutch (NL)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:106
|
||||
msgid "Dutch (BE)"
|
||||
msgstr ""
|
||||
|
||||
|
@ -6,14 +6,14 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre 0.4.55\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-25 04:54+0000\n"
|
||||
"PO-Revision-Date: 2009-12-25 19:27+0000\n"
|
||||
"POT-Creation-Date: 2009-12-26 16:57+0000\n"
|
||||
"PO-Revision-Date: 2009-12-26 16:54+0000\n"
|
||||
"Last-Translator: Kovid Goyal <Unknown>\n"
|
||||
"Language-Team: American English <kde-i18n-doc@lists.kde.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-26 04:32+0000\n"
|
||||
"X-Launchpad-Export-Date: 2009-12-27 04:31+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
"X-Poedit-Country: RUSSIAN FEDERATION\n"
|
||||
"X-Poedit-Language: Russian\n"
|
||||
@ -68,8 +68,8 @@ msgstr "Ничего не делает"
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:79
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:121
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:593
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:783
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:594
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:784
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:896
|
||||
@ -136,7 +136,7 @@ msgstr "Ничего не делает"
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:645
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:717
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server.py:764
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:107
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/podofo/__init__.py:77
|
||||
@ -7760,10 +7760,18 @@ msgid "English (TH)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:103
|
||||
msgid "Dutch (NL)"
|
||||
msgid "English (CY)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:104
|
||||
msgid "German (AT)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:105
|
||||
msgid "Dutch (NL)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/localization.py:106
|
||||
msgid "Dutch (BE)"
|
||||
msgstr ""
|
||||
|
||||
|
7541
src/calibre/translations/sq.po
Normal file
7541
src/calibre/translations/sq.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -190,6 +190,10 @@ class RecursiveFetcher(object):
|
||||
time.sleep(delta)
|
||||
if isinstance(url, unicode):
|
||||
url = url.encode('utf-8')
|
||||
# Not sure is this is really needed as I think mechanize
|
||||
# handles quoting automatically, but leaving it in
|
||||
# in case it breaks something
|
||||
if re.search(r'\s+|,', url) is not None:
|
||||
purl = list(urlparse.urlparse(url))
|
||||
for i in range(2, 6):
|
||||
purl[i] = quote(purl[i])
|
||||
|
Loading…
x
Reference in New Issue
Block a user