diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.lisp | 191 |
1 files changed, 66 insertions, 125 deletions
diff --git a/src/lib.lisp b/src/lib.lisp index 070e021..2ade79b 100644 --- a/src/lib.lisp +++ b/src/lib.lisp @@ -69,29 +69,26 @@ (defun config-file () (merge-pathnames ".config/oneliners.config" (user-homedir-pathname))) -(defun last-search-file () - (merge-pathnames ".last_oneliners_search" (user-homedir-pathname))) - (defun cached-oneliners-file () (merge-pathnames ".cached_oneliners" (user-homedir-pathname))) (defun wipe-cache () - (uiop:delete-file-if-exists (cached-oneliners-file)) - (uiop:delete-file-if-exists (last-search-file ))) + (uiop:delete-file-if-exists (cached-oneliners-file))) -(defun merge-into-cache (ols) +(defun merge-into-cache (new-ols) (if (uiop:file-exists-p (cached-oneliners-file)) - (let ((cached (with-open-file (input (cached-oneliners-file)) (read input)))) + (let ((cached-ols (with-open-file (input (cached-oneliners-file)) (read input)))) (with-open-file (out (cached-oneliners-file) :direction :output :if-exists :supersede) - (print (nconc - ols - (remove-if - (lambda (old) - (member (getf old :id) ols :test 'equal :key (lambda (x) (getf x :id)))) - cached)) - out))) - (with-open-file (out (cached-oneliners-file) :direction :output :if-exists :supersede) - (print ols out)))) + (print + (nconc + new-ols + (remove-if + (lambda (old) + (find (getf old :id) new-ols :key (lambda (x) (getf x :id)))) + cached-ols)) + out))) + (with-open-file (out (cached-oneliners-file) :direction :output) + (print new-ols out)))) ;;; UTILITIES (defun make-temp-file-name () @@ -145,70 +142,69 @@ the directories that appear in the value of that variable." ;; unregisters the hook. (rl:register-hook :pre-input nil))) -(defun cached-result (n &optional idp) - (if idp - (when (uiop:file-exists-p (cached-oneliners-file)) - (let ((contents (with-open-file (input (cached-oneliners-file)) (read input)))) - (find n contents :key (lambda (x) (getf x :id))))) - (when (uiop:file-exists-p (last-search-file)) - (let ((contents (with-open-file (input (last-search-file)) (read input)))) - (nth n contents))))) - -(defmacro with-cached-result ((olvar n &optional idp) &body body) - (a:with-gensyms (nvar idpvar) - `(let ((,nvar ,n) - (,idpvar ,idp)) - (assert (plusp ,nvar) () "Item number must be 1 or greater") - (a:if-let (,olvar (if ,idpvar (cached-result ,nvar t) (cached-result (1- ,nvar)))) +(defun the-oneliner (name-or-id) + "Get the oneliner with name-or-id. Try to fetch from local cache, +and, failing that, try to fetch from configured server." + (a:if-let ((ol (cached-result name-or-id))) + ol + (progn + (ensure-config) + (a:when-let (ol + (api:request-with (:host (host)) + (jonathan:parse + (api:get--oneliner-entry name-or-id)))) + (merge-into-cache (list ol)) + ol)))) + +(defun cached-result (n) + (when (uiop:file-exists-p (cached-oneliners-file)) + (let ((contents (with-open-file (input (cached-oneliners-file)) (read input)))) + (etypecase n + (integer + (find n contents :key (lambda (x) (getf x :id)))) + (string + (find n contents :key (lambda (x) (getf x :name)) :test #'equal)))))) + +(defmacro with-oneliner ((var name-or-id) &body body) + (assert (symbolp var)) + (let ((nvar (gensym))) + `(let ((,nvar ,name-or-id)) + (a:if-let (,var (the-oneliner ,nvar)) (progn ,@body) (format t "Could not find the oneliner specified by ~a~%" ,nvar))))) -(defun print-item-explanation (number &optional idp) - (let ((found nil)) - (with-cached-result (ol number idp) - (setf found t) - (when (getf ol :explanation) - (princ #\newline) - (princ (getf ol :explanation)))) - (when (and idp (not found)) - (format t "Trying to fetch oneliner with id ~a from the wiki.~%" number) - (ensure-config) - (a:if-let ((ol - (api:request-with (:host (host)) - (jonathan:parse - (api::get--oneliner-entry number))))) - (progn - (when (getf ol :explanation) - (princ #\newline) - (princ (getf ol :explanation))) - (merge-into-cache (list ol))) - (format t "Still couldn't find it. Are you connected?"))))) +(defun print-item-explanation (name-or-number) + (with-oneliner (ol name-or-number) + (print-oneliner-result-for-user ol) + (when (getf ol :explanation) + (princ #\newline) + (princ (getf ol :explanation))))) ;;; API REQUEST FUNCTIONS -(defun flag-item (item-number &optional idp) - (with-cached-result (ol item-number idp) +(defun flag-item (ident) + (with-oneliner (ol ident) (ensure-config) (api:request-with (:host (host)) (api:put--oneliner-entry-flag (getf ol :id) :token (api-token) :value "true")))) -(defun unflag-item (item-number &optional idp) - (with-cached-result (ol item-number idp) +(defun unflag-item (item-number) + (with-oneliner (ol item-number) (ensure-config) (api:request-with (:host (host)) (api:put--oneliner-entry-flag (getf ol :id) :token (api-token) :value "false")))) -(defun lock-item (item-number &optional idp) - (with-cached-result (ol item-number idp) +(defun lock-item (item-number) + (with-oneliner (ol item-number) (ensure-config) (api:request-with (:host (host)) (api:put--oneliner-oneliner-locked (getf ol :id) :token (api-token) :value "true")))) -(defun unlock-item (item-number &optional idp) - (with-cached-result (ol item-number idp) +(defun unlock-item (item-number) + (with-oneliner (ol item-number) (ensure-config) (api:request-with (:host (host)) @@ -262,22 +258,10 @@ the directories that appear in the value of that variable." (handle-run-oneliner oneliner (or force-clip (equalp runstyle "manual")))))) -(defun run-item (item-number args &key by-id force-clip (timeout nil timeout-p)) - (let ((*ol-output-timeout* (if timeout-p timeout *ol-output-timeout*)) - (found nil)) - (with-cached-result (ol item-number by-id) - (setf found t) - (bind-vars-and-run-oneliner ol args force-clip)) - (when (and by-id (not found)) - (format t "Trying to fetch oneliner with id ~a from the wiki.~%" item-number) - (ensure-config) - (a:if-let ((ol - (api:request-with (:host (host)) - (jonathan:parse - (api::get--oneliner-entry item-number))))) - (progn (bind-vars-and-run-oneliner ol args force-clip) - (merge-into-cache (list ol))) - (format t "Still couldn't find it. Are you connected?"))))) +(defun run-item (ident args &key force-clip (timeout nil timeout-p)) + (with-oneliner (ol ident) + (let ((*ol-output-timeout* (if timeout-p timeout *ol-output-timeout*))) + (bind-vars-and-run-oneliner ol args force-clip)))) (defun valid-oneliner-string-p (string) (and (not (find #\newline string)) @@ -289,28 +273,6 @@ the directories that appear in the value of that variable." (defun valid-runstyle-p (string) (member string '("auto" "manual") :test 'equalp)) -(defun aliases () - (getf *config* :aliases)) - -(defun (setf aliases) (newval) - (setf (getf *config* :aliases) newval)) - -(defun alias-item (item alias) - (with-cached-result (ol item) - (ensure-config) - (a:if-let (found (assoc alias (aliases))) - (setf (cdr found) ol) - (push (cons alias ol) (aliases))) - (write-config-to-disk))) - -(defun lookup-alias (alias) - (cdr (assoc alias (aliases)))) - -(defun run-alias (alias args &optional force-clip) - (ensure-config) - (a:when-let (ol (lookup-alias alias)) - (bind-vars-and-run-oneliner ol args force-clip))) - (defun add-new-oneliner () (ensure-config) (assert (api-token) () "Cannot add a oneliner without an api token.") @@ -352,10 +314,10 @@ the directories that appear in the value of that variable." (api:post--oneliner :token (api-token)) (format t "Added~%")))) -(defun edit-item (n &optional idp) - (ensure-config) - (assert (api-token) () "Cannot edit a oneliner without an api token.") - (with-cached-result (ol n idp) +(defun edit-item (ident) + (with-oneliner (ol ident) + (ensure-config) + (assert (api-token) () "Cannot edit a oneliner without an api token.") (let* ((oneliner (prompt "Oneliner: " :expect 'valid-oneliner-string-p @@ -400,9 +362,7 @@ the directories that appear in the value of that variable." new-item) :content-type "application/json") (api:patch--oneliner-entry-edit (getf ol :id) :token (api-token)) - (if idp - (update-history-item n new-item) - (update-cached-item new-item)) + (update-cached-item new-item) (format t "OK~%")))))) (defun request-invite-code () @@ -499,26 +459,8 @@ the directories that appear in the value of that variable." (api:delete--access-access (api-token) :token (api-token)) (format t "You were logged out~%"))) -(defun update-history-item (n item) - (when (uiop:file-exists-p (last-search-file)) - (let* ((results (with-open-file (input (last-search-file)) (read input))) - (ol (nth (1- n) results))) - (when ol - (setf (nth (1- n) results) (append item ol)) - (cache-search-results-to-last-search-file results)))) - (merge-into-cache (list item))) - (defun update-cached-item (item) - (let* ((history (with-open-file (input (last-search-file)) (read input))) - (pos (position (getf item :id) history :key (lambda (x) (getf item :id))))) - (if pos - (update-history-item (1+ pos) item) - (merge-into-cache (list item))))) - -(defun cache-search-results-to-last-search-file (results) - (with-open-file (output (last-search-file) :direction :output :if-exists :supersede) - (print results output)) - (merge-into-cache results)) + (merge-into-cache (list item))) (defvar *term-width* nil) @@ -557,7 +499,7 @@ the directories that appear in the value of that variable." (format t "~%~a~%~%" (getf oneliner :oneliner)))) (defun cache-and-print-search-response (response) - (cache-search-results-to-last-search-file + (merge-into-cache (loop for oneliner in (getf (jonathan:parse response) :oneliners) collect oneliner do (print-oneliner-result-for-user oneliner)))) @@ -585,7 +527,6 @@ the directories that appear in the value of that variable." (defun search-for-oneliners (terms limit not-flagged-p) (assert (loop for term in terms never (find #\, term) )) (set-term-width) - (format t "TERM WIDTH IS ~a~%" *term-width*) (ensure-config) (let ((response (api:request-with |