aboutsummaryrefslogtreecommitdiff
path: root/emacs/.emacs.d/lisp/my/my-web.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs/.emacs.d/lisp/my/my-web.el')
-rw-r--r--emacs/.emacs.d/lisp/my/my-web.el203
1 files changed, 187 insertions, 16 deletions
diff --git a/emacs/.emacs.d/lisp/my/my-web.el b/emacs/.emacs.d/lisp/my/my-web.el
index 311bcf9..87c319f 100644
--- a/emacs/.emacs.d/lisp/my/my-web.el
+++ b/emacs/.emacs.d/lisp/my/my-web.el
@@ -59,14 +59,15 @@
(interactive)
(let ((url (plist-get eww-data :url)))
(when (and (string-match "^\\(.*//.*?/\\).*$" url)
- (match-string 1 url))
+ (match-string 1 url))
(eww (match-string 1 url)))))
+(defvar my-tor-browser-bin "tor-browser")
+
(defun my-browse-url-tor-browser (url)
"Browse URL with tor-browser."
(setq url (browse-url-encode-url url))
- (start-process (concat "tor-browser " url) nil "tor-browser"
- "--allow-remote" url))
+ (start-process "tor-browser" nil my-tor-browser-bin "--allow-remote" url))
(defun my-browse-url-firefox-private (url)
"Browse URL in a private firefox window."
@@ -86,19 +87,6 @@
(start-process (concat "mullvad-browser " url) nil "mullvad-browser"
url))
-;; TODO: change to using hmm matching url with default app
-;; override browse-url
-(defun my-browse-url (url &optional arg)
- (interactive "P")
- (cond ((equal arg '(4))
- (funcall browse-url-secondary-browser-function url))
- ((equal arg '(16))
- (my-browse-url-tor-browser url))
- (t (luwak-open url))))
-
-;; this fixes clicking url buttons like those in gnus messages
-(defalias 'browse-url-button-open-url 'my-browse-url)
-
(defun my-browse-url-at-point (arg)
(interactive "P")
(my-browse-url (browse-url-url-at-point) arg))
@@ -148,5 +136,188 @@
(kill-new url)
(message "Copied link: %s" url)))
+;;; webgetter
+(require 'my-net)
+(defun my-fetch-browse (url &optional no-overwrite)
+ "Fetch URL to a local file then browse it with firefox.
+
+Useful for bypassing \"Enable JavaScript and cookies to continue\"."
+ (interactive "sUrl to fetch and browse: ")
+ (let ((file-name
+ (if no-overwrite
+ (my-make-unique-file-name
+ (my-make-file-name-from-url url)
+ my-webpage-incoming-dir)
+ (expand-file-name
+ (my-make-file-name-from-url url "html")
+ my-webpage-incoming-dir))))
+ (url-copy-file url file-name (not no-overwrite))
+ (browse-url-firefox (format "file://%s" file-name))))
+
+(defun my-fetch-browse-as-googlebot (url &optional no-overwrite)
+ "Same as `my-fetch-browse', but spoofing googlebot.
+
+Useful for bypassing some paywalls."
+ (interactive "sUrl to fetch and browse as googlebot: ")
+ (my-url-as-googlebot
+ (my-fetch-browse url no-overwrite)))
+
+(require 'hmm)
+(defvar my-url-context-function 'hmm-url "Context function for urls.")
+(defvar my-file-context-function 'hmm-file "Context function for files.")
+
+(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)))))
+
+(defvar my-newscorp-au-amp-nk nil)
+(defun my-open-newscorp-au (url)
+ (interactive "sNews Corp AU link: ")
+ (pcase-let* ((urlobj (url-generic-parse-url url))
+ (`(,path . _) (url-path-and-query urlobj)))
+ (setf (url-filename urlobj)
+ (format "%s?amp&nk=%s" path my-newscorp-au-amp-nk))
+ (browse-url-firefox (url-recreate-url urlobj))))
+
+(defun my-newscorp-au-url-p (url)
+ (string-match-p "^\\(www\\.\\)?\\(heraldsun\\|theaustralian\\)\\.com\\.au$"
+ (url-host (url-generic-parse-url url))))
+
+(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))
+
+(defvar my-firefox-profile-dir nil "Firefox profile dir")
+(defvar my-firefox-place-limit 1000 "Firefox urls result limit")
+
+(defun my-firefox-places (&optional query)
+ (let ((where
+ (mapconcat
+ (lambda (word) (format "(url LIKE '%%%s%%' OR title LIKE '%%%s%%')" word word))
+ (split-string (or query ""))
+ " AND ")))
+ (unless (string-empty-p where) (setq where (format "WHERE %s" where)))
+ (with-temp-buffer
+ (call-process "sqlite3" nil t nil
+ (format "file://%s/places.sqlite?immutable=1"
+ (expand-file-name my-firefox-profile-dir))
+ (format
+ "SELECT url,title FROM moz_places %s ORDER BY visit_count desc limit %d"
+ where
+ my-firefox-place-limit))
+ (string-lines (buffer-string))
+ )))
+
+(defun my-firefox-places-collection (query pred action)
+ (if (eq action 'metadata)
+ `(metadata (display-sort-function . ,#'identity)
+ ;; Needed for icomplete to respect list order
+ (cycle-sort-function . ,#'identity))
+ (let ((candidates (my-firefox-places query)))
+ (message "Got %d candidates for query %s. Current action is %s" (length candidates) query action)
+ (cl-loop for str in-ref candidates do
+ (setf str (orderless--highlight regexps ignore-case (substring str))))
+ candidates
+ ;; Does not show remotely as many results
+ ;; (complete-with-action action candidates query pred)
+ )))
+
+(defun my-browse-url (url)
+ (interactive (list (completing-read "URL to browse: "
+ #'my-firefox-places-collection)))
+ (message url))
+
+(defun my-forge-infobox-format-url (url)
+ (concat url
+ " -- " (buttonize "clone"
+ (lambda (_)
+ (my-magit-clone url current-prefix-arg)))
+ " " (buttonize "context"
+ (lambda (_)
+ (funcall my-url-context-function url)))))
+
+(defvar my-dw-host "dw.com")
+
+(defun my-dw-parse-article-url (url)
+ "Returns (lang . article-id)"
+ (let* ((urlobj (url-generic-parse-url url))
+ (path (url-filename urlobj))
+ (components (string-split path "/")))
+ `(,(elt components 1) . ,(string-remove-prefix "a-" (elt components 3)))))
+
+(defun my-dw-article-api (url)
+ (pcase-let ((`(,lang . ,id) (my-dw-parse-article-url url)))
+ (my-url-fetch-json
+ (format "https://%s/graph-api/%s/content/article/%s" my-dw-host lang id))))
+
+(defun my-dw-extract (info)
+ "Returns list of (url . file-name) pairs."
+ (let* ((content (alist-get 'content (alist-get 'data info)))
+ (dir (file-name-concat my-audio-incoming-dir
+ (my-make-doc-file-name
+ (alist-get 'title content))))
+ (audios (alist-get 'audios content)))
+ (seq-map
+ (lambda (audio)
+ (let ((url (alist-get 'mp3Src audio)))
+ `(,url
+ .
+ ,(expand-file-name
+ (file-name-concat dir (file-name-with-extension
+ (my-make-doc-file-name
+ (alist-get 'name audio))
+ (file-name-extension url)))))))
+ audios)))
+
+(defun my-dw-download (pairs)
+ "Download list of (url . file-name) pairs with aria2."
+ (let ((file (make-temp-file "/tmp/aria2"))
+ (n (length pairs)))
+ (with-temp-file file
+ (dolist (pair pairs)
+ (insert (car pair) "\n out=" (cdr pair) "\n"))
+ ;; (buffer-string)
+ )
+ (message "Downloading %d files..." n)
+ (set-process-sentinel
+ (start-process "aria2" "*aria2*" "aria2c" "-x" "5" "-d" "/"
+ "-R" "true" "-i" file)
+ (lambda (proc event)
+ (let ((status (process-exit-status proc)))
+ (if (eq status 0)
+ (progn
+ (message "Downloading %d files...Done" n))
+ (message "Downloading %d files...Failed: %s" n event)))))))
+
+(defun my-dw-download-url (url)
+ (interactive "sDW Download URL: ")
+ (my-dw-download (my-dw-extract (my-dw-article-api url))))
+
+(defun my-dw-download-urls (urls)
+ (my-dw-download (seq-mapcat
+ (lambda (url) (my-dw-extract (my-dw-article-api url)))
+ urls)))
+
+(defun my-local-archive-open-url (url)
+ "Open url from local archive."
+ )
+
(provide 'my-web)
;;; my-web.el ends here