aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emacs/.emacs.d/init/ycp-gnus.el4
-rw-r--r--emacs/.emacs.d/init/ycp-web.el19
m---------emacs/.emacs.d/lisp/hmm.el0
-rw-r--r--emacs/.emacs.d/lisp/my/my-libgen.el116
-rw-r--r--emacs/.emacs.d/lisp/my/my-web.el50
-rw-r--r--emacs/.emacs.d/lisp/my/reddio.el53
-rw-r--r--misc/.bashrc2
-rw-r--r--misc/.config/mimeapps.list4
-rw-r--r--misc/.local/share/applications/emacsclient-web.desktop20
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