mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Realign to trunk.
This commit is contained in:
parent
9ee3e926c0
commit
86afb92057
@ -13,4 +13,11 @@ base_dir = os.path.join(src_dir, 'calibre')
|
|||||||
|
|
||||||
vipy.session.initialize(project_name='calibre', src_dir=src_dir,
|
vipy.session.initialize(project_name='calibre', src_dir=src_dir,
|
||||||
project_dir=project_dir, base_dir=base_dir)
|
project_dir=project_dir, base_dir=base_dir)
|
||||||
|
|
||||||
|
def recipe_title_callback(raw):
|
||||||
|
return eval(raw.decode('utf-8'))
|
||||||
|
|
||||||
|
vipy.session.add_content_browser('.r', ',r', 'Recipe',
|
||||||
|
vipy.session.glob_based_iterator(os.path.join(project_dir, 'resources', 'recipes', '*.recipe')),
|
||||||
|
vipy.session.regexp_based_matcher(r'title\s*=\s*(?P<title>.+)', 'title', recipe_title_callback))
|
||||||
EOFPY
|
EOFPY
|
||||||
|
@ -47,25 +47,24 @@ class CYBOOKG3(USBMS):
|
|||||||
DELETE_EXTS = ['.mbp', '.dat', '_6090.t2b']
|
DELETE_EXTS = ['.mbp', '.dat', '_6090.t2b']
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def upload_books(self, files, metadatas, ids, on_card=None,
|
def upload_books(self, files, names, on_card=None, end_session=True,
|
||||||
end_session=True):
|
metadata=None):
|
||||||
|
|
||||||
path = self._sanity_check(on_card, files)
|
path = self._sanity_check(on_card, files)
|
||||||
|
|
||||||
paths = []
|
paths = []
|
||||||
metadatas = iter(metadatas)
|
names = iter(names)
|
||||||
ids = iter(ids)
|
metadata = iter(metadata)
|
||||||
|
|
||||||
for i, infile in enumerate(files):
|
for i, infile in enumerate(files):
|
||||||
mdata, id = metadatas.next(), ids.next()
|
mdata, fname = metadata.next(), names.next()
|
||||||
ext = os.path.splitext(infile)[1]
|
filepath = self.create_upload_path(path, mdata, fname)
|
||||||
filepath = self.create_upload_path(path, mdata, ext, id)
|
|
||||||
paths.append(filepath)
|
paths.append(filepath)
|
||||||
|
|
||||||
self.put_file(infile, filepath, replace_file=True)
|
self.put_file(infile, filepath, replace_file=True)
|
||||||
|
|
||||||
coverdata = None
|
coverdata = None
|
||||||
cover = mdata.cover
|
cover = mdata.get('cover', None)
|
||||||
if cover:
|
if cover:
|
||||||
coverdata = cover[2]
|
coverdata = cover[2]
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class IRIVER_STORY(USBMS):
|
|||||||
|
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = True
|
||||||
|
|
||||||
def windows_sort_drives(self, drives):
|
def windows_open_callback(self, drives):
|
||||||
main = drives.get('main', None)
|
main = drives.get('main', None)
|
||||||
card = drives.get('carda', None)
|
card = drives.get('carda', None)
|
||||||
if card and main and card < main:
|
if card and main and card < main:
|
||||||
|
@ -15,7 +15,7 @@ from itertools import cycle
|
|||||||
|
|
||||||
from calibre.devices.usbms.driver import USBMS
|
from calibre.devices.usbms.driver import USBMS
|
||||||
from calibre.utils.filenames import ascii_filename as sanitize
|
from calibre.utils.filenames import ascii_filename as sanitize
|
||||||
from calibre.ebooks.metadata import authors_to_string, string_to_authors
|
from calibre.ebooks.metadata import string_to_authors
|
||||||
|
|
||||||
class JETBOOK(USBMS):
|
class JETBOOK(USBMS):
|
||||||
name = 'Ectaco JetBook Device Interface'
|
name = 'Ectaco JetBook Device Interface'
|
||||||
@ -50,22 +50,23 @@ class JETBOOK(USBMS):
|
|||||||
r'(?P<authors>.+)#(?P<title>.+)'
|
r'(?P<authors>.+)#(?P<title>.+)'
|
||||||
)
|
)
|
||||||
|
|
||||||
def upload_books(self, files, metadatas, ids, on_card=None,
|
def upload_books(self, files, names, on_card=False, end_session=True,
|
||||||
end_session=True):
|
metadata=None):
|
||||||
path = self._sanity_check(on_card, files)
|
|
||||||
|
base_path = self._sanity_check(on_card, files)
|
||||||
|
|
||||||
paths = []
|
paths = []
|
||||||
metadatas = iter(metadatas)
|
names = iter(names)
|
||||||
ids = iter(ids)
|
metadata = iter(metadata)
|
||||||
|
|
||||||
for i, infile in enumerate(files):
|
for i, infile in enumerate(files):
|
||||||
mdata, id = metadatas.next(), ids.next()
|
mdata, fname = metadata.next(), names.next()
|
||||||
ext = os.path.splitext(infile)[1]
|
path = os.path.dirname(self.create_upload_path(base_path, mdata, fname))
|
||||||
path = self.create_upload_path(path, mdata, ext, id)
|
|
||||||
|
|
||||||
author = sanitize(authors_to_string(mdata.authors)).replace(' ', '_')
|
author = sanitize(mdata.get('authors','Unknown')).replace(' ', '_')
|
||||||
title = sanitize(mdata.title).replace(' ', '_')
|
title = sanitize(mdata.get('title', 'Unknown')).replace(' ', '_')
|
||||||
fname = '%s#%s%s' % (author, title, ext)
|
fileext = os.path.splitext(os.path.basename(fname))[1]
|
||||||
|
fname = '%s#%s%s' % (author, title, fileext)
|
||||||
|
|
||||||
filepath = os.path.join(path, fname)
|
filepath = os.path.join(path, fname)
|
||||||
paths.append(filepath)
|
paths.append(filepath)
|
||||||
|
@ -9,7 +9,6 @@ from base64 import b64decode as decode
|
|||||||
from base64 import b64encode as encode
|
from base64 import b64encode as encode
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.ebooks.metadata import authors_to_string
|
|
||||||
from calibre.devices.interface import BookList as _BookList
|
from calibre.devices.interface import BookList as _BookList
|
||||||
from calibre.devices import strftime, strptime
|
from calibre.devices import strftime, strptime
|
||||||
|
|
||||||
@ -263,9 +262,9 @@ class BookList(_BookList):
|
|||||||
cid = self.max_id()+1
|
cid = self.max_id()+1
|
||||||
sourceid = str(self[0].sourceid) if len(self) else "1"
|
sourceid = str(self[0].sourceid) if len(self) else "1"
|
||||||
attrs = {
|
attrs = {
|
||||||
"title" : info.title,
|
"title" : info["title"],
|
||||||
'titleSorter' : sortable_title(info.title),
|
'titleSorter' : sortable_title(info['title']),
|
||||||
"author" : authors_to_string(info.authors), \
|
"author" : info["authors"] if info['authors'] else 'Unknown', \
|
||||||
"page":"0", "part":"0", "scale":"0", \
|
"page":"0", "part":"0", "scale":"0", \
|
||||||
"sourceid":sourceid, "id":str(cid), "date":"", \
|
"sourceid":sourceid, "id":str(cid), "date":"", \
|
||||||
"mime":mime, "path":name, "size":str(size)
|
"mime":mime, "path":name, "size":str(size)
|
||||||
@ -274,7 +273,7 @@ class BookList(_BookList):
|
|||||||
node.setAttributeNode(self.document.createAttribute(attr))
|
node.setAttributeNode(self.document.createAttribute(attr))
|
||||||
node.setAttribute(attr, attrs[attr])
|
node.setAttribute(attr, attrs[attr])
|
||||||
try:
|
try:
|
||||||
w, h, data = info.cover
|
w, h, data = info["cover"]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
w, h, data = None, None, None
|
w, h, data = None, None, None
|
||||||
|
|
||||||
@ -291,7 +290,10 @@ class BookList(_BookList):
|
|||||||
book.datetime = ctime
|
book.datetime = ctime
|
||||||
self.append(book)
|
self.append(book)
|
||||||
self.set_next_id(cid+1)
|
self.set_next_id(cid+1)
|
||||||
self.set_playlists(book.id, info.tags)
|
if self.prefix and info.has_key('tags'): # Playlists only supportted in main memory
|
||||||
|
if info.has_key('tag order'):
|
||||||
|
self.tag_order.update(info['tag order'])
|
||||||
|
self.set_playlists(book.id, info['tags'])
|
||||||
|
|
||||||
|
|
||||||
def playlist_by_title(self, title):
|
def playlist_by_title(self, title):
|
||||||
|
@ -867,14 +867,14 @@ class PRS500(DeviceConfig, DevicePlugin):
|
|||||||
self.upload_book_list(booklists[1], end_session=False)
|
self.upload_book_list(booklists[1], end_session=False)
|
||||||
|
|
||||||
@safe
|
@safe
|
||||||
def upload_books(self, files, metadatas, ids, on_card=None,
|
def upload_books(self, files, names, on_card=False, end_session=True,
|
||||||
end_session=True):
|
metadata=None):
|
||||||
card = self.card(end_session=False)
|
card = self.card(end_session=False)
|
||||||
prefix = card + '/' + self.CARD_PATH_PREFIX +'/' if on_card else '/Data/media/books/'
|
prefix = card + '/' + self.CARD_PATH_PREFIX +'/' if on_card else '/Data/media/books/'
|
||||||
if on_card and not self._exists(prefix)[0]:
|
if on_card and not self._exists(prefix)[0]:
|
||||||
self.mkdir(prefix[:-1], False)
|
self.mkdir(prefix[:-1], False)
|
||||||
paths, ctimes = [], []
|
paths, ctimes = [], []
|
||||||
names = iter([m.title for m in metatdatas])
|
names = iter(names)
|
||||||
infiles = [file if hasattr(file, 'read') else open(file, 'rb') for file in files]
|
infiles = [file if hasattr(file, 'read') else open(file, 'rb') for file in files]
|
||||||
for f in infiles: f.seek(0, 2)
|
for f in infiles: f.seek(0, 2)
|
||||||
sizes = [f.tell() for f in infiles]
|
sizes = [f.tell() for f in infiles]
|
||||||
|
@ -8,7 +8,7 @@ import xml.dom.minidom as dom
|
|||||||
from base64 import b64decode as decode
|
from base64 import b64decode as decode
|
||||||
from base64 import b64encode as encode
|
from base64 import b64encode as encode
|
||||||
|
|
||||||
from calibre.ebooks.metadata import authors_to_string
|
|
||||||
from calibre.devices.interface import BookList as _BookList
|
from calibre.devices.interface import BookList as _BookList
|
||||||
from calibre.devices import strftime as _strftime
|
from calibre.devices import strftime as _strftime
|
||||||
from calibre.devices import strptime
|
from calibre.devices import strptime
|
||||||
@ -194,9 +194,9 @@ class BookList(_BookList):
|
|||||||
except:
|
except:
|
||||||
sourceid = '1'
|
sourceid = '1'
|
||||||
attrs = {
|
attrs = {
|
||||||
"title" : info.title,
|
"title" : info["title"],
|
||||||
'titleSorter' : sortable_title(info.title),
|
'titleSorter' : sortable_title(info['title']),
|
||||||
"author" : authors_to_string(info.authors),
|
"author" : info["authors"] if info['authors'] else _('Unknown'),
|
||||||
"page":"0", "part":"0", "scale":"0", \
|
"page":"0", "part":"0", "scale":"0", \
|
||||||
"sourceid":sourceid, "id":str(cid), "date":"", \
|
"sourceid":sourceid, "id":str(cid), "date":"", \
|
||||||
"mime":mime, "path":name, "size":str(size)
|
"mime":mime, "path":name, "size":str(size)
|
||||||
@ -205,7 +205,7 @@ class BookList(_BookList):
|
|||||||
node.setAttributeNode(self.document.createAttribute(attr))
|
node.setAttributeNode(self.document.createAttribute(attr))
|
||||||
node.setAttribute(attr, attrs[attr])
|
node.setAttribute(attr, attrs[attr])
|
||||||
try:
|
try:
|
||||||
w, h, data = info.cover
|
w, h, data = info["cover"]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
w, h, data = None, None, None
|
w, h, data = None, None, None
|
||||||
|
|
||||||
@ -221,7 +221,10 @@ class BookList(_BookList):
|
|||||||
book = Book(node, self.mountpath, [], prefix=self.prefix)
|
book = Book(node, self.mountpath, [], prefix=self.prefix)
|
||||||
book.datetime = ctime
|
book.datetime = ctime
|
||||||
self.append(book)
|
self.append(book)
|
||||||
self.set_tags(book, info.tags)
|
if info.has_key('tags'):
|
||||||
|
if info.has_key('tag order'):
|
||||||
|
self.tag_order.update(info['tag order'])
|
||||||
|
self.set_tags(book, info['tags'])
|
||||||
|
|
||||||
def _delete_book(self, node):
|
def _delete_book(self, node):
|
||||||
nid = node.getAttribute('id')
|
nid = node.getAttribute('id')
|
||||||
|
@ -114,22 +114,20 @@ class PRS505(CLI, Device):
|
|||||||
self.report_progress(1.0, _('Getting list of books on device...'))
|
self.report_progress(1.0, _('Getting list of books on device...'))
|
||||||
return bl
|
return bl
|
||||||
|
|
||||||
def upload_books(self, files, metadatas, ids, on_card=None,
|
def upload_books(self, files, names, on_card=None, end_session=True,
|
||||||
end_session=True):
|
metadata=None):
|
||||||
|
|
||||||
path = self._sanity_check(on_card, files)
|
path = self._sanity_check(on_card, files)
|
||||||
|
|
||||||
paths = []
|
paths, ctimes, sizes = [], [], []
|
||||||
metadatas = iter(metadatas)
|
names = iter(names)
|
||||||
ids = iter(ids)
|
metadata = iter(metadata)
|
||||||
|
|
||||||
for i, infile in enumerate(files):
|
for i, infile in enumerate(files):
|
||||||
mdata, id = metadatas.next(), ids.next()
|
mdata, fname = metadata.next(), names.next()
|
||||||
ext = os.path.splitext(infile)[1]
|
filepath = self.create_upload_path(path, mdata, fname)
|
||||||
filepath = self.create_upload_path(path, mdata, ext, id)
|
|
||||||
paths.append(filepath)
|
|
||||||
|
|
||||||
self.put_file(infile, filepath, replace_file=True)
|
paths.append(filepath)
|
||||||
|
self.put_file(infile, paths[-1], replace_file=True)
|
||||||
ctimes.append(os.path.getctime(paths[-1]))
|
ctimes.append(os.path.getctime(paths[-1]))
|
||||||
sizes.append(os.stat(paths[-1]).st_size)
|
sizes.append(os.stat(paths[-1]).st_size)
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ from calibre.devices.interface import DevicePlugin
|
|||||||
from calibre.devices.errors import DeviceError, FreeSpaceError
|
from calibre.devices.errors import DeviceError, FreeSpaceError
|
||||||
from calibre.devices.usbms.deviceconfig import DeviceConfig
|
from calibre.devices.usbms.deviceconfig import DeviceConfig
|
||||||
from calibre import iswindows, islinux, isosx, __appname__
|
from calibre import iswindows, islinux, isosx, __appname__
|
||||||
from calibre.utils.filenames import shorten_components_to
|
from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to
|
||||||
|
|
||||||
class Device(DeviceConfig, DevicePlugin):
|
class Device(DeviceConfig, DevicePlugin):
|
||||||
|
|
||||||
@ -295,20 +295,20 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
|
|
||||||
# This is typically needed when the device has the same
|
# This is typically needed when the device has the same
|
||||||
# WINDOWS_MAIN_MEM and WINDOWS_CARD_A_MEM in which case
|
# WINDOWS_MAIN_MEM and WINDOWS_CARD_A_MEM in which case
|
||||||
# if the devices is connected without a crad, the above
|
# if the devices is connected without a card, the above
|
||||||
# will incorrectly identify the main mem as carda
|
# will incorrectly identify the main mem as carda
|
||||||
# See for example the driver for the Nook
|
# See for example the driver for the Nook
|
||||||
if 'main' not in drives and 'carda' in drives:
|
if 'main' not in drives and 'carda' in drives:
|
||||||
drives['main'] = drives.pop('carda')
|
drives['main'] = drives.pop('carda')
|
||||||
|
|
||||||
drives = self.windows_open_callback(drives)
|
drives = self.windows_open_callback(drives)
|
||||||
drives = self.windows_sort_drives(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__)
|
||||||
|
|
||||||
|
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)
|
||||||
@ -739,18 +739,54 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
raise FreeSpaceError(_("There is insufficient free space on the storage card"))
|
raise FreeSpaceError(_("There is insufficient free space on the storage card"))
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def create_upload_path(self, root, mdata, ext, id):
|
def create_upload_path(self, path, mdata, fname):
|
||||||
from calibre.library.save_to_disk import config, get_components
|
path = os.path.abspath(path)
|
||||||
opts = config().parse()
|
newpath = path
|
||||||
components = get_components(opts.template, mdata, id, opts.timefmt, 250)
|
extra_components = []
|
||||||
components = [str(x) for x in components]
|
|
||||||
components = shorten_components_to(250 - len(root), components)
|
if self.SUPPORTS_SUB_DIRS and self.settings().use_subdirs:
|
||||||
filepath = '%s%s' % (os.path.join(root, *components), ext)
|
if 'tags' in mdata.keys():
|
||||||
|
for tag in mdata['tags']:
|
||||||
|
if tag.startswith(_('News')):
|
||||||
|
extra_components.append('news')
|
||||||
|
c = sanitize(mdata.get('title', ''))
|
||||||
|
if c:
|
||||||
|
extra_components.append(c)
|
||||||
|
c = sanitize(mdata.get('timestamp', ''))
|
||||||
|
if c:
|
||||||
|
extra_components.append(c)
|
||||||
|
break
|
||||||
|
elif tag.startswith('/'):
|
||||||
|
for c in tag.split('/'):
|
||||||
|
c = sanitize(c)
|
||||||
|
if not c: continue
|
||||||
|
extra_components.append(c)
|
||||||
|
break
|
||||||
|
|
||||||
|
if not extra_components:
|
||||||
|
c = sanitize(mdata.get('authors', _('Unknown')))
|
||||||
|
if c:
|
||||||
|
extra_components.append(c)
|
||||||
|
c = sanitize(mdata.get('title', _('Unknown')))
|
||||||
|
if c:
|
||||||
|
extra_components.append(c)
|
||||||
|
newpath = os.path.join(newpath, c)
|
||||||
|
|
||||||
|
fname = sanitize(fname)
|
||||||
|
extra_components.append(fname)
|
||||||
|
extra_components = [str(x) for x in extra_components]
|
||||||
|
def remove_trailing_periods(x):
|
||||||
|
ans = x
|
||||||
|
while ans.endswith('.'):
|
||||||
|
ans = ans[:-1]
|
||||||
|
if not ans:
|
||||||
|
ans = 'x'
|
||||||
|
return ans
|
||||||
|
extra_components = list(map(remove_trailing_periods, extra_components))
|
||||||
|
components = shorten_components_to(250 - len(path), extra_components)
|
||||||
|
filepath = os.path.join(path, *components)
|
||||||
filedir = os.path.dirname(filepath)
|
filedir = os.path.dirname(filepath)
|
||||||
|
|
||||||
if not self.SUPPORTS_SUB_DIRS or not self.settings().use_subdirs:
|
|
||||||
filedir = root
|
|
||||||
filepath = os.path.join(root, os.path.basename(filepath))
|
|
||||||
|
|
||||||
if not os.path.exists(filedir):
|
if not os.path.exists(filedir):
|
||||||
os.makedirs(filedir)
|
os.makedirs(filedir)
|
||||||
|
@ -95,19 +95,19 @@ class USBMS(CLI, Device):
|
|||||||
|
|
||||||
return bl
|
return bl
|
||||||
|
|
||||||
def upload_books(self, files, metadatas, ids, on_card=None,
|
def upload_books(self, files, names, on_card=None, end_session=True,
|
||||||
end_session=True):
|
metadata=None):
|
||||||
|
|
||||||
path = self._sanity_check(on_card, files)
|
path = self._sanity_check(on_card, files)
|
||||||
|
|
||||||
paths = []
|
paths = []
|
||||||
metadatas = iter(metadatas)
|
names = iter(names)
|
||||||
ids = iter(ids)
|
metadata = iter(metadata)
|
||||||
|
|
||||||
for i, infile in enumerate(files):
|
for i, infile in enumerate(files):
|
||||||
mdata, id = metadatas.next(), ids.next()
|
mdata, fname = metadata.next(), names.next()
|
||||||
ext = os.path.splitext(infile)[1]
|
filepath = self.create_upload_path(path, mdata, fname)
|
||||||
filepath = self.create_upload_path(path, mdata, ext, id)
|
|
||||||
paths.append(filepath)
|
paths.append(filepath)
|
||||||
|
|
||||||
self.put_file(infile, filepath, replace_file=True)
|
self.put_file(infile, filepath, replace_file=True)
|
||||||
|
@ -223,17 +223,18 @@ class DeviceManager(Thread):
|
|||||||
return self.create_job(self._sync_booklists, done, args=[booklists],
|
return self.create_job(self._sync_booklists, done, args=[booklists],
|
||||||
description=_('Send metadata to device'))
|
description=_('Send metadata to device'))
|
||||||
|
|
||||||
def _upload_books(self, files, metadata, ids, on_card=None):
|
def _upload_books(self, files, names, on_card=None, metadata=None):
|
||||||
'''Upload books to device: '''
|
'''Upload books to device: '''
|
||||||
return self.device.upload_books(files, metadata, ids, on_card,
|
return self.device.upload_books(files, names, on_card,
|
||||||
end_session=False)
|
metadata=metadata, end_session=False)
|
||||||
|
|
||||||
def upload_books(self, done, files, metadata, ids, on_card=None, titles=None):
|
def upload_books(self, done, files, names, on_card=None, titles=None,
|
||||||
desc = _('Upload %d books to device')%len(files)
|
metadata=None):
|
||||||
|
desc = _('Upload %d books to device')%len(names)
|
||||||
if titles:
|
if titles:
|
||||||
desc += u':' + u', '.join(titles)
|
desc += u':' + u', '.join(titles)
|
||||||
return self.create_job(self._upload_books, done, args=[files, metadata, ids],
|
return self.create_job(self._upload_books, done, args=[files, names],
|
||||||
kwargs={'on_card':on_card}, description=desc)
|
kwargs={'on_card':on_card,'metadata':metadata}, description=desc)
|
||||||
|
|
||||||
def add_books_to_metadata(self, locations, metadata, booklists):
|
def add_books_to_metadata(self, locations, metadata, booklists):
|
||||||
self.device.add_books_to_metadata(locations, metadata, booklists)
|
self.device.add_books_to_metadata(locations, metadata, booklists)
|
||||||
@ -707,18 +708,18 @@ class DeviceGUI(object):
|
|||||||
dynamic.set('news_to_be_synced', set([]))
|
dynamic.set('news_to_be_synced', set([]))
|
||||||
return
|
return
|
||||||
metadata = self.library_view.model().get_metadata(ids,
|
metadata = self.library_view.model().get_metadata(ids,
|
||||||
rows_are_ids=True, full_metadata=True)[1]
|
rows_are_ids=True)
|
||||||
names = []
|
names = []
|
||||||
for mi in metadata:
|
for mi in metadata:
|
||||||
prefix = ascii_filename(mi.title)
|
prefix = ascii_filename(mi['title'])
|
||||||
if not isinstance(prefix, unicode):
|
if not isinstance(prefix, unicode):
|
||||||
prefix = prefix.decode(preferred_encoding, 'replace')
|
prefix = prefix.decode(preferred_encoding, 'replace')
|
||||||
prefix = ascii_filename(prefix)
|
prefix = ascii_filename(prefix)
|
||||||
names.append('%s_%d%s'%(prefix, id,
|
names.append('%s_%d%s'%(prefix, id,
|
||||||
os.path.splitext(f.name)[1]))
|
os.path.splitext(f.name)[1]))
|
||||||
cdata = mi.cover
|
cdata = mi['cover']
|
||||||
if cdata:
|
if cdata:
|
||||||
mi.cover = self.cover_to_thumbnail(cdata)
|
mi['cover'] = self.cover_to_thumbnail(cdata)
|
||||||
dynamic.set('news_to_be_synced', set([]))
|
dynamic.set('news_to_be_synced', set([]))
|
||||||
if config['upload_news_to_device'] and files:
|
if config['upload_news_to_device'] and files:
|
||||||
remove = ids if \
|
remove = ids if \
|
||||||
@ -727,7 +728,8 @@ class DeviceGUI(object):
|
|||||||
self.location_view.model().free[1] : 'carda',
|
self.location_view.model().free[1] : 'carda',
|
||||||
self.location_view.model().free[2] : 'cardb' }
|
self.location_view.model().free[2] : 'cardb' }
|
||||||
on_card = space.get(sorted(space.keys(), reverse=True)[0], None)
|
on_card = space.get(sorted(space.keys(), reverse=True)[0], None)
|
||||||
self.upload_books(files, metadata, ids, on_card=on_card,
|
self.upload_books(files, names, metadata,
|
||||||
|
on_card=on_card,
|
||||||
memory=[[f.name for f in files], remove])
|
memory=[[f.name for f in files], remove])
|
||||||
self.status_bar.showMessage(_('Sending news to device.'), 5000)
|
self.status_bar.showMessage(_('Sending news to device.'), 5000)
|
||||||
|
|
||||||
@ -749,28 +751,38 @@ class DeviceGUI(object):
|
|||||||
else:
|
else:
|
||||||
_auto_ids = []
|
_auto_ids = []
|
||||||
|
|
||||||
metadata = self.library_view.model().get_metadata(ids, True, full_metadata=True)[1]
|
metadata = self.library_view.model().get_metadata(ids, True)
|
||||||
ids = iter(ids)
|
ids = iter(ids)
|
||||||
for mi in metadata:
|
for mi in metadata:
|
||||||
cdata = mi.cover
|
cdata = mi['cover']
|
||||||
if cdata:
|
if cdata:
|
||||||
mi['cover'] = self.cover_to_thumbnail(cdata)
|
mi['cover'] = self.cover_to_thumbnail(cdata)
|
||||||
metadata = iter(metadata)
|
metadata = iter(metadata)
|
||||||
|
|
||||||
files = [getattr(f, 'name', None) for f in _files]
|
files = [getattr(f, 'name', None) for f in _files]
|
||||||
bad, mdata, gf, fids, remove_ids = [], [], [], [], []
|
bad, good, gf, names, remove_ids = [], [], [], [], []
|
||||||
for f in files:
|
for f in files:
|
||||||
mi = metadata.next()
|
mi = metadata.next()
|
||||||
id = ids.next()
|
id = ids.next()
|
||||||
if f is None:
|
if f is None:
|
||||||
bad.append(mi.title)
|
bad.append(mi['title'])
|
||||||
else:
|
else:
|
||||||
remove_ids.append(id)
|
remove_ids.append(id)
|
||||||
|
good.append(mi)
|
||||||
gf.append(f)
|
gf.append(f)
|
||||||
mdata.append(mi)
|
t = mi['title']
|
||||||
fids.append(id)
|
if not t:
|
||||||
|
t = _('Unknown')
|
||||||
|
a = mi['authors']
|
||||||
|
if not a:
|
||||||
|
a = _('Unknown')
|
||||||
|
prefix = ascii_filename(t+' - '+a)
|
||||||
|
if not isinstance(prefix, unicode):
|
||||||
|
prefix = prefix.decode(preferred_encoding, 'replace')
|
||||||
|
prefix = ascii_filename(prefix)
|
||||||
|
names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1]))
|
||||||
remove = remove_ids if delete_from_library else []
|
remove = remove_ids if delete_from_library else []
|
||||||
self.upload_books(gf, mdata, fids, on_card, memory=(_files, remove))
|
self.upload_books(gf, names, good, on_card, memory=(_files, remove))
|
||||||
self.status_bar.showMessage(_('Sending books to device.'), 5000)
|
self.status_bar.showMessage(_('Sending books to device.'), 5000)
|
||||||
|
|
||||||
auto = []
|
auto = []
|
||||||
@ -833,15 +845,17 @@ class DeviceGUI(object):
|
|||||||
cp, fs = job.result
|
cp, fs = job.result
|
||||||
self.location_view.model().update_devices(cp, fs)
|
self.location_view.model().update_devices(cp, fs)
|
||||||
|
|
||||||
def upload_books(self, files, metadata, ids, on_card=None, memory=None):
|
def upload_books(self, files, names, metadata, on_card=None, memory=None):
|
||||||
'''
|
'''
|
||||||
Upload books to device.
|
Upload books to device.
|
||||||
:param files: List of either paths to files or file like objects
|
:param files: List of either paths to files or file like objects
|
||||||
'''
|
'''
|
||||||
titles = [i.title for i in metadata]
|
titles = [i['title'] for i in metadata]
|
||||||
job = self.device_manager.upload_books(
|
job = self.device_manager.upload_books(
|
||||||
Dispatcher(self.books_uploaded),
|
Dispatcher(self.books_uploaded),
|
||||||
files, metadata, ids, on_card=on_card, titles=titles)
|
files, names, on_card=on_card,
|
||||||
|
metadata=metadata, titles=titles
|
||||||
|
)
|
||||||
self.upload_memory[job] = (metadata, on_card, memory, files)
|
self.upload_memory[job] = (metadata, on_card, memory, files)
|
||||||
|
|
||||||
def books_uploaded(self, job):
|
def books_uploaded(self, job):
|
||||||
@ -854,7 +868,7 @@ class DeviceGUI(object):
|
|||||||
if isinstance(job.exception, FreeSpaceError):
|
if isinstance(job.exception, FreeSpaceError):
|
||||||
where = 'in main memory.' if 'memory' in str(job.exception) \
|
where = 'in main memory.' if 'memory' in str(job.exception) \
|
||||||
else 'on the storage card.'
|
else 'on the storage card.'
|
||||||
titles = '\n'.join(['<li>'+mi.title+'</li>' \
|
titles = '\n'.join(['<li>'+mi['title']+'</li>' \
|
||||||
for mi in metadata])
|
for mi in metadata])
|
||||||
d = error_dialog(self, _('No space on device'),
|
d = error_dialog(self, _('No space on device'),
|
||||||
_('<p>Cannot upload books to device there '
|
_('<p>Cannot upload books to device there '
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Here you can control how calibre will save your books when you click the Save to Disk or Send to Device buttons:</string>
|
<string>Here you can control how calibre will save your books when you click the Save to Disk button:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -497,6 +497,7 @@ TXT input supports a number of options to differentiate how paragraphs are detec
|
|||||||
|
|
||||||
|
|
||||||
Convert PDF documents
|
Convert PDF documents
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
PDF documents are one of the worst formats to convert from. They are a fixed page size and text placement format.
|
PDF documents are one of the worst formats to convert from. They are a fixed page size and text placement format.
|
||||||
Meaning, it is very difficult to determine where one paragraph ends and another begins. |app| will try to unwrap
|
Meaning, it is very difficult to determine where one paragraph ends and another begins. |app| will try to unwrap
|
||||||
|
Loading…
x
Reference in New Issue
Block a user