diff --git a/resources/catalog/help_epub_mobi.html b/resources/catalog/help_epub_mobi.html new file mode 100644 index 0000000000..9eb491697d --- /dev/null +++ b/resources/catalog/help_epub_mobi.html @@ -0,0 +1,193 @@ + + + + +Untitled Document + + + + +

AZW3 • EPUB • MOBI Catalogs

+

Selecting books to catalog

+

Included sections: Selecting which sections to include in the catalog

+

Prefixes: Adding a prefix indicating book status

+

Excluded books: Ignoring certain books when generating the catalog

+

Excluded genres: Ignoring certain tags as genres when generating the catalog

+

Other options: Specifying thumb size, adding extra information to Descriptions

+

Customizing the appearance of the generated catalog

+
+

Selecting books to catalog

+

If you want all of your library cataloged, remove any search or filtering criteria by clearing the Search: field in the main window. With a single book selected, all books in your library will be candidates for inclusion in the generated catalog. Individual books may be excluded by various criteria; see the Excluded genres section below for more information.

+

If you want only some of your library cataloged, you have two options:

+
    +
  1. Create a multiple selection of the books you want cataloged. With more than one book selected in calibre's main window, only the selected books will be cataloged.
  2. +
  3. Use the Search: field or calibre's Tag Browser to filter the displayed books. With a single book selected, only the displayed books will be cataloged.
  4. +
+
+

Included sections

+

<img>

+

Sections enabled by a checkmark will be included in the generated catalog:

+ +
+

Prefixes

+

<img>

+

Prefix rules specify matching criteria and a prefix to use when the criteria is matched.

+

The checkbox in the first column enables the rule. Name is a rule name that you provide. Field is either Tags or a custom column in your library. Value is the content of Field to match. When a prefix rule is satisfied, the book will be marked with the selected symbol in the Prefix column.

+

Three prefix rules have been specified in the example above:

+
    +
  1. Read book specifies that a book with any date in a custom column named Last read will be prefixed with a checkmark symbol.
  2. +
  3. Wishlist item specifies that any book with a Wishlist tag will be prefixed with an X symbol.
  4. +
  5. Library books specifies that any book with a value of True (or Yes) in a custom column Available in Library will be prefixed with a double arrow symbol.
  6. +
+

The first matching rule supplies the prefix. Disabled or incomplete rules are ignored.

+
+

Excluded books

+

<img>

+

Exclusion rules specify matching criteria for books that will not be cataloged.

+

The checkbox in the first column enables the rule. Name is a rule name that you provide. Field is either Tags or a custom column in your library. Value is the content of Field to match. When an exclusion rule is satisfied, the book will be excluded from the generated catalog.

+

Two exclusion rules have been specified in the example above:

+
    +
  1. The Catalogs rule specifies that any book with a Catalog tag will be excluded from the generated catalog.
  2. +
  3. The Archived Books rule specifies that any book with a value of Archived in the custom column Status will be excluded from the generated catalog.
  4. +
+

All rules are evaluated for every book. Disabled or incomplete rules are ignored.

+
+

Excluded genres

+

<img>

+

When the catalog is generated, tags in your database are used as genres. For example, you may have the tags Fiction and Nonfiction applied to books in your library. These tags become genres in the generated catalog, with all tagged books showing up in their respective genre lists.

+

You may be using certain tags for other purposes, perhaps a + to indicate a read book, or a bracketed tag like [Amazon Freebie] to indicate a book's source. The Excluded genres regex allows you to specify tags that you don't want used as genres in the generated catalog. The default exclusion regex pattern \[.+\]\+ excludes any tags of the form [tag], as well as excluding +, the default tag for read books, from being used as genres in the generated catalog.

+

You can also use the exact tag name in a regex. For example, [Amazon Freebie] will exclude that tag from the generated catalog. If you want to list multiple exact tags for exclusion, put a pipe character between them: [Amazon Freebie]|[Project Gutenberg].

+

The Results field shows you which tags will be excluded when the catalog is built, based on the tags in your database and the regex you enter.

+
+

Other options

+

Thumb width specifies a width preference for cover thumbnails included in the Descriptions section. Thumbnails are cached to improve performance. If you want to experiment with different widths, try generating a catalog with just a few books until you've found your optimal width, then generate your full catalog. The first time a catalog is generated with a new thumbnail width, performance will be slower, but subsequent runs will take advantage of the cache.

+

Extra note specifies a custom column's contents to be inserted into the Description, opposite the cover. For example, you might want to display the date you last read a book using a Last Read custom column. For advanced use of the Description note feature, see this post in the calibre forum.

+

Merge with Comments specifies a custom column whose content will be non-destructively merged with the Comments metadata during catalog generation. For example, you might have a custom column Author Bio that you'd like to append to the Comments metadata. You can choose to insert the custom column contents before or after the Comments section, and optionally separate the appended content with a horizontal rule. Eligible custom column types include text, comments, and composite.

+
+

