From c8d35b735b88ad58dc4f1a759386124fe76f1379 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Wed, 23 Sep 2020 21:32:06 +0100 Subject: [PATCH] Change the separator to make it easier to read and to write: #@#:[tdnb]: --- manual/gui.rst | 8 ++++---- src/calibre/db/search.py | 4 ++-- src/calibre/db/tests/reading.py | 12 ++++++------ src/calibre/gui2/dialogs/search.py | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manual/gui.rst b/manual/gui.rst index c2f3d42f9a..c53dd51ae8 100644 --- a/manual/gui.rst +++ b/manual/gui.rst @@ -443,15 +443,15 @@ Identifiers (e.g., ISBN, doi, lccn etc) also use an extended syntax. First, note You can search using a template in the :ref:`templatelangcalibre` instead of a metadata field. To do so you enter a template, a search type, and the value to search for. The syntax is:: - ``template:``(the template)``#@``(search type)``#:``(the value) + ``template:``(the template)``#@#:``(search type)``:``(the value) The ``template`` is any valid calibre template language template. The ``search type`` must be one of ``t`` (text search), ``d`` (date search), ``n`` (numeric search), or ``b`` (set/not set (boolean)). The ``value`` is whatever you want. It can use the special operators described above for the various search types. You must quote the entire search string if there are spaces anywhere in it. Examples: - * ``template:"program: connected_device_name('main')#@t#:kindle"`` -- is true of the ``kindle`` device is connected - * ``template:"program: select(formats_sizes(), 'EPUB')#@n#:>1000000"`` -- finds epubs larger than 1 MB - * ``template:"program: select(formats_modtimes('iso'), 'EPUB')#@d#:>10daysago"`` -- finds epubs newer than 10 days ago. + * ``template:"program: connected_device_name('main')#@#:t:kindle"`` -- is true of the ``kindle`` device is connected + * ``template:"program: select(formats_sizes(), 'EPUB')#@#:n:>1000000"`` -- finds epubs larger than 1 MB + * ``template:"program: select(formats_modtimes('iso'), 'EPUB')#@#:d:>10daysago"`` -- finds epubs newer than 10 days ago. You can build template search queries easily using the :guilabel:`Advanced search dialog` accessed by clicking the button |sbi|. You can test templates on specific books using the calibre ``template tester``. Easiest is to add the tester to the book list context menu or to assign the tester a keyboard shortcut. diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index 6537c9270b..dca3e11815 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -630,7 +630,7 @@ class Parser(SearchQueryParser): # {{{ if location == 'template': try: - template, sep, query = regex.split('#@([tdnb]?)#:', query, flags=regex.IGNORECASE) + template, sep, query = regex.split('#@#:([tdnb]):', query, flags=regex.IGNORECASE) if sep: sep = sep.lower() else: @@ -639,7 +639,7 @@ class Parser(SearchQueryParser): # {{{ if DEBUG: import traceback traceback.print_exc() - raise ParseException(_('template: missing or invalid separator (#@[tdnb]#:)')) + raise ParseException(_('template: missing or invalid separator (#@#:[tdnb]:)')) matchkind, query = _matchkind(query, case_sensitive=case_sensitive) matches = set() error_string = '*@*TEMPLATE_ERROR*@*' diff --git a/src/calibre/db/tests/reading.py b/src/calibre/db/tests/reading.py index fe0afb129a..e807b5b719 100644 --- a/src/calibre/db/tests/reading.py +++ b/src/calibre/db/tests/reading.py @@ -362,19 +362,19 @@ class ReadingTest(BaseTest): # template searches # Test text search - self.assertEqual(cache.search('template:"{#formats}#@t#:fmt1"'), {1,2}) - self.assertEqual(cache.search('template:"{authors}#@t#:=Author One"'), {2}) + self.assertEqual(cache.search('template:"{#formats}#@#:t:fmt1"'), {1,2}) + self.assertEqual(cache.search('template:"{authors}#@#:t:=Author One"'), {2}) cache.set_field('pubdate', {1:p('2001-02-06'), 2:p('2001-10-06'), 3:p('2001-06-06')}) cache.set_field('timestamp', {1:p('2002-02-06'), 2:p('2000-10-06'), 3:p('2001-06-06')}) # Test numeric compare search self.assertEqual(cache.search("template:\"program: " "floor(days_between(field(\'pubdate\'), " - "field(\'timestamp\')))#@n#:>0\""), {2,3}) + "field(\'timestamp\')))#@#:n:>0\""), {2,3}) # Test date search - self.assertEqual(cache.search('template:{pubdate}#@d#:<2001-09-01"'), {1,3}) + self.assertEqual(cache.search('template:{pubdate}#@#:d:<2001-09-01"'), {1,3}) # Test boolean search - self.assertEqual(cache.search('template:{series}#@b#:true'), {1,2}) - self.assertEqual(cache.search('template:{series}#@b#:false'), {3}) + self.assertEqual(cache.search('template:{series}#@#:b:true'), {1,2}) + self.assertEqual(cache.search('template:{series}#@#:b:false'), {3}) # Note that the old db searched uuid for un-prefixed searches, the new # db does not, for performance diff --git a/src/calibre/gui2/dialogs/search.py b/src/calibre/gui2/dialogs/search.py index 49e065c6b2..2de97b7a48 100644 --- a/src/calibre/gui2/dialogs/search.py +++ b/src/calibre/gui2/dialogs/search.py @@ -376,7 +376,7 @@ class SearchDialog(QDialog): if template and value: cb = self.template_test_type_box op = unicode_type(cb.itemData(cb.currentIndex())) - l = '{0}#@{1}#:{2}'.format(template, op, value) + l = '{0}#@#:{1}:{2}'.format(template, op, value) return 'template:"' + l + '"' return ''