chenyanming / calibredb.el

Emacs calibre client - An Ebook Management Solution in Emacs.
GNU General Public License v3.0
318 stars 16 forks source link

use calibre content server as backend #49

Open untoreh opened 2 years ago

untoreh commented 2 years ago

These are examples to fetch the books from the calibre content server, and setting metadata on them. The advantages are:

(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)))))
chenyanming commented 2 years ago

Hi, @untoreh Thanks for your idea. I think content server is considered a library, just like opds, and calibredb.el is working as frontend. image

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.

untoreh commented 2 years ago

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.

chenyanming commented 2 years ago

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.