From 8c70bf25e20cc4ff061a53644a213ec9f55b97d0 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 17 Feb 2025 18:16:27 +1100 Subject: [emacs] allow choosing library in belf --- emacs/.emacs.d/lisp/my/belf.el | 102 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 10 deletions(-) (limited to 'emacs/.emacs.d/lisp/my') diff --git a/emacs/.emacs.d/lisp/my/belf.el b/emacs/.emacs.d/lisp/my/belf.el index e0d89b0..97bf0b2 100644 --- a/emacs/.emacs.d/lisp/my/belf.el +++ b/emacs/.emacs.d/lisp/my/belf.el @@ -41,6 +41,8 @@ "o" #'belf-open-book-other-window "p" #'belf-previous-line "e" #'belf-set-field + "," #'belf-rename-desort-at-point + "E" #'belf-epub-rename-at-point ;; "s" #'tabulated-list-col-sort ) @@ -63,6 +65,11 @@ (belf-list-refresh-contents)) (pop-to-buffer-same-window buf))) +(defun belf-library (dir) + (interactive (list (read-directory-name "Book directory: " belf-dir nil t))) + (setq belf-dir dir) + (belf)) + (defun belf-list-refresh-contents (&rest _) (setq-local tabulated-list-entries (belf-parse-all-file-names)) (tabulated-list-print)) @@ -79,7 +86,7 @@ (list f (vector .authors .title .year))))) (directory-files belf-dir t "\\.\\(epub\\|pdf\\|cbr\\|djvu\\)$")))) -(defun belf-fix-file-name (file-name) +(defun belf-file-name-desort (file-name new-dir) "Rename a file. Change authors-sort to authors. Change title-sort to title. @@ -114,18 +121,91 @@ foo bar & quux, baf" ((string-suffix-p ", A" title) (concat "A " (string-remove-suffix ", A" title))) (t title)))) - (format "%s.%s" (belf-format-base-name parsed) (alist-get 'ext parsed)))) + (format "%s.%s" + (belf-format-base-name parsed new-dir) + (alist-get 'ext parsed)))) -(defun belf-fix-rename-file (file-name) - (when-let ((new-name (belf-fix-file-name file-name))) +(defun belf-rename-desort (file-name new-dir) + (when-let ((new-name (belf-file-name-desort file-name new-dir))) (unless (equal new-name file-name) (rename-file file-name new-name)))) -(defun belf-fix-rename-files () +(defun belf-rename-desort-at-point () + (interactive) + (let ((file-name (tabulated-list-get-id))) + (belf-rename-desort file-name (file-name-directory file-name)) + (revert-buffer))) + +(defun belf-rename-desort-files (dir new-dir) (interactive) (dolist (file-name - (directory-files belf-dir t directory-files-no-dot-files-regexp)) - (belf-fix-rename-file file-name))) + (directory-files dir t directory-files-no-dot-files-regexp)) + (belf-rename-desort file-name new-dir))) + +(defun belf-epub-rename-files (dir new-dir) + (dolist (epub (directory-files dir t "\\.epub$")) + (belf-epub-rename epub new-dir))) + +(defun belf-epub-rename (file-name new-dir) + (when-let ((content-file-name (belf-epub-content-file-name file-name))) + (with-temp-buffer + (call-process "unzip" nil t nil "-p" file-name content-file-name) + (let* ((dom (libxml-parse-xml-region (point-min) (point-max))) + (metadata (dom-by-tag dom 'metadata)) + (title (dom-text (dom-by-tag metadata 'title))) + (authors (dom-texts (dom-by-tag metadata 'creator) ", ")) + (identifier + (replace-regexp-in-string + "[^0-9,]" "" + (dom-texts + (seq-filter + (lambda (node) + (or (equal "ISBN" (dom-attr node 'scheme)) + (string-match-p "^[0-9]+$" (dom-text node)))) + (dom-by-tag metadata 'identifier)) + ","))) + (date (replace-regexp-in-string + "[^0-9]" "" + (dom-text (dom-by-tag metadata 'date)))) + (year (substring date 0 (min 4 (length date)))) + (dir (file-name-directory file-name)) + (new-base-name (belf-format-base-name + `((title . ,title) + (authors . ,authors) + (year . ,year) + (identifier . ,identifier)) + new-dir)) + new-name) + ;; (pp metadata) + (dolist (file (directory-files dir t + (format "^%s\\.[a-zA-Z0-9]+$" + (regexp-quote + (file-name-base file-name))))) + (setq new-name (format "%s.%s" new-base-name (file-name-extension file))) + (unless (equal file-name new-name) + (message "%s -> %s" file new-name) + (ignore-error 'file-already-exists (rename-file file new-name)) + ) + ) + )) + )) + +(defun belf-move-invalid-file-names (dir new-dir) + "Move files in DIR whose file names do not validate to NEW-DIR." + (let (new-name) + (dolist (file-name (directory-files dir t directory-files-no-dot-files-regexp)) + (unless (string-match-p "^.*? +- +.* +([0-9]*) +\\[.*\\]\\.[a-zA-Z0-9]+$" file-name) + (message "%s -> %s" file-name + (setq new-name (file-name-concat + new-dir (file-name-nondirectory file-name)))) + (rename-file file-name new-name) + )))) + +(defun belf-epub-rename-at-point () + (interactive) + (let ((file-name (tabulated-list-get-id))) + (belf-epub-rename file-name (file-name-directory file-name)) + (revert-buffer))) (defun belf-parse-file-name (file-name) (let ((fn (file-name-nondirectory file-name))) @@ -136,11 +216,13 @@ foo bar & quux, baf" (identifier . ,(match-string 4 fn)) (ext . ,(match-string 5 fn)))))) -(defun belf-format-base-name (info) +(defun belf-format-base-name (info &optional dir) (let-alist info (file-name-concat - (expand-file-name belf-dir) - (format "%s - %s (%s) [%s]" .authors .title .year .identifier)))) + (expand-file-name (or dir belf-dir)) + (replace-regexp-in-string + "[/:?*\"]" "_" + (format "%s - %s (%s) [%s]" .authors .title .year .identifier))))) (defun belf-book-infobox (file-name) (interactive) -- cgit v1.2.3