mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from source
This commit is contained in:
commit
f22868e769
@ -33,6 +33,6 @@ class SNE(USBMS):
|
||||
STORAGE_CARD_VOLUME_LABEL = 'SNE Storage Card'
|
||||
|
||||
EBOOK_DIR_MAIN = EBOOK_DIR_CARD_A = 'Books'
|
||||
SUPPORTS_SUB_DIRS = True
|
||||
SUPPORTS_SUB_DIRS = False
|
||||
|
||||
|
||||
|
@ -141,6 +141,7 @@ class DefaultEncoding:
|
||||
self.__code_page = '850'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
encode_obj = DefaultEncoding(
|
||||
in_file = sys.argv[1],
|
||||
bug_handler = Exception,
|
||||
|
@ -199,7 +199,8 @@ class DeleteInfo:
|
||||
# Get action to perform
|
||||
action = self.__state_dict.get(self.__state)
|
||||
if not action:
|
||||
sys.stderr.write('No action in dictionary state is "%s" \n' % self.__state)
|
||||
sys.stderr.write('No action in dictionary state is "%s" \n'
|
||||
% self.__state)
|
||||
# Print if allowed by action
|
||||
if action(line):
|
||||
self.__write_obj.write(line)
|
||||
|
@ -28,7 +28,7 @@ class GenerateCatalogAction(InterfaceAction):
|
||||
|
||||
if not ids:
|
||||
return error_dialog(self.gui, _('No books selected'),
|
||||
_('No books selected to generate catalog for'),
|
||||
_('No books selected for catalog generation'),
|
||||
show=True)
|
||||
|
||||
db = self.gui.library_view.model().db
|
||||
@ -55,9 +55,9 @@ class GenerateCatalogAction(InterfaceAction):
|
||||
|
||||
def catalog_generated(self, job):
|
||||
if job.result:
|
||||
# Search terms nulled catalog results
|
||||
return error_dialog(self.gui, _('No books found'),
|
||||
_("No books to catalog\nCheck job details"),
|
||||
# Error during catalog generation
|
||||
return error_dialog(self.gui, _('Catalog generation terminated'),
|
||||
job.result,
|
||||
show=True)
|
||||
if job.failed:
|
||||
return self.gui.job_exception(job)
|
||||
|
@ -1144,7 +1144,9 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
def error(self):
|
||||
def fget(self):
|
||||
return self.__error
|
||||
return property(fget=fget)
|
||||
def fset(self, val):
|
||||
self.__error = val
|
||||
return property(fget=fget,fset=fset)
|
||||
@dynamic_property
|
||||
def generateForKindle(self):
|
||||
def fget(self):
|
||||
@ -1411,6 +1413,88 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
except:
|
||||
pass
|
||||
|
||||
def fetchBooksByAuthor(self):
|
||||
'''
|
||||
Generate a list of titles sorted by author from the database
|
||||
return = Success
|
||||
'''
|
||||
|
||||
self.updateProgressFullStep("Sorting database")
|
||||
|
||||
'''
|
||||
# Sort titles case-insensitive, by author
|
||||
self.booksByAuthor = sorted(self.booksByTitle,
|
||||
key=lambda x:(x['author_sort'].upper(), x['author_sort'].upper()))
|
||||
'''
|
||||
|
||||
self.booksByAuthor = list(self.booksByTitle)
|
||||
self.booksByAuthor.sort(self.author_compare)
|
||||
|
||||
if False and self.verbose:
|
||||
self.opts.log.info("fetchBooksByAuthor(): %d books" % len(self.booksByAuthor))
|
||||
self.opts.log.info(" %-30s %-20s %s" % ('title', 'series', 'series_index'))
|
||||
for title in self.booksByAuthor:
|
||||
self.opts.log.info((u" %-30s %-20s%5s " % \
|
||||
(title['title'][:30],
|
||||
title['series'][:20] if title['series'] else '',
|
||||
title['series_index'],
|
||||
)).encode('utf-8'))
|
||||
raise SystemExit
|
||||
|
||||
# Build the unique_authors set from existing data
|
||||
authors = [(record['author'], record['author_sort'].capitalize()) for record in self.booksByAuthor]
|
||||
|
||||
# authors[] contains a list of all book authors, with multiple entries for multiple books by author
|
||||
# authors[]: (([0]:friendly [1]:sort))
|
||||
# unique_authors[]: (([0]:friendly [1]:sort [2]:book_count))
|
||||
books_by_current_author = 0
|
||||
current_author = authors[0]
|
||||
multiple_authors = False
|
||||
unique_authors = []
|
||||
for (i,author) in enumerate(authors):
|
||||
if author != current_author:
|
||||
# Note that current_author and author are tuples: (friendly, sort)
|
||||
multiple_authors = True
|
||||
|
||||
if author != current_author and i:
|
||||
# Warn, exit if friendly matches previous, but sort doesn't
|
||||
if author[0] == current_author[0]:
|
||||
error_msg = _('''
|
||||
\n*** Metadata error ***
|
||||
Inconsistent Author Sort values for Author '{0}', unable to continue building catalog.
|
||||
Select all books by '{0}', apply correct Author Sort value in Edit Metadata dialog,
|
||||
then rebuild the catalog.\n''').format(author[0])
|
||||
|
||||
self.opts.log.warn(error_msg)
|
||||
self.error = error_msg
|
||||
return False
|
||||
|
||||
# New author, save the previous author/sort/count
|
||||
unique_authors.append((current_author[0], icu_title(current_author[1]),
|
||||
books_by_current_author))
|
||||
current_author = author
|
||||
books_by_current_author = 1
|
||||
elif i==0 and len(authors) == 1:
|
||||
# Allow for single-book lists
|
||||
unique_authors.append((current_author[0], icu_title(current_author[1]),
|
||||
books_by_current_author))
|
||||
else:
|
||||
books_by_current_author += 1
|
||||
else:
|
||||
# Add final author to list or single-author dataset
|
||||
if (current_author == author and len(authors) > 1) or not multiple_authors:
|
||||
unique_authors.append((current_author[0], icu_title(current_author[1]),
|
||||
books_by_current_author))
|
||||
|
||||
if False and self.verbose:
|
||||
self.opts.log.info("\nfetchBooksByauthor(): %d unique authors" % len(unique_authors))
|
||||
for author in unique_authors:
|
||||
self.opts.log.info((u" %-50s %-25s %2d" % (author[0][0:45], author[1][0:20],
|
||||
author[2])).encode('utf-8'))
|
||||
|
||||
self.authors = unique_authors
|
||||
return True
|
||||
|
||||
def fetchBooksByTitle(self):
|
||||
|
||||
self.updateProgressFullStep("Fetching database")
|
||||
@ -1562,90 +1646,9 @@ class EPUB_MOBI(CatalogPlugin):
|
||||
title['title_sort'][0:40])).decode('mac-roman'))
|
||||
return True
|
||||
else:
|
||||
self.error = _("No books found to catalog.\nCheck 'Excluded books' criteria in E-book options.")
|
||||
return False
|
||||
|
||||
def fetchBooksByAuthor(self):
|
||||
'''
|
||||
Generate a list of titles sorted by author from the database
|
||||
return = Success
|
||||
'''
|
||||
|
||||
self.updateProgressFullStep("Sorting database")
|
||||
|
||||
'''
|
||||
# Sort titles case-insensitive, by author
|
||||
self.booksByAuthor = sorted(self.booksByTitle,
|
||||
key=lambda x:(x['author_sort'].upper(), x['author_sort'].upper()))
|
||||
'''
|
||||
|
||||
self.booksByAuthor = list(self.booksByTitle)
|
||||
self.booksByAuthor.sort(self.author_compare)
|
||||
|
||||
if False and self.verbose:
|
||||
self.opts.log.info("fetchBooksByAuthor(): %d books" % len(self.booksByAuthor))
|
||||
self.opts.log.info(" %-30s %-20s %s" % ('title', 'series', 'series_index'))
|
||||
for title in self.booksByAuthor:
|
||||
self.opts.log.info((u" %-30s %-20s%5s " % \
|
||||
(title['title'][:30],
|
||||
title['series'][:20] if title['series'] else '',
|
||||
title['series_index'],
|
||||
)).encode('utf-8'))
|
||||
raise SystemExit
|
||||
|
||||
# Build the unique_authors set from existing data
|
||||
authors = [(record['author'], record['author_sort'].capitalize()) for record in self.booksByAuthor]
|
||||
|
||||
# authors[] contains a list of all book authors, with multiple entries for multiple books by author
|
||||
# authors[]: (([0]:friendly [1]:sort))
|
||||
# unique_authors[]: (([0]:friendly [1]:sort [2]:book_count))
|
||||
books_by_current_author = 0
|
||||
current_author = authors[0]
|
||||
multiple_authors = False
|
||||
unique_authors = []
|
||||
for (i,author) in enumerate(authors):
|
||||
if author != current_author:
|
||||
# Note that current_author and author are tuples: (friendly, sort)
|
||||
multiple_authors = True
|
||||
|
||||
if author != current_author and i:
|
||||
# Warn, exit if friendly matches previous, but sort doesn't
|
||||
if author[0] == current_author[0]:
|
||||
error_msg = _('''
|
||||
\n*** Metadata error ***
|
||||
Inconsistent Author Sort values for Author '{0}', unable to continue building catalog.
|
||||
Select all books by '{0}', apply correct Author Sort value in Edit Metadata dialog,
|
||||
then rebuild the catalog.
|
||||
*** Terminating catalog generation ***\n''').format(author[0])
|
||||
|
||||
self.opts.log.warn(error_msg)
|
||||
return False
|
||||
|
||||
# New author, save the previous author/sort/count
|
||||
unique_authors.append((current_author[0], icu_title(current_author[1]),
|
||||
books_by_current_author))
|
||||
current_author = author
|
||||
books_by_current_author = 1
|
||||
elif i==0 and len(authors) == 1:
|
||||
# Allow for single-book lists
|
||||
unique_authors.append((current_author[0], icu_title(current_author[1]),
|
||||
books_by_current_author))
|
||||
else:
|
||||
books_by_current_author += 1
|
||||
else:
|
||||
# Add final author to list or single-author dataset
|
||||
if (current_author == author and len(authors) > 1) or not multiple_authors:
|
||||
unique_authors.append((current_author[0], icu_title(current_author[1]),
|
||||
books_by_current_author))
|
||||
|
||||
if False and self.verbose:
|
||||
self.opts.log.info("\nfetchBooksByauthor(): %d unique authors" % len(unique_authors))
|
||||
for author in unique_authors:
|
||||
self.opts.log.info((u" %-50s %-25s %2d" % (author[0][0:45], author[1][0:20],
|
||||
author[2])).encode('utf-8'))
|
||||
|
||||
self.authors = unique_authors
|
||||
return True
|
||||
|
||||
def fetchBookmarks(self):
|
||||
'''
|
||||
Collect bookmarks for catalog entries
|
||||
@ -5069,6 +5072,8 @@ then rebuild the catalog.
|
||||
abort_after_input_dump=False)
|
||||
plumber.merge_ui_recommendations(recommendations)
|
||||
plumber.run()
|
||||
return 0
|
||||
# returns to gui2.actions.catalog:catalog_generated()
|
||||
return None
|
||||
else:
|
||||
return 1
|
||||
# returns to gui2.actions.catalog:catalog_generated()
|
||||
return catalog.error
|
||||
|
@ -693,8 +693,12 @@ def command_catalog(args, dbpath):
|
||||
}
|
||||
|
||||
with plugin:
|
||||
plugin.run(args[1], opts, get_db(dbpath, opts))
|
||||
return 0
|
||||
ret = plugin.run(args[1], opts, get_db(dbpath, opts))
|
||||
if ret is None:
|
||||
ret = 0
|
||||
else:
|
||||
ret = 1
|
||||
return ret
|
||||
|
||||
# end of GR additions
|
||||
|
||||
|
@ -437,6 +437,15 @@ My antivirus program claims |app| is a virus/trojan?
|
||||
|
||||
Your antivirus program is wrong. |app| is a completely open source product. You can actually browse the source code yourself (or hire someone to do it for you) to verify that it is not a virus. Please report the false identification to whatever company you buy your antivirus software from. If the antivirus program is preventing you from downloading/installing |app|, disable it temporarily, install |app| and then re-enable it.
|
||||
|
||||
How do I backup |app|?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The most important thing to backup is the |app| library folder, that contains all your books and metadata. This is the folder you chose for your |app| library when you ran |app| for the first time. You can get the path to the library folder by clicking the |app| icon on the main toolbar. You must backup this complete folder with all its files and sub-folders.
|
||||
|
||||
You can switch |app| to using a backed up library folder by simply clicking the |app| icon on the toolbar and choosing your backup library folder.
|
||||
|
||||
If you want to backup the |app| configuration/plugins, you have to backup the config directory. You can find this config directory via :guilabel:`Preferences->Miscellaneous`. Note that restoring configuration directories is not officially supported, but should work in most cases. Just copy the contents of the backup directory into the current configuration directory to restore.
|
||||
|
||||
How do I use purchased EPUB books with |app|?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Most purchased EPUB books have `DRM <http://wiki.mobileread.com/wiki/DRM>`_. This prevents |app| from opening them. You can still use |app| to store and transfer them to your e-book reader. First, you must authorize your reader on a windows machine with Adobe Digital Editions. Once this is done, EPUB books transferred with |app| will work fine on your reader. When you purchase an epub book from a website, you will get an ".acsm" file. This file should be opened with Adobe Digital Editions, which will then download the actual ".epub" e-book. The e-book file will be stored in the folder "My Digital Editions", from where you can add it to |app|.
|
||||
|
Loading…
x
Reference in New Issue
Block a user