Post markdown with images to micro.blog in emacs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require 'request) | |
(setq mb-emacs-app-token "123456789") ;; create this in account -> app tokens -> edit apps | |
(setq mb-micropub-endpoint "https://micro.blog/micropub") | |
(setq mb-destination-address "https://your.micro.blog") | |
(setq mb-image-upload-timeout 20) ;; seconds | |
(defun mb-get-media-endpoint () | |
(cdr (assoc "media-endpoint" | |
(let (result) | |
(request | |
mb-micropub-endpoint | |
:params '(("q" . "config")) | |
:type "GET" | |
:sync t | |
:timeout: 10 | |
:parser 'json-read | |
:headers `(("Content-Type" . "application/json") | |
("Authorization".,(format "Bearer %s" mb-emacs-app-token))) | |
:complete (cl-function | |
(lambda (&key data &allow-other-keys) | |
(setq result data)))) | |
(if result | |
result | |
(error "Can't get media endpoint"))) | |
#'string=))) | |
(defun mb-upload-image (img-path media-endpoint) | |
"Post inline images." | |
(cdr (assoc "url" | |
(let ((result)) | |
(request | |
(concat media-endpoint | |
(if (boundp 'mb-destination-address) (concat "?mp-destination=" mb-destination-address))) | |
:type "POST" | |
:files `(("file" . ,img-path)) | |
:headers `(("Content-Type" . "multipart/form-data") | |
("Authorization".,(format "Bearer %s" mb-emacs-app-token))) | |
:sync t | |
:timeout mb-image-upload-timeout | |
:parser 'json-read | |
:success (cl-function | |
(lambda (&key data &allow-other-keys) | |
(setq result data)))) | |
(if result | |
result | |
(error "Error in uploading."))) | |
#'string=))) | |
(defun mb-markdown-upload-images-substitute-links () | |
"Upload images to micro.blog and substitute their local links with the upload locations." | |
(interactive) | |
(save-excursion | |
(save-restriction | |
(let ((media-endpoint (mb-get-media-endpoint))) | |
(widen) | |
(goto-char (point-min)) | |
(while (re-search-forward markdown-regex-link-inline nil t) | |
(let ((start (match-beginning 0)) | |
(imagep (match-beginning 1)) | |
(end (match-end 0)) | |
(file (match-string-no-properties 6))) | |
(when (and imagep | |
(not (zerop (length file)))) | |
(when (file-exists-p file) | |
(let* ((abspath (if (file-name-absolute-p file) | |
file | |
(concat default-directory file))) | |
(img-upload-url (save-match-data (mb-upload-image abspath media-endpoint)))) | |
(replace-match img-upload-url t t nil 6)))))))))) | |
(defun mb-post-buffer () | |
"Post current buffer to micro.blog (possibly as draft)." | |
(interactive) | |
(if (yes-or-no-p "Are you sure you want to post this?") | |
(save-restriction | |
(widen) | |
(let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max))) | |
(mb-post-name (read-string "Enter post name (leave empty if none):")) | |
(mb-post-status `(post-status . [,(if (yes-or-no-p "Post as draft?") "draft" "published")]))) | |
;; copy content of current buffer to new buffer, | |
;; then upload eventual linked images, substitute links with the upload locations, send buffer to microblog | |
(with-current-buffer (generate-new-buffer "post2mb") | |
(goto-char (point-min)) | |
(insert buffer-contents) | |
(goto-char (point-min)) | |
(mb-markdown-upload-images-substitute-links) | |
(request | |
(concat mb-micropub-endpoint | |
(if (boundp 'mb-destination-address) (concat "?mp-destination=" mb-destination-address))) | |
:type "POST" | |
:data (json-encode `((type . ["h-entry"]) | |
(properties | |
(content . [,(buffer-substring-no-properties (point-min) (point-max))]) | |
(name . [,mb-post-name]) ,mb-post-status))) | |
:headers `(("Content-Type" . "application/json") | |
("Authorization".,(format "Bearer %s" mb-emacs-app-token))) | |
:success (cl-function | |
(lambda (&key data &allow-other-keys) | |
(message "Success."))))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Thadeej, I'm also no Lisp programmer, so let's see if I'm of any help!
What about if instead of setting the token as a variable, you create a function which, when called, returns the token?
Something like this (didn't test it):
Then the headers section in the requests just becomes