mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk.
This commit is contained in:
commit
66beba7708
@ -201,8 +201,9 @@ class ITUNES(DriverBase):
|
|||||||
# 0x1294 iPhone 3GS
|
# 0x1294 iPhone 3GS
|
||||||
# 0x1297 iPhone 4
|
# 0x1297 iPhone 4
|
||||||
# 0x129a iPad
|
# 0x129a iPad
|
||||||
|
# 0x12a2 iPad2
|
||||||
VENDOR_ID = [0x05ac]
|
VENDOR_ID = [0x05ac]
|
||||||
PRODUCT_ID = [0x1292,0x1293,0x1294,0x1297,0x1299,0x129a]
|
PRODUCT_ID = [0x1292,0x1293,0x1294,0x1297,0x1299,0x129a,0x12a2]
|
||||||
BCD = [0x01]
|
BCD = [0x01]
|
||||||
|
|
||||||
# Plugboard ID
|
# Plugboard ID
|
||||||
@ -421,7 +422,7 @@ class ITUNES(DriverBase):
|
|||||||
|
|
||||||
cached_books[this_book.path] = {
|
cached_books[this_book.path] = {
|
||||||
'title':book.name(),
|
'title':book.name(),
|
||||||
'author':[book.artist()],
|
'author':book.artist().split(' & '),
|
||||||
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
||||||
'dev_book':book,
|
'dev_book':book,
|
||||||
'uuid': book.composer()
|
'uuid': book.composer()
|
||||||
@ -459,7 +460,7 @@ class ITUNES(DriverBase):
|
|||||||
|
|
||||||
cached_books[this_book.path] = {
|
cached_books[this_book.path] = {
|
||||||
'title':book.Name,
|
'title':book.Name,
|
||||||
'author':book.Artist,
|
'author':book.artist().split(' & '),
|
||||||
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
||||||
'uuid': book.Composer,
|
'uuid': book.Composer,
|
||||||
'format': 'pdf' if book.KindAsString.startswith('PDF') else 'epub'
|
'format': 'pdf' if book.KindAsString.startswith('PDF') else 'epub'
|
||||||
@ -1021,7 +1022,9 @@ class ITUNES(DriverBase):
|
|||||||
if isosx:
|
if isosx:
|
||||||
for (i,file) in enumerate(files):
|
for (i,file) in enumerate(files):
|
||||||
format = file.rpartition('.')[2].lower()
|
format = file.rpartition('.')[2].lower()
|
||||||
path = self.path_template % (metadata[i].title, metadata[i].author[0],format)
|
path = self.path_template % (metadata[i].title,
|
||||||
|
authors_to_string(metadata[i].authors),
|
||||||
|
format)
|
||||||
self._remove_existing_copy(path, metadata[i])
|
self._remove_existing_copy(path, metadata[i])
|
||||||
fpath = self._get_fpath(file, metadata[i], format, update_md=True)
|
fpath = self._get_fpath(file, metadata[i], format, update_md=True)
|
||||||
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
||||||
@ -1034,9 +1037,11 @@ class ITUNES(DriverBase):
|
|||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info("ITUNES.upload_books()")
|
self.log.info("ITUNES.upload_books()")
|
||||||
self.log.info(" adding '%s' by '%s' uuid:%s to self.cached_books" %
|
self.log.info(" adding '%s' by '%s' uuid:%s to self.cached_books" %
|
||||||
( metadata[i].title, metadata[i].author, metadata[i].uuid))
|
(metadata[i].title,
|
||||||
|
authors_to_string(metadata[i].authors),
|
||||||
|
metadata[i].uuid))
|
||||||
self.cached_books[this_book.path] = {
|
self.cached_books[this_book.path] = {
|
||||||
'author': metadata[i].author,
|
'author': authors_to_string(metadata[i].authors),
|
||||||
'dev_book': db_added,
|
'dev_book': db_added,
|
||||||
'format': format,
|
'format': format,
|
||||||
'lib_book': lb_added,
|
'lib_book': lb_added,
|
||||||
@ -1055,7 +1060,9 @@ class ITUNES(DriverBase):
|
|||||||
|
|
||||||
for (i,file) in enumerate(files):
|
for (i,file) in enumerate(files):
|
||||||
format = file.rpartition('.')[2].lower()
|
format = file.rpartition('.')[2].lower()
|
||||||
path = self.path_template % (metadata[i].title, metadata[i].author[0],format)
|
path = self.path_template % (metadata[i].title,
|
||||||
|
authors_to_string(metadata[i].authors),
|
||||||
|
format)
|
||||||
self._remove_existing_copy(path, metadata[i])
|
self._remove_existing_copy(path, metadata[i])
|
||||||
fpath = self._get_fpath(file, metadata[i],format, update_md=True)
|
fpath = self._get_fpath(file, metadata[i],format, update_md=True)
|
||||||
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
||||||
@ -1075,9 +1082,11 @@ class ITUNES(DriverBase):
|
|||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info("ITUNES.upload_books()")
|
self.log.info("ITUNES.upload_books()")
|
||||||
self.log.info(" adding '%s' by '%s' uuid:%s to self.cached_books" %
|
self.log.info(" adding '%s' by '%s' uuid:%s to self.cached_books" %
|
||||||
( metadata[i].title, metadata[i].author, metadata[i].uuid))
|
(metadata[i].title,
|
||||||
|
authors_to_string(metadata[i].authors),
|
||||||
|
metadata[i].uuid))
|
||||||
self.cached_books[this_book.path] = {
|
self.cached_books[this_book.path] = {
|
||||||
'author': metadata[i].author[0],
|
'author': authors_to_string(metadata[i].authors),
|
||||||
'dev_book': db_added,
|
'dev_book': db_added,
|
||||||
'format': format,
|
'format': format,
|
||||||
'lib_book': lb_added,
|
'lib_book': lb_added,
|
||||||
@ -1190,7 +1199,7 @@ class ITUNES(DriverBase):
|
|||||||
base_fn = base_fn.rpartition('.')[0]
|
base_fn = base_fn.rpartition('.')[0]
|
||||||
db_added = self._find_device_book(
|
db_added = self._find_device_book(
|
||||||
{ 'title': base_fn if format == 'pdf' else metadata.title,
|
{ 'title': base_fn if format == 'pdf' else metadata.title,
|
||||||
'author': metadata.authors[0],
|
'author': authors_to_string(metadata.authors),
|
||||||
'uuid': metadata.uuid,
|
'uuid': metadata.uuid,
|
||||||
'format': format})
|
'format': format})
|
||||||
return db_added
|
return db_added
|
||||||
@ -1255,7 +1264,7 @@ class ITUNES(DriverBase):
|
|||||||
base_fn = base_fn.rpartition('.')[0]
|
base_fn = base_fn.rpartition('.')[0]
|
||||||
added = self._find_library_book(
|
added = self._find_library_book(
|
||||||
{ 'title': base_fn if format == 'pdf' else metadata.title,
|
{ 'title': base_fn if format == 'pdf' else metadata.title,
|
||||||
'author': metadata.author[0],
|
'author': authors_to_string(metadata.authors),
|
||||||
'uuid': metadata.uuid,
|
'uuid': metadata.uuid,
|
||||||
'format': format})
|
'format': format})
|
||||||
return added
|
return added
|
||||||
@ -1314,7 +1323,7 @@ class ITUNES(DriverBase):
|
|||||||
with open(metadata.cover,'r+b') as cd:
|
with open(metadata.cover,'r+b') as cd:
|
||||||
cover_data = cd.read()
|
cover_data = cd.read()
|
||||||
except:
|
except:
|
||||||
self.problem_titles.append("'%s' by %s" % (metadata.title, metadata.author[0]))
|
self.problem_titles.append("'%s' by %s" % (metadata.title, authors_to_string(metadata.authors)))
|
||||||
self.log.error(" error scaling '%s' for '%s'" % (metadata.cover,metadata.title))
|
self.log.error(" error scaling '%s' for '%s'" % (metadata.cover,metadata.title))
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
@ -1389,7 +1398,7 @@ class ITUNES(DriverBase):
|
|||||||
thumb_path = path.rpartition('.')[0] + '.jpg'
|
thumb_path = path.rpartition('.')[0] + '.jpg'
|
||||||
zfw.writestr(thumb_path, thumb)
|
zfw.writestr(thumb_path, thumb)
|
||||||
except:
|
except:
|
||||||
self.problem_titles.append("'%s' by %s" % (metadata.title, metadata.author[0]))
|
self.problem_titles.append("'%s' by %s" % (metadata.title, authors_to_string(metadata.authors)))
|
||||||
self.log.error(" error converting '%s' to thumb for '%s'" % (metadata.cover,metadata.title))
|
self.log.error(" error converting '%s' to thumb for '%s'" % (metadata.cover,metadata.title))
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
@ -1407,7 +1416,7 @@ class ITUNES(DriverBase):
|
|||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" ITUNES._create_new_book()")
|
self.log.info(" ITUNES._create_new_book()")
|
||||||
|
|
||||||
this_book = Book(metadata.title, authors_to_string(metadata.author))
|
this_book = Book(metadata.title, authors_to_string(metadata.authors))
|
||||||
this_book.datetime = time.gmtime()
|
this_book.datetime = time.gmtime()
|
||||||
this_book.db_id = None
|
this_book.db_id = None
|
||||||
this_book.device_collections = []
|
this_book.device_collections = []
|
||||||
@ -2451,7 +2460,7 @@ class ITUNES(DriverBase):
|
|||||||
for book in self.cached_books:
|
for book in self.cached_books:
|
||||||
if self.cached_books[book]['uuid'] == metadata.uuid or \
|
if self.cached_books[book]['uuid'] == metadata.uuid or \
|
||||||
(self.cached_books[book]['title'] == metadata.title and \
|
(self.cached_books[book]['title'] == metadata.title and \
|
||||||
self.cached_books[book]['author'] == metadata.authors[0]):
|
self.cached_books[book]['author'] == authors_to_string(metadata.authors)):
|
||||||
self.update_list.append(self.cached_books[book])
|
self.update_list.append(self.cached_books[book])
|
||||||
self._remove_from_device(self.cached_books[book])
|
self._remove_from_device(self.cached_books[book])
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
@ -2470,7 +2479,7 @@ class ITUNES(DriverBase):
|
|||||||
for book in self.cached_books:
|
for book in self.cached_books:
|
||||||
if self.cached_books[book]['uuid'] == metadata.uuid or \
|
if self.cached_books[book]['uuid'] == metadata.uuid or \
|
||||||
(self.cached_books[book]['title'] == metadata.title and \
|
(self.cached_books[book]['title'] == metadata.title and \
|
||||||
self.cached_books[book]['author'] == metadata.authors[0]):
|
self.cached_books[book]['author'] == authors_to_string(metadata.authors)):
|
||||||
self.update_list.append(self.cached_books[book])
|
self.update_list.append(self.cached_books[book])
|
||||||
self._remove_from_iTunes(self.cached_books[book])
|
self._remove_from_iTunes(self.cached_books[book])
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
@ -2939,13 +2948,13 @@ class ITUNES(DriverBase):
|
|||||||
def _xform_metadata_via_plugboard(self, book, format):
|
def _xform_metadata_via_plugboard(self, book, format):
|
||||||
''' Transform book metadata from plugboard templates '''
|
''' Transform book metadata from plugboard templates '''
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" ITUNES._xform_metadata_via_plugboard()")
|
self.log.info(" ITUNES._xform_metadata_via_plugboard()")
|
||||||
|
|
||||||
if self.plugboard_func:
|
if self.plugboard_func:
|
||||||
pb = self.plugboard_func(self.DEVICE_PLUGBOARD_NAME, format, self.plugboards)
|
pb = self.plugboard_func(self.DEVICE_PLUGBOARD_NAME, format, self.plugboards)
|
||||||
newmi = book.deepcopy_metadata()
|
newmi = book.deepcopy_metadata()
|
||||||
newmi.template_to_attribute(book, pb)
|
newmi.template_to_attribute(book, pb)
|
||||||
if DEBUG:
|
if pb is not None and DEBUG:
|
||||||
self.log.info(" transforming %s using %s:" % (format, pb))
|
self.log.info(" transforming %s using %s:" % (format, pb))
|
||||||
self.log.info(" title: %s %s" % (book.title, ">>> %s" %
|
self.log.info(" title: %s %s" % (book.title, ">>> %s" %
|
||||||
newmi.title if book.title != newmi.title else ''))
|
newmi.title if book.title != newmi.title else ''))
|
||||||
@ -3062,7 +3071,7 @@ class ITUNES_ASYNC(ITUNES):
|
|||||||
|
|
||||||
cached_books[this_book.path] = {
|
cached_books[this_book.path] = {
|
||||||
'title':library_books[book].name(),
|
'title':library_books[book].name(),
|
||||||
'author':[library_books[book].artist()],
|
'author':library_books[book].artist().split(' & '),
|
||||||
'lib_book':library_books[book],
|
'lib_book':library_books[book],
|
||||||
'dev_book':None,
|
'dev_book':None,
|
||||||
'uuid': library_books[book].composer(),
|
'uuid': library_books[book].composer(),
|
||||||
@ -3102,7 +3111,7 @@ class ITUNES_ASYNC(ITUNES):
|
|||||||
|
|
||||||
cached_books[this_book.path] = {
|
cached_books[this_book.path] = {
|
||||||
'title':library_books[book].Name,
|
'title':library_books[book].Name,
|
||||||
'author':library_books[book].Artist,
|
'author':library_books[book].Artist.split(' & '),
|
||||||
'lib_book':library_books[book],
|
'lib_book':library_books[book],
|
||||||
'uuid': library_books[book].Composer,
|
'uuid': library_books[book].Composer,
|
||||||
'format': format
|
'format': format
|
||||||
@ -3288,7 +3297,7 @@ class Book(Metadata):
|
|||||||
See ebooks.metadata.book.base
|
See ebooks.metadata.book.base
|
||||||
'''
|
'''
|
||||||
def __init__(self,title,author):
|
def __init__(self,title,author):
|
||||||
Metadata.__init__(self, title, authors=[author])
|
Metadata.__init__(self, title, authors=author.split(' & '))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def title_sorter(self):
|
def title_sorter(self):
|
||||||
|
@ -52,6 +52,9 @@ class CHMInput(InputFormatPlugin):
|
|||||||
|
|
||||||
metadata = get_metadata_from_reader(self._chm_reader)
|
metadata = get_metadata_from_reader(self._chm_reader)
|
||||||
self._chm_reader.CloseCHM()
|
self._chm_reader.CloseCHM()
|
||||||
|
#print tdir
|
||||||
|
#from calibre import ipython
|
||||||
|
#ipython()
|
||||||
|
|
||||||
odi = options.debug_pipeline
|
odi = options.debug_pipeline
|
||||||
options.debug_pipeline = None
|
options.debug_pipeline = None
|
||||||
|
@ -147,7 +147,8 @@ class CHMReader(CHMFile):
|
|||||||
if self.hhc_path == '.hhc' and self.hhc_path not in files:
|
if self.hhc_path == '.hhc' and self.hhc_path not in files:
|
||||||
from calibre import walk
|
from calibre import walk
|
||||||
for x in walk(output_dir):
|
for x in walk(output_dir):
|
||||||
if os.path.basename(x).lower() in ('index.htm', 'index.html'):
|
if os.path.basename(x).lower() in ('index.htm', 'index.html',
|
||||||
|
'contents.htm', 'contents.html'):
|
||||||
self.hhc_path = os.path.relpath(x, output_dir)
|
self.hhc_path = os.path.relpath(x, output_dir)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#define BUFFER 6000
|
#define BUFFER 6000
|
||||||
|
|
||||||
#define MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
|
#define MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
|
||||||
|
#define MAX(x, y) ( ((x) > (y)) ? (x) : (y) )
|
||||||
|
|
||||||
typedef unsigned short int Byte;
|
typedef unsigned short int Byte;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -53,7 +54,7 @@ cpalmdoc_decompress(PyObject *self, PyObject *args) {
|
|||||||
// Map chars to bytes
|
// Map chars to bytes
|
||||||
for (j = 0; j < input_len; j++)
|
for (j = 0; j < input_len; j++)
|
||||||
input[j] = (_input[j] < 0) ? _input[j]+256 : _input[j];
|
input[j] = (_input[j] < 0) ? _input[j]+256 : _input[j];
|
||||||
output = (char *)PyMem_Malloc(sizeof(char)*BUFFER);
|
output = (char *)PyMem_Malloc(sizeof(char)*(MAX(BUFFER, 5*input_len)));
|
||||||
if (output == NULL) return PyErr_NoMemory();
|
if (output == NULL) return PyErr_NoMemory();
|
||||||
|
|
||||||
while (i < input_len) {
|
while (i < input_len) {
|
||||||
|
@ -114,8 +114,12 @@ class ISBNMerge(object):
|
|||||||
|
|
||||||
return self.results
|
return self.results
|
||||||
|
|
||||||
def merge_metadata_results(self):
|
def merge_metadata_results(self, merge_on_identifiers=False):
|
||||||
' Merge results with identical title and authors '
|
'''
|
||||||
|
Merge results with identical title and authors or an identical
|
||||||
|
identifier
|
||||||
|
'''
|
||||||
|
# First title/author
|
||||||
groups = {}
|
groups = {}
|
||||||
for result in self.results:
|
for result in self.results:
|
||||||
title = lower(result.title if result.title else '')
|
title = lower(result.title if result.title else '')
|
||||||
@ -135,6 +139,44 @@ class ISBNMerge(object):
|
|||||||
result = rgroup[0]
|
result = rgroup[0]
|
||||||
self.results.append(result)
|
self.results.append(result)
|
||||||
|
|
||||||
|
if merge_on_identifiers:
|
||||||
|
# Now identifiers
|
||||||
|
groups, empty = {}, []
|
||||||
|
for result in self.results:
|
||||||
|
key = set()
|
||||||
|
for typ, val in result.identifiers.iteritems():
|
||||||
|
if typ and val:
|
||||||
|
key.add((typ, val))
|
||||||
|
if key:
|
||||||
|
key = frozenset(key)
|
||||||
|
match = None
|
||||||
|
for candidate in list(groups):
|
||||||
|
if candidate.intersection(key):
|
||||||
|
# We have at least one identifier in common
|
||||||
|
match = candidate.union(key)
|
||||||
|
results = groups.pop(candidate)
|
||||||
|
results.append(result)
|
||||||
|
groups[match] = results
|
||||||
|
break
|
||||||
|
if match is None:
|
||||||
|
groups[key] = [result]
|
||||||
|
else:
|
||||||
|
empty.append(result)
|
||||||
|
|
||||||
|
if len(groups) != len(self.results):
|
||||||
|
self.results = []
|
||||||
|
for rgroup in groups.itervalues():
|
||||||
|
rel = [r.average_source_relevance for r in rgroup]
|
||||||
|
if len(rgroup) > 1:
|
||||||
|
result = self.merge(rgroup, None, do_asr=False)
|
||||||
|
result.average_source_relevance = sum(rel)/len(rel)
|
||||||
|
elif rgroup:
|
||||||
|
result = rgroup[0]
|
||||||
|
self.results.append(result)
|
||||||
|
|
||||||
|
if empty:
|
||||||
|
self.results.extend(empty)
|
||||||
|
|
||||||
self.results.sort(key=attrgetter('average_source_relevance'))
|
self.results.sort(key=attrgetter('average_source_relevance'))
|
||||||
|
|
||||||
def merge_isbn_results(self):
|
def merge_isbn_results(self):
|
||||||
|
@ -15,14 +15,17 @@ from calibre.customize.ui import metadata_plugins
|
|||||||
from calibre import prints, sanitize_file_name2
|
from calibre import prints, sanitize_file_name2
|
||||||
from calibre.ebooks.metadata import check_isbn
|
from calibre.ebooks.metadata import check_isbn
|
||||||
from calibre.ebooks.metadata.sources.base import (create_log,
|
from calibre.ebooks.metadata.sources.base import (create_log,
|
||||||
get_cached_cover_urls)
|
get_cached_cover_urls, msprefs)
|
||||||
|
|
||||||
def isbn_test(isbn):
|
def isbn_test(isbn):
|
||||||
isbn_ = check_isbn(isbn)
|
isbn_ = check_isbn(isbn)
|
||||||
|
|
||||||
def test(mi):
|
def test(mi):
|
||||||
misbn = check_isbn(mi.isbn)
|
misbn = check_isbn(mi.isbn)
|
||||||
return misbn and misbn == isbn_
|
if misbn and misbn == isbn_:
|
||||||
|
return True
|
||||||
|
prints('ISBN test failed. Expected: \'%s\' found \'%s\''%(isbn_, misbn))
|
||||||
|
return False
|
||||||
|
|
||||||
return test
|
return test
|
||||||
|
|
||||||
@ -32,8 +35,11 @@ def title_test(title, exact=False):
|
|||||||
|
|
||||||
def test(mi):
|
def test(mi):
|
||||||
mt = mi.title.lower()
|
mt = mi.title.lower()
|
||||||
return (exact and mt == title) or \
|
if (exact and mt == title) or \
|
||||||
(not exact and title in mt)
|
(not exact and title in mt):
|
||||||
|
return True
|
||||||
|
prints('Title test failed. Expected: \'%s\' found \'%s\''%(title, mt))
|
||||||
|
return False
|
||||||
|
|
||||||
return test
|
return test
|
||||||
|
|
||||||
@ -42,7 +48,22 @@ def authors_test(authors):
|
|||||||
|
|
||||||
def test(mi):
|
def test(mi):
|
||||||
au = set([x.lower() for x in mi.authors])
|
au = set([x.lower() for x in mi.authors])
|
||||||
return au == authors
|
if msprefs['swap_author_names']:
|
||||||
|
def revert_to_fn_ln(a):
|
||||||
|
if ',' not in a:
|
||||||
|
return a
|
||||||
|
parts = a.split(',', 1)
|
||||||
|
t = parts[-1]
|
||||||
|
parts = parts[:-1]
|
||||||
|
parts.insert(0, t)
|
||||||
|
return ' '.join(parts)
|
||||||
|
|
||||||
|
au = set([revert_to_fn_ln(x) for x in au])
|
||||||
|
|
||||||
|
if au == authors:
|
||||||
|
return True
|
||||||
|
prints('Author test failed. Expected: \'%s\' found \'%s\''%(authors, au))
|
||||||
|
return False
|
||||||
|
|
||||||
return test
|
return test
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ from calibre.translations.dynamic import translate
|
|||||||
from calibre.ebooks.chardet import xml_to_unicode
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from calibre.ebooks.oeb.entitydefs import ENTITYDEFS
|
from calibre.ebooks.oeb.entitydefs import ENTITYDEFS
|
||||||
from calibre.ebooks.conversion.preprocess import CSSPreProcessor
|
from calibre.ebooks.conversion.preprocess import CSSPreProcessor
|
||||||
from calibre import isbytestring
|
from calibre import isbytestring, as_unicode
|
||||||
|
|
||||||
RECOVER_PARSER = etree.XMLParser(recover=True, no_network=True)
|
RECOVER_PARSER = etree.XMLParser(recover=True, no_network=True)
|
||||||
|
|
||||||
@ -643,7 +643,7 @@ class Metadata(object):
|
|||||||
return unicode(self.value).encode('ascii', 'xmlcharrefreplace')
|
return unicode(self.value).encode('ascii', 'xmlcharrefreplace')
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return unicode(self.value)
|
return as_unicode(self.value)
|
||||||
|
|
||||||
def to_opf1(self, dcmeta=None, xmeta=None, nsrmap={}):
|
def to_opf1(self, dcmeta=None, xmeta=None, nsrmap={}):
|
||||||
attrib = {}
|
attrib = {}
|
||||||
|
@ -648,6 +648,18 @@ def open_url(qurl):
|
|||||||
if isfrozen and islinux and paths:
|
if isfrozen and islinux and paths:
|
||||||
os.environ['LD_LIBRARY_PATH'] = os.pathsep.join(paths)
|
os.environ['LD_LIBRARY_PATH'] = os.pathsep.join(paths)
|
||||||
|
|
||||||
|
def get_current_db():
|
||||||
|
'''
|
||||||
|
This method will try to return the current database in use by the user as
|
||||||
|
efficiently as possible, i.e. without constructing duplicate
|
||||||
|
LibraryDatabase objects.
|
||||||
|
'''
|
||||||
|
from calibre.gui2.ui import get_gui
|
||||||
|
gui = get_gui()
|
||||||
|
if gui is not None and gui.current_db is not None:
|
||||||
|
return gui.current_db
|
||||||
|
from calibre.library import db
|
||||||
|
return db()
|
||||||
|
|
||||||
def open_local_file(path):
|
def open_local_file(path):
|
||||||
if iswindows:
|
if iswindows:
|
||||||
|
@ -17,7 +17,7 @@ from calibre.gui2.actions import InterfaceAction
|
|||||||
class GenerateCatalogAction(InterfaceAction):
|
class GenerateCatalogAction(InterfaceAction):
|
||||||
|
|
||||||
name = 'Generate Catalog'
|
name = 'Generate Catalog'
|
||||||
action_spec = (_('Create a catalog of the books in your calibre library'), None, None, None)
|
action_spec = (_('Create a catalog of the books in your calibre library'), 'catalog.png', 'Catalog builder', None)
|
||||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||||
|
|
||||||
def generate_catalog(self):
|
def generate_catalog(self):
|
||||||
|
@ -483,8 +483,15 @@ class BookDetails(QWidget): # {{{
|
|||||||
self.book_info.show_data(data)
|
self.book_info.show_data(data)
|
||||||
self.cover_view.show_data(data)
|
self.cover_view.show_data(data)
|
||||||
self._layout.do_layout(self.rect())
|
self._layout.do_layout(self.rect())
|
||||||
self.setToolTip('<p>'+_('Double-click to open Book Details window') +
|
try:
|
||||||
'<br><br>' + _('Path') + ': ' + data.get(_('Path'), ''))
|
sz = self.cover_view.pixmap.size()
|
||||||
|
except:
|
||||||
|
sz = QSize(0, 0)
|
||||||
|
self.setToolTip(
|
||||||
|
'<p>'+_('Double-click to open Book Details window') +
|
||||||
|
'<br><br>' + _('Path') + ': ' + data.get(_('Path'), '') +
|
||||||
|
'<br><br>' + _('Cover size: %dx%d')%(sz.width(), sz.height())
|
||||||
|
)
|
||||||
|
|
||||||
def reset_info(self):
|
def reset_info(self):
|
||||||
self.show_data({})
|
self.show_data({})
|
||||||
|
@ -109,6 +109,8 @@ class BookInfo(QDialog, Ui_BookInfo):
|
|||||||
pixmap = pixmap.scaled(new_width, new_height,
|
pixmap = pixmap.scaled(new_width, new_height,
|
||||||
Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||||||
self.cover.set_pixmap(pixmap)
|
self.cover.set_pixmap(pixmap)
|
||||||
|
sz = pixmap.size()
|
||||||
|
self.cover.setToolTip(_('Cover size: %dx%d')%(sz.width(), sz.height()))
|
||||||
|
|
||||||
def refresh(self, row):
|
def refresh(self, row):
|
||||||
if isinstance(row, QModelIndex):
|
if isinstance(row, QModelIndex):
|
||||||
|
@ -12,6 +12,7 @@ from zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED
|
|||||||
|
|
||||||
from PyQt4.Qt import QDialog
|
from PyQt4.Qt import QDialog
|
||||||
|
|
||||||
|
from calibre.constants import isosx, iswindows
|
||||||
from calibre.gui2 import open_local_file
|
from calibre.gui2 import open_local_file
|
||||||
from calibre.gui2.dialogs.tweak_epub_ui import Ui_Dialog
|
from calibre.gui2.dialogs.tweak_epub_ui import Ui_Dialog
|
||||||
from calibre.libunzip import extract as zipextract
|
from calibre.libunzip import extract as zipextract
|
||||||
@ -42,11 +43,19 @@ class TweakEpub(QDialog, Ui_Dialog):
|
|||||||
self.move(parent_loc.x(),parent_loc.y())
|
self.move(parent_loc.x(),parent_loc.y())
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
|
if isosx:
|
||||||
|
try:
|
||||||
|
import appscript
|
||||||
|
self.finder = appscript.app('Finder')
|
||||||
|
self.finder.Finder_windows[os.path.basename(self._exploded)].close()
|
||||||
|
except:
|
||||||
|
# appscript fails to load on 10.4
|
||||||
|
pass
|
||||||
|
|
||||||
# Delete directory containing exploded ePub
|
# Delete directory containing exploded ePub
|
||||||
if self._exploded is not None:
|
if self._exploded is not None:
|
||||||
shutil.rmtree(self._exploded, ignore_errors=True)
|
shutil.rmtree(self._exploded, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
def display_exploded(self):
|
def display_exploded(self):
|
||||||
'''
|
'''
|
||||||
Generic subprocess launch of native file browser
|
Generic subprocess launch of native file browser
|
||||||
|
@ -317,9 +317,8 @@ class BaseToolBar(QToolBar): # {{{
|
|||||||
QToolBar.resizeEvent(self, ev)
|
QToolBar.resizeEvent(self, ev)
|
||||||
style = self.get_text_style()
|
style = self.get_text_style()
|
||||||
self.setToolButtonStyle(style)
|
self.setToolButtonStyle(style)
|
||||||
if hasattr(self, 'd_widget'):
|
if hasattr(self, 'd_widget') and hasattr(self.d_widget, 'filler'):
|
||||||
if hasattr(self.d_widget, 'filler'):
|
self.d_widget.filler.setVisible(style != Qt.ToolButtonIconOnly)
|
||||||
self.d_widget.filler.setVisible(style != Qt.ToolButtonIconOnly)
|
|
||||||
|
|
||||||
def get_text_style(self):
|
def get_text_style(self):
|
||||||
style = Qt.ToolButtonTextUnderIcon
|
style = Qt.ToolButtonTextUnderIcon
|
||||||
|
@ -73,13 +73,13 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
choices=sorted(list(choices), key=sort_key))
|
choices=sorted(list(choices), key=sort_key))
|
||||||
|
|
||||||
|
|
||||||
self.current_font = None
|
self.current_font = self.initial_font = None
|
||||||
self.change_font_button.clicked.connect(self.change_font)
|
self.change_font_button.clicked.connect(self.change_font)
|
||||||
|
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
ConfigWidgetBase.initialize(self)
|
ConfigWidgetBase.initialize(self)
|
||||||
self.current_font = gprefs['font']
|
self.current_font = self.initial_font = gprefs['font']
|
||||||
self.update_font_display()
|
self.update_font_display()
|
||||||
|
|
||||||
def restore_defaults(self):
|
def restore_defaults(self):
|
||||||
@ -119,7 +119,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
|
|
||||||
def commit(self, *args):
|
def commit(self, *args):
|
||||||
rr = ConfigWidgetBase.commit(self, *args)
|
rr = ConfigWidgetBase.commit(self, *args)
|
||||||
if self.current_font != gprefs['font']:
|
if self.current_font != self.initial_font:
|
||||||
gprefs['font'] = self.current_font
|
gprefs['font'] = self.current_font
|
||||||
QApplication.setFont(self.font_display.font())
|
QApplication.setFont(self.font_display.font())
|
||||||
rr = True
|
rr = True
|
||||||
|
@ -88,6 +88,11 @@ class SystemTrayIcon(QSystemTrayIcon): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
_gui = None
|
||||||
|
|
||||||
|
def get_gui():
|
||||||
|
return _gui
|
||||||
|
|
||||||
class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||||
TagBrowserMixin, CoverFlowMixin, LibraryViewMixin, SearchBoxMixin,
|
TagBrowserMixin, CoverFlowMixin, LibraryViewMixin, SearchBoxMixin,
|
||||||
SavedSearchBoxMixin, SearchRestrictionMixin, LayoutMixin, UpdateMixin,
|
SavedSearchBoxMixin, SearchRestrictionMixin, LayoutMixin, UpdateMixin,
|
||||||
@ -97,7 +102,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
|
|
||||||
|
|
||||||
def __init__(self, opts, parent=None, gui_debug=None):
|
def __init__(self, opts, parent=None, gui_debug=None):
|
||||||
|
global _gui
|
||||||
MainWindow.__init__(self, opts, parent=parent, disable_automatic_gc=True)
|
MainWindow.__init__(self, opts, parent=parent, disable_automatic_gc=True)
|
||||||
|
_gui = self
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.device_connected = None
|
self.device_connected = None
|
||||||
self.gui_debug = gui_debug
|
self.gui_debug = gui_debug
|
||||||
|
Loading…
x
Reference in New Issue
Block a user