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'
|
STORAGE_CARD_VOLUME_LABEL = 'SNE Storage Card'
|
||||||
|
|
||||||
EBOOK_DIR_MAIN = EBOOK_DIR_CARD_A = 'Books'
|
EBOOK_DIR_MAIN = EBOOK_DIR_CARD_A = 'Books'
|
||||||
SUPPORTS_SUB_DIRS = True
|
SUPPORTS_SUB_DIRS = False
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ class DefaultEncoding:
|
|||||||
else:
|
else:
|
||||||
fenc = re.compile(r'\\(mac|pc|ansi|pca)[\\ \{\}\t\n]+')
|
fenc = re.compile(r'\\(mac|pc|ansi|pca)[\\ \{\}\t\n]+')
|
||||||
fenccp = re.compile(r'\\ansicpg(\d+)[\\ \{\}\t\n]+')
|
fenccp = re.compile(r'\\ansicpg(\d+)[\\ \{\}\t\n]+')
|
||||||
|
|
||||||
for line in read_obj:
|
for line in read_obj:
|
||||||
if fenc.search(line):
|
if fenc.search(line):
|
||||||
enc = fenc.search(line).group(1)
|
enc = fenc.search(line).group(1)
|
||||||
@ -141,6 +141,7 @@ class DefaultEncoding:
|
|||||||
self.__code_page = '850'
|
self.__code_page = '850'
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
encode_obj = DefaultEncoding(
|
encode_obj = DefaultEncoding(
|
||||||
in_file = sys.argv[1],
|
in_file = sys.argv[1],
|
||||||
bug_handler = Exception,
|
bug_handler = Exception,
|
||||||
|
@ -199,7 +199,8 @@ class DeleteInfo:
|
|||||||
# Get action to perform
|
# Get action to perform
|
||||||
action = self.__state_dict.get(self.__state)
|
action = self.__state_dict.get(self.__state)
|
||||||
if not action:
|
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
|
# Print if allowed by action
|
||||||
if action(line):
|
if action(line):
|
||||||
self.__write_obj.write(line)
|
self.__write_obj.write(line)
|
||||||
|
@ -28,7 +28,7 @@ class GenerateCatalogAction(InterfaceAction):
|
|||||||
|
|
||||||
if not ids:
|
if not ids:
|
||||||
return error_dialog(self.gui, _('No books selected'),
|
return error_dialog(self.gui, _('No books selected'),
|
||||||
_('No books selected to generate catalog for'),
|
_('No books selected for catalog generation'),
|
||||||
show=True)
|
show=True)
|
||||||
|
|
||||||
db = self.gui.library_view.model().db
|
db = self.gui.library_view.model().db
|
||||||
@ -55,9 +55,9 @@ class GenerateCatalogAction(InterfaceAction):
|
|||||||
|
|
||||||
def catalog_generated(self, job):
|
def catalog_generated(self, job):
|
||||||
if job.result:
|
if job.result:
|
||||||
# Search terms nulled catalog results
|
# Error during catalog generation
|
||||||
return error_dialog(self.gui, _('No books found'),
|
return error_dialog(self.gui, _('Catalog generation terminated'),
|
||||||
_("No books to catalog\nCheck job details"),
|
job.result,
|
||||||
show=True)
|
show=True)
|
||||||
if job.failed:
|
if job.failed:
|
||||||
return self.gui.job_exception(job)
|
return self.gui.job_exception(job)
|
||||||
|
@ -1144,7 +1144,9 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
def error(self):
|
def error(self):
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return self.__error
|
return self.__error
|
||||||
return property(fget=fget)
|
def fset(self, val):
|
||||||
|
self.__error = val
|
||||||
|
return property(fget=fget,fset=fset)
|
||||||
@dynamic_property
|
@dynamic_property
|
||||||
def generateForKindle(self):
|
def generateForKindle(self):
|
||||||
def fget(self):
|
def fget(self):
|
||||||
@ -1411,6 +1413,88 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
except:
|
except:
|
||||||
pass
|
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):
|
def fetchBooksByTitle(self):
|
||||||
|
|
||||||
self.updateProgressFullStep("Fetching database")
|
self.updateProgressFullStep("Fetching database")
|
||||||
@ -1562,90 +1646,9 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
title['title_sort'][0:40])).decode('mac-roman'))
|
title['title_sort'][0:40])).decode('mac-roman'))
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
self.error = _("No books found to catalog.\nCheck 'Excluded books' criteria in E-book options.")
|
||||||
return False
|
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):
|
def fetchBookmarks(self):
|
||||||
'''
|
'''
|
||||||
Collect bookmarks for catalog entries
|
Collect bookmarks for catalog entries
|
||||||
@ -5069,6 +5072,8 @@ then rebuild the catalog.
|
|||||||
abort_after_input_dump=False)
|
abort_after_input_dump=False)
|
||||||
plumber.merge_ui_recommendations(recommendations)
|
plumber.merge_ui_recommendations(recommendations)
|
||||||
plumber.run()
|
plumber.run()
|
||||||
return 0
|
# returns to gui2.actions.catalog:catalog_generated()
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
return 1
|
# returns to gui2.actions.catalog:catalog_generated()
|
||||||
|
return catalog.error
|
||||||
|
@ -693,8 +693,12 @@ def command_catalog(args, dbpath):
|
|||||||
}
|
}
|
||||||
|
|
||||||
with plugin:
|
with plugin:
|
||||||
plugin.run(args[1], opts, get_db(dbpath, opts))
|
ret = plugin.run(args[1], opts, get_db(dbpath, opts))
|
||||||
return 0
|
if ret is None:
|
||||||
|
ret = 0
|
||||||
|
else:
|
||||||
|
ret = 1
|
||||||
|
return ret
|
||||||
|
|
||||||
# end of GR additions
|
# 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.
|
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|?
|
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|.
|
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