diff options
-rw-r--r-- | emacs/.emacs.d/init/ycp-gnus.el | 4 | ||||
-rw-r--r-- | emacs/.emacs.d/init/ycp-web.el | 19 | ||||
m--------- | emacs/.emacs.d/lisp/hmm.el | 0 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-libgen.el | 116 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-web.el | 50 | ||||
-rw-r--r-- | emacs/.emacs.d/lisp/my/reddio.el | 53 | ||||
-rw-r--r-- | misc/.bashrc | 2 | ||||
-rw-r--r-- | misc/.config/mimeapps.list | 4 | ||||
-rw-r--r-- | misc/.local/share/applications/emacsclient-web.desktop | 20 |
9 files changed, 263 insertions, 5 deletions
diff --git a/emacs/.emacs.d/init/ycp-gnus.el b/emacs/.emacs.d/init/ycp-gnus.el index f4886fd..9e89ee9 100644 --- a/emacs/.emacs.d/init/ycp-gnus.el +++ b/emacs/.emacs.d/init/ycp-gnus.el @@ -186,6 +186,10 @@ (setq gnus-summary-next-group-on-exit nil) ) +(my-package gnus-art + (my-keybind gnus-article-mode-map + "w" #'my-copy-url-at-point)) + (my-package nnrss (:delay 60) (setq nnrss-use-local t)) diff --git a/emacs/.emacs.d/init/ycp-web.el b/emacs/.emacs.d/init/ycp-web.el index b1e546c..b156e9a 100644 --- a/emacs/.emacs.d/init/ycp-web.el +++ b/emacs/.emacs.d/init/ycp-web.el @@ -217,6 +217,9 @@ 'turn-off-flyspell) ) +(my-package dnd + (setq dnd-open-remote-file-function 'browse-url)) + (my-package eww (:delay 60) (advice-add 'eww-browse-url :filter-args #'my-rewrite-url-advice) @@ -245,7 +248,18 @@ "T" #'my-eww-top-path "b" #'my-eww-switch-by-title) (my-keybind global-map "\C-c\C-o" #'my-browse-url-at-point) - (my-override browse-url) + (setq browse-url-handlers + `(("^https?://www.spectator.com.au\\>" . + ,(lambda (url &rest args) (my-open-spectator-au url))) + (my-mastodon-url-p + . ,(lambda (url &rest args) (mastorg-open url))) + (my-hacker-news-url-p + . ,(lambda (url &rest args) (hnreader-comment url))) + (reddio-reddit-url-p + . ,(lambda (url &rest args) (reddio-open-url url))) + (my-stack-overflow-url-p + . ,(lambda (url &rest args) (sx-open-link url))) + (stringp . browse-url-firefox))) ) (my-package my-semantic-scholar @@ -308,7 +322,8 @@ (my-setq-from-local my-libgen-hosts my-libgen-alt-hosts my-libgen-library-hosts my-libgen-onion-host ) - (setq my-libgen-download-dir my-document-incoming-dir) + (setq my-libgen-download-dir my-document-incoming-dir + my-libfic-download-dir my-document-incoming-dir) (my-libgen-set-random-hosts)) (my-package my-scihub diff --git a/emacs/.emacs.d/lisp/hmm.el b/emacs/.emacs.d/lisp/hmm.el -Subproject 2157ead39273691013c38529b14953ea839c2a5 +Subproject a0660da71f9aef8909973e9fd44b5eb34db0386 diff --git a/emacs/.emacs.d/lisp/my/my-libgen.el b/emacs/.emacs.d/lisp/my/my-libgen.el index 6b65eb1..67e0071 100644 --- a/emacs/.emacs.d/lisp/my/my-libgen.el +++ b/emacs/.emacs.d/lisp/my/my-libgen.el @@ -251,5 +251,121 @@ (filesize-human . ,filesize-human) (extension . ,extension)))) +(defvar my-libfic-download-dir "~/Downloads") +(defun my-libfic-search (query) + (interactive "sQuery: ") + (generic-search-open + (mapcar 'my-libfic-search-parse-tr + (cdr + (dom-by-tag + (my-url-fetch-dom + (format "%s/fiction/?q=%s" + my-libgen-host query)) + 'tr))) + (format "libfic-query:%s" query) + `((formatter . my-libfic-search-format-result) + (default-action . my-grok-libfic-action) + (keymap . ,my-libfic-button-keymap)))) + +(defun my-libfic-search-parse-tr (tr) + (let* ((tds (dom-by-tag tr 'td)) + (author (string-trim (dom-texts (pop tds) ""))) + (series (dom-text (pop tds))) + (title-id (pop tds)) + (title-md5 (car (dom-by-tag title-id 'a))) + (title (dom-text title-md5)) + (md5 (elt (split-string (or (dom-attr title-md5 'href) "") "/") 2)) + (identifier (dom-text (dom-by-class title-id "catalog_identifier"))) + (language (dom-text (pop tds))) + (extension-filesize-human (split-string (dom-text (pop tds)) " / ")) + (extension (downcase (car extension-filesize-human))) + (filesize-human (cadr extension-filesize-human)) + ) + `((author . ,author) + (series . ,series) + (md5 . ,md5) + (title . ,title) + (identifier . ,identifier) + (language . ,language) + (filesize-human . ,filesize-human) + (extension . ,extension)))) + +(defun my-libfic-search-format-result (info) + (format + "%s [%s] %s" + (my-libfic-format-filename info) + (alist-get 'language info) + (alist-get 'filesize-human info))) + +(defun my-libfic-format-filename (info) + (replace-regexp-in-string "[:;]" "_" + (format + "%s - %s (%s) [%s].%s" + (alist-get 'author info) + (alist-get 'title info) + (alist-get 'series info) + (alist-get 'identifier info) + (alist-get 'extension info)))) + +(defun my-grok-libfic-action (info) + (interactive) + (my-org-create-node + (my-grok-libfic-make-info + (my-libfic-update-info info)) + t)) + +(defun my-libfic-update-info (info) + (when-let ((tr-id + (seq-find + (lambda (tr) + (equal "ID:" (dom-text (car (dom-by-tag tr 'td))))) + (dom-by-tag + (my-url-fetch-dom + (format "%s/fiction/%s" my-libgen-host (alist-get 'md5 info))) + 'tr)))) + `((id . ,(dom-text (cadr (dom-by-tag tr-id 'td)))) . ,info))) + +;;; todo: description; publisher; cover +(defun my-grok-libfic-make-info (info) + (list + (cons "libfic-id" (alist-get 'id info)) + (cons "Title" (alist-get 'title info)) + (cons "Series" (alist-get 'series info)) + (cons "Authors" (alist-get 'author info)) + (cons "ISBN" (alist-get 'identifier info)) + (cons "Language" (alist-get 'language info)) + (cons "Filesize-human" (alist-get 'filesize-human info)) + (cons "Extension" (alist-get 'extension info)) + (cons "md5" (alist-get 'md5 info)))) + +(defvar my-libfic-button-keymap + (let ((kmap (make-sparse-keymap))) + (set-keymap-parent kmap button-map) + (define-key kmap "d" 'my-libfic-download-action) + (define-key kmap "p" 'my-libfic-show-more-info) + kmap)) + +(defun my-libfic-show-more-info () + (interactive) + (let ((info (get-text-property (point) 'button-data))) + (pp (my-grok-libfic-make-info (my-libfic-update-info info))))) + +(defun my-libfic-download-action () + (interactive) + (let ((info (get-text-property (point) 'button-data))) + (my-wget-async + (my-libfic-make-download-link-onion + (my-libfic-update-info info)) + (format "%s/%s" (expand-file-name my-libfic-download-dir) + (my-libfic-format-filename info))))) + +(defun my-libfic-make-download-link-onion (info) + (let ((id-head (substring (alist-get 'id info) 0 -3))) + (format "%s/FF/%s%s/%s" + my-libgen-onion-host + (make-string (- 4 (length id-head)) ?0) + id-head + (downcase (alist-get 'md5 info))))) + (provide 'my-libgen) ;;; my-libgen.el ends here diff --git a/emacs/.emacs.d/lisp/my/my-web.el b/emacs/.emacs.d/lisp/my/my-web.el index 311bcf9..95592fd 100644 --- a/emacs/.emacs.d/lisp/my/my-web.el +++ b/emacs/.emacs.d/lisp/my/my-web.el @@ -148,5 +148,55 @@ (kill-new url) (message "Copied link: %s" url))) +;;; webgetter +(require 'my-net) +(defun my-open-spectator-au (url &optional no-overwrite) + (interactive "sspectator.com.au link: ") + (let ((url-request-extra-headers '(("X-Forwarded-For" . "66.249.66.1"))) + (url-user-agent "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")) + (let ((file-name + (if no-overwrite + (my-make-unique-file-name + (my-make-file-name-from-url url) + my-download-dir) + (expand-file-name + (my-make-file-name-from-url url) + my-download-dir)))) + (url-copy-file url file-name (not no-overwrite)) + (browse-url-firefox (format "file://%s" file-name))))) + +(defun my-mastodon-url-p (url) + "Guess if a url is a mastodon post. +e.g. https://hostux.social/@fsf/113709722998924141 +" + (pcase-let* ((urlobj (url-generic-parse-url url)) + (`(,path . _) (url-path-and-query urlobj))) + (string-match-p "^/@[^/]+/[0-9]\\{18\\}$" path))) + +(defun my-hacker-news-url-p (url) + "Check if a url is a hacker news post. +e.g. https://news.ycombinator.com/item?id=42505454" + (let ((urlobj (url-generic-parse-url url))) + (and (equal "news.ycombinator.com" (url-host urlobj)) + (string-match-p "^/item\\?id=[0-9]+$" (url-filename urlobj))))) + +(defun my-stack-overflow-url-p (url) + "Guess whether a url stack overflow question +e.g. +https://emacs.stackexchange.com/questions/40887/in-org-mode-how-do-i-link-to-internal-documentation" + (pcase-let* ((urlobj (url-generic-parse-url url)) + (`(,path . _) (url-path-and-query urlobj))) + (string-match-p "^/questions/[0-9]+/.+$" path)) ) + +(advice-add 'server-visit-files :around #'my-ec-handle-http) +(defun my-ec-handle-http (orig-fun files client &rest args) + ;; (message "GOT %s" files) + (dolist (var files) + (let ((fname (expand-file-name (car var)))) + (when (string-match ".*/\\(https?:/\\)" fname) + (browse-url (replace-match "\\1/" nil nil fname)) + (setq files (delq var files))))) + (apply orig-fun files client args)) + (provide 'my-web) ;;; my-web.el ends here diff --git a/emacs/.emacs.d/lisp/my/reddio.el b/emacs/.emacs.d/lisp/my/reddio.el new file mode 100644 index 0000000..2198e43 --- /dev/null +++ b/emacs/.emacs.d/lisp/my/reddio.el @@ -0,0 +1,53 @@ +;;; reddio.el -- reddit client through reddio -*- lexical-binding: t -*- + +;; Copyright (C) 2024 Free Software Foundation, Inc. + +;; Author: Yuchen Pei <id@ypei.org> +;; Package-Requires: ((emacs "29.4")) + +;; This file is part of dotted. + +;; dotted 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. + +;; dotted 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 dotted. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; reddit client through reddio. + +;;; Code: + +(defvar reddio-buffer "*reddio*") + +(defun reddio-open-url (url) + (interactive "sReddit link: ") + (when (string-match "/\\(comments/[^/]+\\)/" url) + (with-current-buffer (get-buffer-create reddio-buffer) + (let ((inhibit-read-only t)) + (erase-buffer) + (when (= 0 (call-process "reddio" nil reddio-buffer nil "print" + (match-string 1 url))) + (goto-char (point-min))) + (delete-trailing-whitespace)) + (text-mode) + (view-mode)) + (display-buffer reddio-buffer))) + +(defun reddio-reddit-url-p (url) + "e.g. +https://www.reddit.com/r/linux/comments/cs3os6/introducing_reddio_a_commandline_interface_for/" + (let ((urlobj (url-generic-parse-url url))) + (and (string-match-p "^.*\\<reddit.com$" (url-host urlobj)) + (string-match-p "^/r/[^/]+/comments/[^/]+/.+$" (url-filename urlobj))))) + +(provide 'reddio) +;;; reddio.el ends here diff --git a/misc/.bashrc b/misc/.bashrc index b425d61..814098d 100644 --- a/misc/.bashrc +++ b/misc/.bashrc @@ -280,7 +280,7 @@ gs-extract() { # ghostscript, merge files: gs-merge merged.pdf 1.pdf 2.pdf gs-merge() { - gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=$* + gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="$@" } # dptrp1 diff --git a/misc/.config/mimeapps.list b/misc/.config/mimeapps.list index e0b551f..413a9f5 100644 --- a/misc/.config/mimeapps.list +++ b/misc/.config/mimeapps.list @@ -36,8 +36,8 @@ video/quicktime=vlc.desktop video/x-msvideo=mpv.desktop x-scheme-handler/chrome=firefox.desktop x-scheme-handler/ftp=filezilla.desktop -x-scheme-handler/http=firefox.desktop -x-scheme-handler/https=firefox.desktop +x-scheme-handler/http=emacsclient-web.desktop +x-scheme-handler/https=emacsclient-web.desktop x-scheme-handler/mailto=emacsclient-mail.desktop x-scheme-handler/sgnl=signal-desktop.desktop x-scheme-handler/org-protocol=emacsclient-org-protocol.desktop diff --git a/misc/.local/share/applications/emacsclient-web.desktop b/misc/.local/share/applications/emacsclient-web.desktop new file mode 100644 index 0000000..5beb0f3 --- /dev/null +++ b/misc/.local/share/applications/emacsclient-web.desktop @@ -0,0 +1,20 @@ +[Desktop Entry] +Categories=Network;Web; +Comment=GNU Emacs is an extensible, customizable text editor - and more +Exec=/usr/bin/emacsclient -n %u +Icon=emacs +Name=Emacs (Web Browser, Client) +MimeType=x-scheme-handler/http;x-scheme-handler/https; +NoDisplay=true +Terminal=false +Type=Application +Keywords=emacsclient; +Actions=new-window;new-instance; + +[Desktop Action new-window] +Name=New Window +Exec=/usr/bin/emacsclient --create-frame -n %u + +[Desktop Action new-instance] +Name=New Instance +Exec=emacs -f browse-url %u |