From 093ffa5fbf7143f4668bb0a3dc9659a5cc836e12 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Sat, 17 Jun 2023 17:20:29 +1000 Subject: Moving things one level deeper To ease gnu stow usage. Now we can do stow -t ~ emacs --- emacs/.emacs.d/lisp/my/my-openlibrary.el | 147 +++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 emacs/.emacs.d/lisp/my/my-openlibrary.el (limited to 'emacs/.emacs.d/lisp/my/my-openlibrary.el') diff --git a/emacs/.emacs.d/lisp/my/my-openlibrary.el b/emacs/.emacs.d/lisp/my/my-openlibrary.el new file mode 100644 index 0000000..559ecba --- /dev/null +++ b/emacs/.emacs.d/lisp/my/my-openlibrary.el @@ -0,0 +1,147 @@ +;;; my-openlibrary.el -- openlibrary client -*- lexical-binding: t -*- + +;; Copyright (C) 2023 Free Software Foundation. + +;; Author: Yuchen Pei +;; Package-Requires: ((emacs "28.2")) + +;; This file is part of dotfiles. + +;; dotfiles is free software: you can redistribute it and/or modify it under +;; the terms of the GNU Affero General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; dotfiles is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General +;; Public License for more details. + +;; You should have received a copy of the GNU Affero General Public +;; License along with dotfiles. If not, see . + +;;; Commentary: + +;; openlibrary client. + +;;; Code: + + +;;; an openlibrary client +(require 'generic-search) +(require 'my-net) + +(defvar my-openlibrary-host "https://openlibrary.org") +(defun my-openlibrary-api-book-by-olid (olid) + (my-url-fetch-json + (format "%s/api/books?bibkeys=OLID:%s&format=json&jscmd=data" + my-openlibrary-host olid))) + +(defun my-openlibrary-html-book-by-url (url) + (list + (cons 'description + (string-trim + (dom-texts + (dom-by-class + (my-url-fetch-dom url) + "book-description-content restricted-view")))))) + +(defun my-grok-openlibrary (url) + "grok openlibrary. +title, subtitle, description, subjects, authors (by_statement?), classification, publisher, publish_places, publish_date, subjects, cover" + (when (string-match + (concat my-openlibrary-host "/books/\\([^/]+\\)") url) + (my-grok-openlibrary-make-info + (append + (my-openlibrary-api-book-by-olid (match-string 1 url)) + (my-openlibrary-html-book-by-url url))))) + +(defun my-grok-openlibrary-make-info (info) + (list + (cons "Title" (alist-get 'title info)) + (cons "Subtitle" (alist-get 'subtitle info)) + (cons "Authors" (string-join + (mapcar (lambda (author) (alist-get 'name author)) + (alist-get 'authors info)) + ", ")) + (cons "Pages" + (when (alist-get 'number_of_pages info) + (number-to-string (alist-get 'number_of_pages info)))) + (cons "OpenLibrary-link" (alist-get 'url info)) + (cons "OpenLibrary-ID" (string-join (alist-get 'openlibrary info) ",")) + (cons "ISBN" (string-join + (vconcat + (alist-get 'isbn_13 + (alist-get 'identifiers info)) + (alist-get 'isbn_10 + (alist-get 'identifiers info))) + ", ")) + (cons "Dewey-Decimal" (alist-get 'dewey_decimal_class info)) + (cons "Subject" (string-join + (seq-take + (remove-duplicates + (mapcar (lambda (subject) (alist-get 'name subject)) + (alist-get 'subjects info)) + :test 'string=) + 20) + ", ")) + (cons "Cover" (alist-get 'large (alist-get 'cover info))) + (cons "Published" (alist-get 'publish_date info)) + (cons "Description" (alist-get 'description info)))) + +(defun my-openlibrary-api-book-by-isbn (isbn) + (my-url-fetch-json + (format + "%s/api/books?bibkeys=ISBN:%s&format=json&jscmd=data" + my-openlibrary-host isbn))) + +(defun my-grok-openlibrary-isbn (isbn) + (unless isbn (error "isbn not supplied")) + (let* ((info-json (alist-get (intern (format "ISBN:%s" isbn)) + (my-openlibrary-api-book-by-isbn isbn))) + (url (alist-get 'url info-json)) + (info-html (my-openlibrary-html-book-by-url url))) + (my-grok-openlibrary-make-info + (append info-json info-html)))) + +(defun my-openlibrary-api-search (query) + (my-url-fetch-json + (format "%s/search.json?q=%s" my-openlibrary-host query))) + +(defun my-openlibrary-format-result (info) + (format "%s - %s [%s] (%s)" + (string-join (alist-get 'author_name info) ", ") + (alist-get 'title info) + (string-join (alist-get 'isbn info) ",") + (alist-get 'publish_date info))) + +(defun my-openlibrary-action (info) + (interactive) + (my-org-create-node + (my-grok-openlibrary-isbn (elt (alist-get 'isbn info) 0)) + t)) + +(defun my-openlibrary-show-more-info () + (interactive) + (pp (my-grok-openlibrary-isbn + (elt + (alist-get 'isbn (get-text-property (point) 'button-data)) + 0)))) + +(defvar my-openlibrary-button-keymap + (let ((kmap (make-sparse-keymap))) + (set-keymap-parent kmap button-map) + (define-key kmap "p" 'my-openlibrary-show-more-info) + kmap)) + +(defun my-openlibrary-search (query) + (interactive "sQuery: ") + (generic-search-open + (alist-get 'docs (my-openlibrary-api-search query)) + (format "openlibrary-query:%s" query) + `((formatter . my-openlibrary-format-result) + (default-action . my-openlibrary-action) + (keymap . ,my-openlibrary-button-keymap)))) + +(provide 'my-openlibrary) +;;; my-openlibrary.el ends here -- cgit v1.2.3