untrusted comment: verify with st.pub
RWQTleDnDrmVqVdvd3FyfBzCpuHDQsj+wkAgx9X3fb1VzuwjFvMa1LqnrsgKorzL0SVcu3yas8TtbHGrTPJIfyZuy8npVC9dEQ0=
(require :asdf)
(require :alexandria)

(require :tooter)

;; Do first:
;; Make a tooter client instance and make-load-form it into
;; client.sexp. super easy. Check tooter's doc/

(defvar *client* (with-open-file (in #p"client.sexp") (read in)))
(defvar *ht* (make-hash-table :test 'equal))

(defun save-threads (&optional (filename #p"threads.sexp")) "
Saves alist of *ht* to #p\"threads.sexp\"
"
(with-open-file (out filename :direction :output :if-exists :supersede)
 (let ((*print-pretty* t))
  (prin1 (alexandria:hash-table-alist *ht*) out))))

(Defun load-threads (&optional (filename #p"threads.sexp"))
(setq *ht*
 (alexandria:alist-hash-table
  (with-open-file (in filename) (read in))
  :test 'equal)))

(defun 2key.alist (status)
(cons (tooter:id status)
 (list
   (cons  'utime (tooter:created-at status))
   (multiple-value-bind (sec min hou day mon yea)
    (decode-universal-time (tooter:created-at status))
    (cons 'd-time (format nil "~d of ~d ~d:~d"
     day mon hou min)))
   (cons 'account-name
    (tooter:account-name (tooter:account status)))
   (cons 'content (tooter:plain-format-html
    (tooter:content status)))
   (cons 'attachments
    (mapcar (lambda (x) (tooter:remote-url x))
     (tooter:media-attachments status))))))

(defun sew-thread (status)
(let* ((progenitor
        (or (car (tooter:ancestors
                  (tooter:context *client* status)))
         status))
       (orig-context (tooter:context *client* progenitor))
       (protid (tooter:id progenitor)))
 (symbol-macrolet ((it (gethash protid *ht*)))
  (loop initially (setf it
                   (or it (list (2key.alist progenitor))))
   for d in (tooter:descendants orig-context)
   for key.alist = (2key.alist d)
   do (unless (assoc (car key.alist) it :test 'equal)
       (push key.alist (cdr it)))
   finally (setf it (sort it '< :key 'cdadr))
   (return-from sew-thread it)))))