Skip to content
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

feature request: fetch-ebook-metadata #9

Closed
dalanicolai opened this issue Jul 30, 2020 · 6 comments
Closed

feature request: fetch-ebook-metadata #9

dalanicolai opened this issue Jul 30, 2020 · 6 comments

Comments

@dalanicolai
Copy link
Contributor

First of all thanks for this very beautiful package that almost saves me from opening Calibre-gui. However, usually after adding a book I fetch metadata (incl. cover) automatically with Calibre. Now calibre comes with a command-line utility for fetching the metadata. Would be great if we could use this from Calibre to set the metadata (and download the cover).
This command line utility returns only the first result from all possible sources (Google, Amazon.com etc.), while Calibre-gui let's you choose from multiple results (would be great to have that option here too).

Here is an example of how to use the command that also donwloads the cover in the current working directory:
fetch-ebook-metadata -p "Amazon.com" --authors "dominik" --title "org" -c cover.jpg

@dalanicolai
Copy link
Contributor Author

dalanicolai commented Jul 30, 2020

As I thought this was a fun little project, I have coded a partial solution (it is working, but I would still like to choose between metadata from different sources). First here is the code:

(defun calibredb-fetch-metadata (author title)
  (let* ((authors (read-string "Authors: " author))
         (title (read-string "Title: " title))
         (sources '("Google" "Amazon.com")))
    (mapcar
     (lambda (source)
       (let* ((md (split-string (shell-command-to-string
                  (format
                   "fetch-ebook-metadata -p '%s' --authors '%s' --title '%s'"
                   source
                   authors
                   title)) "Comments" nil " *"))
              (no-comments 
               (mapcar (lambda (x)
                         (let ((string x))
                           (string-match "\\([A-z]*\\)(*\\(s\\)*)* *: *\\(.*\\)" string)
                           (cons (format "%s%s" (match-string 1 string) (cond ((match-string 2 string))
                                                                              ("")))
                                 (match-string 3 string))))
                       (split-string (car md) "\n" t " *"))))
         (append no-comments (list (cons "Comments" (substring (nth 1 md) 2))))))
     sources)))

(defun calibredb-fetch-and-set-metadata ()
  (interactive)
  (let* ((candidate (car (calibredb-find-candidate-at-point)))
         (authors (calibredb-getattr candidate :author-sort))
         (title (calibredb-getattr candidate :book-title))
         (metadata (calibredb-fetch-metadata authors title))
         (id (calibredb-getattr candidate :id)))
    (mapcar (lambda (x)
              (calibredb-command :command "set_metadata"
                                 :option "--field"
                                 :input (format "%s:\"%s\"" (downcase (car x)) (cdr x))
                                 :id id
                                 :library (format "--library-path \"%s\"" calibredb-root-dir)))
            (nth 0 metadata)))
  (cond ((equal major-mode 'calibredb-show-mode)
         (calibredb-show-refresh))
        ((eq major-mode 'calibredb-search-mode)
         (calibredb-search-refresh-or-resume))))

So the calibredb-fetch-metadata fetches metadata from Google and Amazon.com (more options can easily be added of course).
The function calibredb-fetch-and-set-metadata can be invoked interactively from the calibredb-search buffer. For now the last expression before refreshing the buffer, (nth 0/1 metadata), selects wether the Google or the Amazon metadata is used.

I was wondering if you have some suggestion how some functionality for previewing the metadata from different sources and subsequent selection could be nicely implemented

chenyanming added a commit that referenced this issue Aug 2, 2020
Implement auto fetch metadata (issue #9)
@chenyanming
Copy link
Owner

@dalanicolai Appreciate that your contribution to fetch-ebook-metadata which I would like to implement in the next version as well! I did an early merge. And I am testing on it.

@dalanicolai
Copy link
Contributor Author

dalanicolai commented Aug 2, 2020

Thanks for testing! I developed on my Spacemacs configuration, where the new functionality is working perfectly fine (of course). However, now I test it on a plain (except that it has Ivy installed) Emacs installation and it returns a very strange error. Namely, while fetching metadata, at the first step where I should choose between the original and fetched cover, Emacs returns an error saying that the 'ivy-read' command receives an invalid keyword argument. However, the ivy-read command looks perfectly fine and it works perfectly fine on my Spacemacs configuration. I really don't know why it behaves like this. Do you have an idea?

Also of course I am happy to answer any question.

One more thing. Maybe I could mention my toc-mode package somewhere in the README as RELATED PACKAGE. Some people might be interested and it is otherwise not easy to find...

dalanicolai referenced this issue in dalanicolai/calibredb.el Aug 2, 2020
Fixed the key-argument error mentioned in
[https://github.com/chenyanming/calibredb.el/issues/9#issuecomment-667661650](this
comment). Also added clear image cache to refresh images and added some
whitespace between the different covers in the cover selection buffer. Finally
added a conditional to test if fetched metadata contains 'published' field.
@dalanicolai
Copy link
Contributor Author

As I would prefer to set the author and author_sort columns correctly, I asked Kovid (main Calibre developer), if it is possible to use the author_sort algorithm from the command line. So the algorithm can be use via:
calibre-debug -c "from calibre.ebooks.metadata import *; import sys; print(author_to_author_sort(' '.join(sys.argv[1:])))" Kovid Goyal. In case you might be interested...

@chenyanming
Copy link
Owner

I think this feature has been done. Shall we close the issue?

@dalanicolai
Copy link
Contributor Author

Agreed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants