calibredb.el
calibredb.el copied to clipboard
use calibre content server as backend
These are examples to fetch the books from the calibre content server, and setting metadata on them. The advantages are:
- the server should load the database in memory only once
- setting metadata should also be fast, because we are not spawning a (python) process on each call
(defun calibredb-server-url (&optional path)
(if calibredb-server-host
(concat calibredb-server-host ":" calibredb-server-port (or path ""))
;; start a calibre-server managed by emacs and set url..
;; NOTE: calibre-server has to be started with `--enable-local-write'
;; ...
))
;; fetch library data
(request
(calibredb-server-url "/interface-data/books-init")
:params '(("library_id" . calibredb-library-id)
("sort" . (concat (symbol-name calibredb-sort-by) "."
(symbol-name calibredb-order))))
:parser 'json-read
:complete (lambda (&rest args)
(setq-local calibredb-data (plist-get args :data))))
;; parse the books candidates
(let ((candidates '()))
(dolist (book (alist-get 'metadata calibredb-data))
(push (let* ((book-id (car book))
(book-data (cdr book)))
`((:id ,book-id)
(:author-sort ,(alist-get 'author_sort book-data))
(:book-dir nil)
(:book-name ,(alist-get 'sort book-data))
(:book-format ,(downcase (seq-elt (alist-get 'formats book-data) 0)))
(:book-pubdate ,(alist-get 'pubdate book-data))
(:book-title ,(alist-get 'title book-data))
(:file-path nil)
(:tag ,(string-join (alist-get 'tags book-data) ","))
(:size ,(alist-get 'size book-data))
(:comment ,(alist-get 'comments book-data))
(:ids ,(alist-get 'identifiers book-data))
(:series ,(alist-get 'series_index book-data))
(:lang_code ,(seq-elt (alist-get 'languages book-data) 0))))
candidates))
candidates)
;; send request to update metadata
(defun calibredb-set-metadata--tags-server (id tags)
(request
(calibredb-server-url (concat "/cdb/set-fields/" id "/books"))
:type "POST"
:headers '(("Content-Type" . "application/json"))
:data (json-encode `(("changes" . (("tags" . ,tags)))))
:complete (lambda (&rest args)
(prin1 (plist-get args :data)))))
Hi, @untoreh Thanks for your idea. I think content server is considered a library, just like opds, and calibredb.el is working as frontend.
Would you like to add a pull request? You can make a function just like calibredb-opds-request-page
, and update calibredb-library-list
.
In this case, if we choose the content server via calibredb-library-list
, we will request the content server and get the results which will be shown in calibredb dashboard.
The calibre content server has the OPDS interface, but to use it as a replacement for the metadata
database OPDS is not enough to get the full details, so the content server API must be queried.
To use the content server as a library at least the function to read (download) the books is required.
Then after support for adding books (upload) and setting metadata, calibredb
is not a hard dependency anymore and calibredb.el can work just with just remote servers.
Yes. What I mean is adding a function to query the content server, I guess it is not difficult, just like the opds implementation. But adding books/updating meta/deleting books remotely are new features that may need some works.