From ca44c445eebabae22b686214f22b0b02d0af67ec Mon Sep 17 00:00:00 2001 From: zdm Date: Sat, 15 Feb 2020 10:56:51 -0700 Subject: [PATCH] git on! --- emacs-upload.el | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 emacs-upload.el diff --git a/emacs-upload.el b/emacs-upload.el new file mode 100644 index 0000000..f6a9022 --- /dev/null +++ b/emacs-upload.el @@ -0,0 +1,154 @@ +;;; emacs-upload.el --- Upload regions, buffers, and files to various hosts. -*- lexical-binding: t; -*- + +;;; emacs-upload - Upload the region, buffer, or file to various hosts +;;; Copyright (C) <2019,2020> + +;;; This program is free software: you can redistribute it and/or +;;; modify it under the terms of the GNU Affero General Public License +;;; v3.0 as published by the Free Software Foundation. + +;;; This program 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 this program. If not, see . + +;;; Dependencies: cURL, cl, json + +;;; _Usage_ +;;; +;;; Place emacs-upload.el in your `load-path' and load the package: +;;; +;;; (require 'emacs-upload) +;;; +;;; Bind the interactive function `emacs-upload' to some key: +;;; +;;; (global-set-key (kbd "C-c e") 'emacs-upload) +;;; +;;; Alternatively, with `use-package' you can easily bind and set a default host. +;;; +;;; (use-package emacs-upload +;;; :demand t +;;; :bind +;;; ("C-c e" . emacs-upload) +;;; :config +;;; (emacs-upload/set-host "ix")) + +;;; `emacs-upload/set-host' is also an interactive command, so you can +;;; change your host on the fly. + +;;; To upload the region, simply select the region and call emacs-upload. To +;;; upload the whole buffer, have no region selected and call emacs-upload. For +;;; a file, use the universal argument `C-u' before calling emacs-upload. + +(require 'cl) +(require 'json) + +(defcustom emacs-upload/host '("http://w1r3.net" "upload=@%s") + "Current host to upload to.") + +(defcustom emacs-upload/hosts '(("w1r3" . ("https://w1r3.net" "upload=@%s")) + ("ix" . ("http://ix.io" "f:1=@%s")) + ("0x0" . ("https://0x0.st" "file=@%s")) + ("sprunge" . ("http://sprunge.us" "sprunge=@%s")) + ("youdieifyou.work" . ("http://youdieifyou.work/upload.php" "files[]=@%s")) + ("catbox" . ("https://catbox.moe/user/api.php" "reqtype=fileupload" "fileToUpload=@%s")) + ("fiery" . ("https://safe.fiery.me/api/upload" "files[]=@%s")) + ("dmca.gripe" . ("https://dmca.gripe/api/upload" "files[]=@%s"))) + "List of hosts you can set emacs-upload/host to.") + +(defun emacs-upload/buffer-list () + "Return a list consisting of the minimum and maximum point values." + (list (point-min) (point-max))) + +(defun emacs-upload/region-list () + "Return a list consisting of the beginning and end of the active region." + (list (region-beginning) (region-end))) + +(defun emacs-upload/make-temp-file (file-name) + "Return a string of a temporarily created file with the suffix +either being the filename's extension, if it exists, or `.txt' +for buffers not associated with a file." + (make-temp-file "emacs-upload" nil (if file-name (file-name-extension file-name t) + ".txt"))) + +(defun emacs-upload/write-content-to-file (content file) + "Write content to file, content being a list of the beginning +and ending points." + (apply 'write-region (append content (list file)))) + +(defun emacs-upload/list-curl-forms (file) + "Generate a list curl forms" + (if (cddr emacs-upload/host) + (let* ((forms (mapcan (lambda (form) (list "-F" form)) (rest emacs-upload/host))) + (file-form (car (last forms)))) + (append (butlast forms) + (list (format file-form file) (first emacs-upload/host)))) + (list "-F" (format (second emacs-upload/host) file) (first emacs-upload/host)))) + +(defun emacs-upload/start-curl-process (file) + "Start curl process" + (apply 'start-process "emacs-upload" nil "curl" (emacs-upload/list-curl-forms file))) + +(defun emacs-upload/pomf-parse (json) + "Parse json and return a URL string or nil if an error occurred" + (let* ((pretty-json (json-read-from-string json)) + (success (equal (cdr (assoc 'success pretty-json)) t))) + (if success (cdr (assoc 'url (aref (cdr (cadr pretty-json)) 0))) + (let ((inhibit-message t)) + (mapc (lambda (desc) + (message "%s: %s" (car desc) (cdr desc))) + pretty-json) + nil)))) + +(defun emacs-upload/filter (process output) + "Determine whether or not the output is json, either parsing +the json or simply stripping the newlines from output and killing +that." + (if (string-match "{" output) + (let ((result (emacs-upload/pomf-parse output))) + (if result (message "File uploaded at %s and saved to your kill-ring." + (kill-new result)) + (message "Error while uploading file. See *Messages* buffer for more information."))) + (if (string-match "http" output) + (message "File uploaded at %s and saved to your kill ring." + (kill-new (replace-regexp-in-string "\n$" "" output))) + (progn + (let ((inhibit-message t)) + (message output) + nil) + (message "Error while uploading file. See *Messages* buffer for more information"))))) + +;;;###autoload +(defun emacs-upload/set-host (host) + "Set host. Call this interactively or as function from your +init to set a default from the list of available hosts, such +as: (emacs-upload/set-host \"ix\")" + (interactive + (list (completing-read "Set the host: " (mapcar 'first emacs-upload/hosts) + nil t))) + (setq emacs-upload/host (cdr (assoc host emacs-upload/hosts))) + (message "emacs-upload/host is now set to %s" host)) + +;;;###autoload +(defun emacs-upload (&optional arg) + "Upload the region if selected, the buffer if it is not, or if +called with ARG (C-u) select a file." + (interactive "P") + (if (executable-find "curl") + (let ((file nil)) + (cond ((and (not arg) (region-active-p)) + (setq file (emacs-upload/make-temp-file nil)) + (emacs-upload/write-content-to-file (emacs-upload/region-list) file)) + (arg (setq file (read-file-name "File to upload: "))) + (t (setq file (emacs-upload/make-temp-file nil)) + (emacs-upload/write-content-to-file (emacs-upload/buffer-list) file))) + (message "Uploading...") + (set-process-filter (emacs-upload/start-curl-process file) 'emacs-upload/filter)) + (message "cURL not found"))) + +(provide 'emacs-upload) + +;;; emacs-upload.el ends here