diff options
-rw-r--r-- | emacs/.emacs.d/lisp/my/fediorg.el | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/emacs/.emacs.d/lisp/my/fediorg.el b/emacs/.emacs.d/lisp/my/fediorg.el index e2f21b8..744206e 100644 --- a/emacs/.emacs.d/lisp/my/fediorg.el +++ b/emacs/.emacs.d/lisp/my/fediorg.el @@ -233,11 +233,14 @@ Including ancestors and descendants, if any." attachments "\n")) -(defun fediorg-format-post (post level) - "Format a POST with indent LEVEL." +(defun fediorg-format-post (post level &optional absolute-time) + "Format a POST with indent LEVEL. + +Required fields: url, created_at, account.username +Optional fields: account.display_name" (let-alist post (let ((host (car (fediorg-parse-url .url)))) - (format "%s %s (@%s@%s) %s\n\n%s%s\n\n⤷%d ⇆%d ★%d\n" + (format "%s %s (@%s@%s) %s\n\n%s%s\n\n⤷%s ⇆%s ★%s\n" (make-string level ?*) (if (string-empty-p .account.display_name) .account.username .account.display_name) @@ -245,10 +248,12 @@ Including ancestors and descendants, if any." host (fediorg-make-org-link .url - (fediorg--relative-time-description .created_at)) + (if absolute-time .created_at + (fediorg--relative-time-description .created_at))) (with-temp-buffer (insert .content) - (shr-render-region (point-min) (point-max)) + (let ((shr-fill-text nil)) + (shr-render-region (point-min) (point-max))) (buffer-substring-no-properties (point-min) (point-max))) (fediorg-format-attached .media_attachments host) .replies_count @@ -275,6 +280,78 @@ Including ancestors and descendants, if any." (pcase-let ((`(,host . ,post-id) (fediorg-parse-url url))) (format "%s.%s.org" host post-id))) +(defun fediorg-archive-make-file-name (actor) + (let-alist (fediorg-archive-parse-actor actor) + (format "%s.%s.org" .host .username))) + +(defun fediorg-archive-parse-actor (actor) + "Parse actor to username and display_name." + (let ((username (alist-get 'preferredUsername actor)) + (name (alist-get 'name actor)) + (url (alist-get 'id actor))) + (pcase-let* ((urlobj (url-generic-parse-url url)) + (host (url-host urlobj))) + `((display_name . ,name) + (username . ,username) + (host . ,host)))) + ) + +(defun fediorg-archive-format-item (item actor) + "ACTOR is parsed actor.json." + (let (post) + (pcase (alist-get 'type item) + ("Create" + (setq post (alist-get 'object item)) + (setf (alist-get 'url post) (alist-get 'id post) + (alist-get 'created_at post) (alist-get 'published item) + (alist-get 'account post) actor + (alist-get 'replies_count post) (alist-get 'repliesCount post))) + ("Announce" + (setf (alist-get 'url post) (alist-get 'object item) + (alist-get 'created_at post) (alist-get 'published item) + (alist-get 'account post) actor + (alist-get 'content post) + (format "[repost of %s]" (alist-get 'object item))))) + (fediorg-format-post post 1 t))) + +(defun fediorg-archive-format-outbox (info actor) + "Transform an outbox.json and an actor.json to an org file." + (let ((parsed-actor (fediorg-archive-parse-actor actor))) + (string-join + (seq-map + (lambda (item) (fediorg-archive-format-item item parsed-actor)) + (alist-get 'orderedItems info)) + "\n"))) + +;;;###autoload +(defun fediorg-archive-open (dir) + "Given a fedi archive, open an org buffer showing all outbox posts. + +A fedi archive can be obtained by exporting. This function requires an +outbox.json and an actor.json file. + +TODO: +- add support for likes and bookmarks +- add support for inline announces +- add inline images +- mark dm +" + (interactive (list (read-directory-name "Fedi archive dir: "))) + (let ((outbox-file (file-name-concat dir "outbox.json")) + (actor-file (file-name-concat dir "actor.json")) + (outbox) (actor)) + (unless (and (file-exists-p actor-file) (file-exists-p outbox-file)) + (error "Actor or outbox file missing!")) + (with-temp-buffer + (insert-file-contents actor-file) + (setq actor (json-read))) + (with-temp-buffer + (insert-file-contents outbox-file) + (setq outbox (json-read))) + (fediorg-save-text-and-switch-to-buffer + (fediorg-archive-format-outbox outbox actor) + (file-name-concat dir (fediorg-archive-make-file-name actor))))) + ;;;###autoload (defun fediorg-open (url) "Given a fedi post URL, open an org buffer rendering the post. |