Customizing catalog appearance

+

If you wish to change the default appearance of the Description pages or Section lists, you can do so by modifying a local copy of the catalog's template and CSS files, overriding the default layout. This requires familiarity with HTML and CSS.
+

+ +

Customizing the Description page. Available fields in template.xhtml:
+

+ +

Example: Changing year of publication in Description header
+ Default: <td class="date">{pubyear}</td>
+ Removed: <td class="date"></td>
+ Augmented: <td class="date">Year of publication: {pubyear}</td>
+Modified: <td class="date">{pubmonth} {pubyear}</td>

+

Customizing the Section lists. Templates controlling the display of book titles in the various Section lists (Books by Author, Books by Title, etc) may be edited to taste.
+ Available fields in section_list_templates.py:
+ {title} - Title of the book
+ {series} - Series name
+ {series_index} - Number of the book in the series
+ {rating} - 0-5 stars
+ {rating_parens} - (0-5 stars)
+ {pubyear} - Year the book was published
+ {pubyear_parens} - (Year the book was published)
+ Example: Changing Books by Author to remove year of publication:
+Default:

+

Code:
+ by_authors_normal_title_template = '{title} {pubyear_parens}'
+ by_authors_series_title_template = '[{series_index}] {title} {pubyear_parens}'
+ Year of publication removed:

+

Code:
+ by_authors_normal_title_template = '{title}'
+ by_authors_series_title_template = '[{series_index}] {title}'
+ Rating added:

+

Code:
+ by_authors_normal_title_template = '{title} {rating}'
+ by_authors_series_title_template = '[{series_index}] {title} {rating}'

+

Tips for experimenting with customization:
+ Work with a small subset of your catalog, 5-10 books
+ If you are experimenting with Section list templates, disable Descriptions in E-book options - catalog generation will be much faster.
+ If you are experimenting with CSS, build an EPUB version of your catalog, explode it with the Tweak EPUB feature to find the class of the element you want to change.

+

 

+

 

+ + diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index 838edb4e69..8b05fb5b8f 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -13,7 +13,8 @@ from calibre.constants import isosx, iswindows from calibre.devices.errors import OpenFeedback, UserFeedback from calibre.devices.usbms.deviceconfig import DeviceConfig from calibre.devices.interface import DevicePlugin -from calibre.ebooks.metadata import authors_to_string, MetaInformation, title_sort +from calibre.ebooks.metadata import (author_to_author_sort, authors_to_string, + MetaInformation, title_sort) from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.config import config_dir, dynamic, prefs from calibre.utils.date import now, parse_date @@ -405,9 +406,9 @@ class ITUNES(DriverBase): @return: A BookList. Implementation notes: - iTunes does not sync purchased books, they are only on the device. They are visible, but - they are not backed up to iTunes. Since calibre can't manage them, don't show them in the - list of device books. + iTunes does not sync purchased books, they are only on the device. They are + visible, but they are not backed up to iTunes. Since calibre can't manage them, + don't show them in the list of device books. """ if not oncard: @@ -1637,9 +1638,19 @@ class ITUNES(DriverBase): logger().info('%s%s' % (' '*indent,'-' * len(msg))) for book in booklist: + tl = [i.title for i in booklist] + lt = max(tl, key=len) + al = [i.author for i in booklist] + la = max(al, key=len) + asl = [i.author_sort for i in booklist] + las = max(asl, key=len) if isosx: - logger().info("%s%-40.40s %-30.30s %-10.10s %s" % - (' '*indent,book.title, book.author, str(book.library_id)[-9:], book.uuid)) + fs = '{!s}{:<%d} {:<%d} {:<%d} {:<10} {!s}' % (' ' * indent, len(lt), + len(la), len(las)) + logger.info(fs.format(book.title, book.author, book.author_sort, + str(book.library_id)[-9:], book.uuid)) + #logger().info("%s%-40.40s %-30.30s %-10.10s %s" % + # (' '*indent,book.title, book.author, str(book.library_id)[-9:], book.uuid)) elif iswindows: logger().info("%s%-40.40s %-30.30s" % (' '*indent,book.title, book.author)) @@ -3478,6 +3489,7 @@ class Book(Metadata): ''' def __init__(self,title,author): Metadata.__init__(self, title, authors=author.split(' & ')) + self.author_sort = author_to_author_sort(author) @property def title_sorter(self): diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.py b/src/calibre/gui2/catalog/catalog_epub_mobi.py index 7c89d3e0dd..4dc42b73bd 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.py +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.py @@ -11,13 +11,14 @@ import re, sys from functools import partial from calibre.ebooks.conversion.config import load_defaults -from calibre.gui2 import gprefs, info_dialog, question_dialog +from calibre.gui2 import gprefs, info_dialog, open_url, question_dialog from calibre.utils.icu import sort_key from catalog_epub_mobi_ui import Ui_Form from PyQt4.Qt import (Qt, QAbstractItemView, QCheckBox, QComboBox, QDoubleSpinBox, QIcon, QLineEdit, QObject, QRadioButton, QSize, QSizePolicy, - QTableWidget, QTableWidgetItem, QTextEdit, QToolButton, QVBoxLayout, QWidget, + QTableWidget, QTableWidgetItem, QTextEdit, QToolButton, QUrl, + QVBoxLayout, QWidget, SIGNAL) class PluginWidget(QWidget,Ui_Form): @@ -440,6 +441,13 @@ class PluginWidget(QWidget,Ui_Form): self.merge_after.setEnabled(False) self.include_hr.setEnabled(False) + def show_help(self): + ''' + Display help file + ''' + url = 'file:///' + P('catalog/help_epub_mobi.html') + open_url(QUrl(url)) + class CheckableTableWidgetItem(QTableWidgetItem): ''' Borrowed from kiwidude diff --git a/src/calibre/gui2/catalog/catalog_epub_mobi.ui b/src/calibre/gui2/catalog/catalog_epub_mobi.ui index f3bffb4930..28a17725df 100644 --- a/src/calibre/gui2/catalog/catalog_epub_mobi.ui +++ b/src/calibre/gui2/catalog/catalog_epub_mobi.ui @@ -268,7 +268,7 @@ The default pattern \[.+\]|\+ excludes tags of the form [tag], e.g., [Test book] - List of tags that will be excluded as genres + Tags that will be excluded as genres QFrame::StyledPanel @@ -379,7 +379,7 @@ The default pattern \[.+\]|\+ excludes tags of the form [tag], e.g., [Test book] - &Extra note + E&xtra note header_note_source_field diff --git a/src/calibre/gui2/dialogs/catalog.py b/src/calibre/gui2/dialogs/catalog.py index a8f7ed160f..6ec5dd6d13 100644 --- a/src/calibre/gui2/dialogs/catalog.py +++ b/src/calibre/gui2/dialogs/catalog.py @@ -10,7 +10,7 @@ import os, sys, importlib from calibre.customize.ui import config from calibre.gui2.dialogs.catalog_ui import Ui_Dialog -from calibre.gui2 import dynamic, ResizableDialog +from calibre.gui2 import dynamic, ResizableDialog, info_dialog from calibre.customize.ui import catalog_plugins class Catalog(ResizableDialog, Ui_Dialog): @@ -22,7 +22,6 @@ class Catalog(ResizableDialog, Ui_Dialog): from PyQt4.uic import compileUi ResizableDialog.__init__(self, parent) - self.dbspec, self.ids = dbspec, ids # Display the number of books we've been passed @@ -115,6 +114,7 @@ class Catalog(ResizableDialog, Ui_Dialog): self.format.currentIndexChanged.connect(self.show_plugin_tab) self.buttonBox.button(self.buttonBox.Apply).clicked.connect(self.apply) + self.buttonBox.button(self.buttonBox.Help).clicked.connect(self.help) self.show_plugin_tab(None) geom = dynamic.get('catalog_window_geom', None) @@ -129,6 +129,10 @@ class Catalog(ResizableDialog, Ui_Dialog): if cf in pw.formats: self.tabs.addTab(pw, pw.TITLE) break + if hasattr(self.tabs.widget(1),'show_help'): + self.buttonBox.button(self.buttonBox.Help).setVisible(True) + else: + self.buttonBox.button(self.buttonBox.Help).setVisible(False) def format_changed(self, idx): cf = unicode(self.format.currentText()) @@ -165,6 +169,29 @@ class Catalog(ResizableDialog, Ui_Dialog): self.save_catalog_settings() return ResizableDialog.accept(self) + def help(self): + ''' + To add help functionality for a specific format: + In gui2.catalog.catalog_.py, add the following: + from calibre.gui2 import open_url + from PyQt4.Qt import QUrl + + In the PluginWidget() class, add this method: + def show_help(self): + url = 'file:///' + P('catalog/help_.html') + open_url(QUrl(url)) + + Create the help file at resources/catalog/help_.html + ''' + if self.tabs.count() > 1 and hasattr(self.tabs.widget(1),'show_help'): + try: + self.tabs.widget(1).show_help() + except: + info_dialog(self, _('No help available'), + _('No help available for this output format.'), + show_copy_button=False, + show=True) + def reject(self): dynamic.set('catalog_window_geom', bytearray(self.saveGeometry())) ResizableDialog.reject(self) diff --git a/src/calibre/gui2/dialogs/catalog.ui b/src/calibre/gui2/dialogs/catalog.ui index cf51ac8848..a4366b26c2 100644 --- a/src/calibre/gui2/dialogs/catalog.ui +++ b/src/calibre/gui2/dialogs/catalog.ui @@ -14,7 +14,7 @@ Generate catalog - + :/images/lt.png:/images/lt.png @@ -37,7 +37,7 @@ Qt::Horizontal - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok @@ -54,8 +54,8 @@ 0 0 - 666 - 599 + 650 + 575