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-net.el | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 emacs/.emacs.d/lisp/my/my-net.el (limited to 'emacs/.emacs.d/lisp/my/my-net.el') diff --git a/emacs/.emacs.d/lisp/my/my-net.el b/emacs/.emacs.d/lisp/my/my-net.el new file mode 100644 index 0000000..7713dba --- /dev/null +++ b/emacs/.emacs.d/lisp/my/my-net.el @@ -0,0 +1,113 @@ +;;; my-net.el -- Network related extensions for emacs core -*- 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: + +;; Network related extensions for emacs core. + +;;; Code: + + +;;; net utilities +(defvar my-download-dir "~/Downloads") + +(defun my-make-file-name-from-url (url) + (file-name-nondirectory + (directory-file-name + (car (url-path-and-query (url-generic-parse-url + (url-unhex-string url))))))) + +(defun my-fetch-url (url) + (interactive "sURL: ") + (let ((file-name (expand-file-name (my-make-file-name-from-url url) + my-download-dir))) + (url-retrieve url 'my-fetch-url-save-and-switch (list file-name)))) + +(defun my-fetch-url-save-and-switch (status file-name) + (unless (plist-get status :error) + (my-delete-http-header) + (write-file file-name) + (let ((coding-system-for-read 'utf-8)) + (revert-buffer t t)) + (switch-to-buffer (current-buffer)))) + +(defun my-kill-http-header () + (my-skip-http-header) + (let ((killed (buffer-substring-no-properties (point-min) (point)))) + (delete-region (point-min) (point)) + killed)) + +(defun my-parse-http-header (text) + (let ((status) (fields)) + (with-temp-buffer + (insert text) + (goto-char (point-min)) + (re-search-forward "^HTTP.*\\([0-9]\\{3\\}\\).*$") + (setq status (match-string 1)) + (while (re-search-forward "^\\(.*?\\): \\(.*\\)$" nil t) + (push (cons (intern (match-string 1)) (match-string 2)) fields))) + (list (cons 'status status) (cons 'fields fields)))) + +(defvar my-client-buffer-name "*my-api*") + +(defun my-url-fetch-json (url &optional decompression with-header) + (my-url-fetch-internal + url + (lambda () + (json-read-from-string (decode-coding-string (buffer-string) 'utf-8))) + decompression + with-header)) + +(defun my-url-fetch-dom (url &optional decompression with-header) + (my-url-fetch-internal + url + (lambda () (libxml-parse-html-region (point) (point-max))) + decompression + with-header)) + +(defun my-url-fetch-internal (url buffer-processor decompression with-header) + (with-current-buffer (get-buffer-create my-client-buffer-name) + (goto-char (point-max)) + (insert "[" (current-time-string) "] Request: " url "\n")) + (with-current-buffer (url-retrieve-synchronously url t) + (let ((header (my-kill-http-header)) (status) (fields)) + (goto-char (point-min)) + (setq header (my-parse-http-header header) + status (alist-get 'status header) + fields (alist-get 'fields header)) + (with-current-buffer my-client-buffer-name + (insert "[" (current-time-string) "] Response: " status "\n")) + (when decompression + (call-process-region (point) (point-max) "gunzip" t t t) + (goto-char (point-min))) + (call-interactively 'delete-trailing-whitespace) + (if (string= status "200") + (unless (= (point) (point-max)) + (if with-header + (list + (cons 'header fields) + (cons 'json (funcall buffer-processor))) + (funcall buffer-processor))) + (error "HTTP error: %s" (buffer-substring (point) (point-max))))))) + +(provide 'my-net) +;;; my-net.el ends here -- cgit v1.2.3