From 68e32e6ee51456bea907413e98409c59b5b70f50 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Fri, 24 Dec 2010 13:11:02 +0000 Subject: [PATCH] Enhancement #8033: Sony collection name format changes --- resources/default_tweaks.py | 61 ++++++++++++++++++++---------- src/calibre/devices/usbms/books.py | 34 +++++++++++++---- 2 files changed, 67 insertions(+), 28 deletions(-) diff --git a/resources/default_tweaks.py b/resources/default_tweaks.py index a420cd7d44..d01999e766 100644 --- a/resources/default_tweaks.py +++ b/resources/default_tweaks.py @@ -135,32 +135,53 @@ auto_connect_to_folder = '' # metadata management is set to automatic. Collections on Sonys are named # depending upon whether the field is standard or custom. A collection derived # from a standard field is named for the value in that field. For example, if -# the standard 'series' column contains the name 'Darkover', then the series -# will be named 'Darkover'. A collection derived from a custom field will have -# the name of the field added to the value. For example, if a custom series +# the standard 'series' column contains the value 'Darkover', then the +# collection name is 'Darkover'. A collection derived from a custom field will +# have the name of the field added to the value. For example, if a custom series # column named 'My Series' contains the name 'Darkover', then the collection -# will be named 'Darkover (My Series)'. If two books have fields that generate -# the same collection name, then both books will be in that collection. This -# tweak lets you specify for a standard or custom field the value to be put -# inside the parentheses. You can use it to add a parenthetical description to a +# will by default be named 'Darkover (My Series)'. For purposes of this +# documentation, 'Darkover' is called the value and 'My Series' is called the +# category. If two books have fields that generate the same collection name, +# then both books will be in that collection. +# This set of tweaks tweak lets you specify for a standard or custom field how +# the collections are to be named. You can use it to add a description to a # standard field, for example 'Foo (Tag)' instead of the 'Foo'. You can also use # it to force multiple fields to end up in the same collection. For example, you # could force the values in 'series', '#my_series_1', and '#my_series_2' to # appear in collections named 'some_value (Series)', thereby merging all of the -# fields into one set of collections. The syntax of this tweak is -# {'field_lookup_name':'name_to_use', 'lookup_name':'name', ...} -# Example 1: I want three series columns to be merged into one set of -# collections. If the column lookup names are 'series', '#series_1' and -# '#series_2', and if I want nothing in the parenthesis, then the value to use -# in the tweak value would be: -# sony_collection_renaming_rules={'series':'', '#series_1':'', '#series_2':''} -# Example 2: I want the word '(Series)' to appear on collections made from -# series, and the word '(Tag)' to appear on collections made from tags. Use: -# sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'} -# Example 3: I want 'series' and '#myseries' to be merged, and for the -# collection name to have '(Series)' appended. The renaming rule is: -# sony_collection_renaming_rules={'series':'Series', '#myseries':'Series'} +# fields into one set of collections. +# There are two related tweaks. The first determines the category name to use +# for a metadata field. The second is a template, used to determines how the +# value and category are combined to create the collection name. +# The syntax of the first tweak, sony_collection_renaming_rules, is: +# {'field_lookup_name':'category_name_to_use', 'lookup_name':'name', ...} +# The second tweak, sony_collection_name_template, is a template. It uses the +# same template language as plugboards and save templates. This tweak controls +# how the value and category are combined together to make the collection name. +# The only two fields available are {category} and {value}. The {value} field is +# never empty. The {category} field can be empty. The default is to put the +# value first, then the category enclosed in parentheses, it is isn't empty: +# '{value} {category:|(|)}' +# Examples: The first three examples assume that the second tweak +# has not been changed. +# 1: I want three series columns to be merged into one set of collections. The +# column lookup names are 'series', '#series_1' and '#series_2'. I want nothing +# in the parenthesis. The value to use in the tweak value would be: +# sony_collection_renaming_rules={'series':'', '#series_1':'', '#series_2':''} +# 2: I want the word '(Series)' to appear on collections made from series, and +# the word '(Tag)' to appear on collections made from tags. Use: +# sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'} +# 3: I want 'series' and '#myseries' to be merged, and for the collection name +# to have '(Series)' appended. The renaming rule is: +# sony_collection_renaming_rules={'series':'Series', '#myseries':'Series'} +# 4: Same as example 2, but instead of having the category name in parentheses +# and appended to the value, I want it prepended and separated by a colon, such +# as in Series: Darkover. I must change the template used to format the category name +# The resulting two tweaks are: +# sony_collection_renaming_rules={'series':'Series', 'tags':'Tag'} +# sony_collection_name_template='{category:||: }{value}' sony_collection_renaming_rules={} +sony_collection_name_template='{value}{category:| (|)}' # Specify how sony collections are sorted. This tweak is only applicable if diff --git a/src/calibre/devices/usbms/books.py b/src/calibre/devices/usbms/books.py index ba005c4e6d..73afd770c1 100644 --- a/src/calibre/devices/usbms/books.py +++ b/src/calibre/devices/usbms/books.py @@ -14,6 +14,22 @@ from calibre.constants import preferred_encoding from calibre import isbytestring, force_unicode from calibre.utils.config import prefs, tweaks from calibre.utils.icu import strcmp +from calibre.utils.formatter import TemplateFormatter + +class SafeFormat(TemplateFormatter): + ''' + Provides a format function that substitutes '' for any missing value + ''' + + def get_value(self, key, args, kwargs): + try: + if key in kwargs: + return kwargs[key] + return key + except: + return key + +safe_formatter = SafeFormat() class Book(Metadata): def __init__(self, prefix, lpath, size=None, other=None): @@ -107,23 +123,25 @@ class CollectionsBookList(BookList): return sortattr return None - def compute_category_name(self, attr, category, field_meta): + def compute_category_name(self, field_key, field_value, field_meta): renames = tweaks['sony_collection_renaming_rules'] - attr_name = renames.get(attr, None) - if attr_name is None: + field_name = renames.get(field_key, None) + if field_name is None: if field_meta['is_custom']: - attr_name = '(%s)'%field_meta['name'] + field_name = field_meta['name'] else: - attr_name = '' - elif attr_name != '': - attr_name = '(%s)'%attr_name - cat_name = '%s %s'%(category, attr_name) + field_name = '' + cat_name = safe_formatter.safe_format( + fmt=tweaks['sony_collection_name_template'], + kwargs={'category':field_name, 'value':field_value}, + error_value='', book=None) return cat_name.strip() def get_collections(self, collection_attributes): from calibre.devices.usbms.driver import debug_print debug_print('Starting get_collections:', prefs['manage_device_metadata']) debug_print('Renaming rules:', tweaks['sony_collection_renaming_rules']) + debug_print('Formatting template:', tweaks['sony_collection_name_template']) debug_print('Sorting rules:', tweaks['sony_collection_sorting_rules']) # Complexity: we can use renaming rules only when using automatic