diff --git a/src/calibre/db/cli/cmd_set_custom.py b/src/calibre/db/cli/cmd_set_custom.py index 2f6f22ae56..819e8d5534 100644 --- a/src/calibre/db/cli/cmd_set_custom.py +++ b/src/calibre/db/cli/cmd_set_custom.py @@ -4,19 +4,76 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from calibre import prints +from calibre.db import _get_series_values +from calibre.srv.changes import metadata + readonly = False version = 0 # change this if you change signature of implementation() -def implementation(db, notify_changes, *args): +def implementation(db, notify_changes, col, book_id, val, append): is_remote = notify_changes is not None - is_remote + field = db.field_metadata.custom_field_prefix + col + with db.write_lock: + if not db.has_id(book_id): + return False, _('No book with id {} exists').format(book_id) + try: + fm = db.field_metadata[field] + except KeyError: + return False, _('No column with name {} exists').format(col) + if fm['datatype'] == 'series': + val, s_index = _get_series_values(val) + if s_index is None: + s_index = db.get_next_series_num_for(val, field=field) + db.set_field(field, {book_id: val}), db.set_field(field + '_index', {book_id: s_index}) + msg = _('Data set to: {} [{}]').format(db.field_for(field, book_id), db.field_for(field + '_index', book_id)) + else: + if append and fm['is_multiple']: + val = list(db.field_for(field, book_id)) + [val] + db.set_field(field, {book_id: val}) + val = db.field_for(field, book_id) + if isinstance(val, (tuple, list)): + val = fm['is_multiple']['list_to_ui'].join(val) + msg = _('Data set to: {}').format(val) + if is_remote: + notify_changes(metadata((book_id,))) + return True, msg def option_parser(get_parser, args): - pass + parser = get_parser( + _( + '''\ +%prog set_custom [options] column id value + +Set the value of a custom column for the book identified by id. +You can get a list of ids using the search command. +You can get a list of custom column names using the custom_columns +command. + ''' + ) + ) + + parser.add_option( + '-a', + '--append', + default=False, + action='store_true', + help=_( + 'If the column stores multiple values, append the specified ' + 'values to the existing ones, instead of replacing them.' + ) + ) + return parser def main(opts, args, dbctx): - raise NotImplementedError('TODO: implement this') + if len(args) < 3: + raise SystemExit(_('Error: You must specify a field name, id and value')) + ok, msg = dbctx.run('set_custom', args[0], int(args[1]), args[2], opts.append) + if ok: + prints(msg) + else: + raise SystemExit(msg) return 0 diff --git a/src/calibre/db/cli/main.py b/src/calibre/db/cli/main.py index 40e48619d3..e4634207ce 100644 --- a/src/calibre/db/cli/main.py +++ b/src/calibre/db/cli/main.py @@ -21,10 +21,8 @@ from calibre.utils.serialize import MSGPACK_MIME COMMANDS = ( 'list', 'add', 'remove', 'add_format', 'remove_format', 'show_metadata', 'set_metadata', 'export', 'catalog', 'saved_searches', 'add_custom_column', - 'custom_columns', 'remove_custom_column', - # 'set_custom', 'restore_database', - # 'check_library', 'list_categories', 'backup_metadata', 'clone', 'embed_metadata', - # 'search' + 'custom_columns', 'remove_custom_column', 'set_custom', + # 'restore_database', 'check_library', 'list_categories', 'backup_metadata', 'clone', 'embed_metadata', 'search' )