-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements to value icons: #2622
Conversation
1) Make average rating and count usable in templates 2) Pass the database to safe_format so it can be used in non-GUI contexts.
LibraryBroker doesnt use Legacy() only Cache(), see the init_library() Indeed when running the server from the command line (non-GUI context) Does safe_format actually need the Legacy interface? user formatter |
The base (built-in) server functions are loaded. Library-specific functions aren't, (or might not be) but that is OK in this context. Dereferencing the weakref() from Cache() to the legacy database works. To test, I ran a GPM template that checks notes, something that uses the database. I can use this GPM template as an icon selector in the content server:
The has_note() function uses new_api. This python template that uses LibraryDatabase works in the content server as well:
The all_ids() function exists only in legacy (LibraryDatabase) so the weakref deference must be working.. This tells me that the db being given to metadata.py / Bottom line: it works. Having the db available in icon value templates dramatically increases the template's power. |
Stored templates work as well. To test I:
|
Yes, as I said it will work only in the following scenario. Running the server from within the GUI. This is because that library was created with calibre-server from a command prompt you will see that it wont work. The GUI uses GUILibraryBroker which overrides init_library to use |
You are right (of course), when running from the command line the LibraryDatabase object isn't available. However, the stored templates for a library are available. I tried this by using the GUI to change the default library to something with no stored templates, opened the content server from the command line, and selected a library with templates and icon value rules that use them. They ran. Built-in template functions also ran. I will change the formatter functions to use new_api, and document that the old api isn't available in icon templates. However, we have a different problem. Composite columns that use the database don't work in the content server. Reason: the database isn't available to templates run by db.fields.CompositeField because that class doesn't have the database. This is not caused by the changes I'm making so I'm not going to worry about it for the moment. I can fix it if the database were passed to CompositeField() |
…metadata.py 2) Change formatter functions to use the new_api where possible. Also fix a bug where the wrong exception was raised attempting to get a database object from the weak reference. These were tested using the command line content server.
Pushed changes:
These were tested using the command line content server. |
I dont think we need to worry too much about the composite columns using |
Would you be OK with Cache() passing an instance of itself to fields.create_field() when it creates the field? CompositeField would pass this instance when calling the formatter. This would permit using all formatter database functions that don't require information from view.py such as virtual libraries and marks. Can I get the current virtual library in srv.metadata.py? Or even better, from Cache()? It seems like the content server does all VL work in the client. |
Also, I'm now allowed to use embedded assignment (:=)? Your cleanup of formatter_functions does. |
On Tue, Jan 21, 2025 at 05:45:17AM -0800, Charles Haley wrote:
Also, I'm now allowed to use embedded assignment (:=)? Your cleanup of formatter_functions does.
Yes, that's python 3.8 which is the oldest version of python calibre
supports.
|
Last question: why does this import work? |
On Tue, Jan 21, 2025 at 05:43:38AM -0800, Charles Haley wrote:
Would you be OK with Cache() passing an instance of itself to fields.create_field() when it creates the field? CompositeField would pass this instance when calling the formatter. This would permit using all formatter database functions that don't require information from view.py such as virtual libraries and marks.
No, that would be a reference cycle. In any case IIRC CompositeField
doesnt create formatters, it just uses the pre-existing one on mi.
Can I get the current virtual library in srv.metadata.py? Or even better, from Cache()? It seems like the content server does all VL work in the client.
There is no current virtual library in the server. The server can serve
multiple requests simultaneously. Various server endpoints take a vl
parameter in the URL to restrict their results ot a virtual library. In
this case the endpoint is tag_browser() in srv/code.py you can get the
vl from there and pass it into the srv/metadata.py functions. In fact
looking at the code the vl is passed into categories_as_json already.
|
The problem isn't creating a formatter. It is calling safe_format() with a database, which is done in CompositeField. What about passing a function to create_field() to get the Cache instance? Using the function the cache instance would exist only during the evaluation of the composite. |
On Tue, Jan 21, 2025 at 05:52:34AM -0800, Charles Haley wrote:
Last question: why does this import work? `from calibre.gui2 import get_gui`
Shouldn't it be `from calibre.gui2.ui import get_gui` as it is everywhere else?
It doesnt, was a typo.
|
Alternatively I could pass a weakref to the field, thus avoiding the circular reference. This is better than an accessor function because the function could itself create the circular reference. |
Yes a weakref is fine |
The second was needed to make item value templates able to use the DB api or the database formatter functions.
Note: I added the db as a parameter to metadata.py / fillout_tree, passed in from render_categories that already had the db. It seems that this db is a reference to
Cache()
, notLegacy()
, even though the library broker seems to get the legacy version. I couldn't find where it became.new_api
so I used the weak reference in cache to get the legacy version. There might be a better way to do this via the library broker.