Add support for searching via the calibre:// URL scheme

This commit is contained in:
Kovid Goyal 2020-11-12 11:26:37 +05:30
parent c26a981001
commit fe9ed4c8ef
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 44 additions and 1 deletions

View File

@ -27,7 +27,7 @@ The URL syntax is::
Library names are the folder name of the library with spaces replaced by
underscores. The special value ``_`` means the current library. You can also
use hex encoding for the library names, useful if the library names have
use :ref:`hex encoding <hex_encoding>` for the library names, useful if the library names have
special characters that would otherwise require URL encoding. Hex encoded
library names look like::
@ -62,3 +62,28 @@ Here, ``book_format`` is the format of the book, for example, ``EPUB`` or
easiest way to get these links is to open a book in the viewer, then in the
viewer controls select :guilabel:`Go to->Location` and there such a link
will be given that you can copy/paste elsewhere.
Searching for books
------------------------------
The URL syntax is::
calibre://search/Library_Name?q=query
calibre://search/Library_Name?eq=hex_encoded_query
Here query is any valid :ref:`search expression <search_interface>`. If the
search expression is complicated, :ref:`encode it as a hex string <hex_encoding>`
and use ``eq`` instead. Leaving out the query will cause the current search to
be cleared.
.. _hex_encoding:
Hex encoding of URL parameters
----------------------------------
Hex encoding of URL parameters is done by first encoding the parameter as UTF-8
bytes, and then replacing each byte by two hexadecimal characters representing
the byte. For example, the string ``abc`` is the bytes ``0x61 0x62 and 0x63`` in
UTF-8, so the encoded version is the string: ``616263``.

View File

@ -707,6 +707,24 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
else:
doit()
elif action == 'search':
parts = tuple(filter(None, path.split('/')))
if len(parts) != 1:
return
library_id = decode_library_id(parts[0])
library_path = self.library_broker.path_for_library_id(library_id)
if library_path is None:
return
sq = query.get('eq')
if sq:
sq = bytes.fromhex(sq[0]).decode('utf-8')
else:
sq = query.get('q')
if sq:
sq = sq[0]
sq = sq or ''
self.search.set_search_string(sq)
def message_from_another_instance(self, msg):
if isinstance(msg, bytes):
msg = msg.decode('utf-8', 'replace')