aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-app.lisp18
-rw-r--r--oneliners.api-client.lisp88
-rw-r--r--oneliners.cli.asd2
-rw-r--r--src/lib.lisp61
4 files changed, 98 insertions, 71 deletions
diff --git a/build-app.lisp b/build-app.lisp
index 0a1bfd5..69338b1 100644
--- a/build-app.lisp
+++ b/build-app.lisp
@@ -80,7 +80,7 @@ you run the oneliner, all positional variables appear first.
(group (:header "ONELINER EXECUTION OPTIONS")
(text :contents "Runs the Nth search result with possible arguments ARGS.")
(flag :long-name "id"
- :description "Runs a oneliner by its id instead of by result number.")
+ :description "Refers a oneliner by its unique id instead of by result number.")
(flag :long-name "clip"
:description "Put oneliner into clipboard instead of running it.")
(flag :long-name "clear-cache"
@@ -203,21 +203,17 @@ than the users."
(a:when-let (hist-number (parse-integer (first arguments) :junk-allowed t))
(cond
((getopt :long-name "flag")
- (cli::flag-item hist-number))
+ (cli::flag-item hist-number (getopt :long-name "id")))
((getopt :long-name "unflag")
- (cli::unflag-item hist-number))
+ (cli::unflag-item hist-number (getopt :long-name "id")))
((getopt :long-name "lock")
- (cli::lock-item hist-number))
+ (cli::lock-item hist-number (getopt :long-name "id")))
((getopt :long-name "unlock")
- (cli::unlock-item hist-number))
+ (cli::unlock-item hist-number (getopt :long-name "id")))
((getopt :long-name "edit")
- (cli::edit-item hist-number))
+ (cli::edit-item hist-number (getopt :long-name "id")))
((getopt :long-name "explain")
- (cli::print-item-explanation hist-number))
-
- ;; ((getopt :long-name "alias")
- ;; (cli::make-alias-for-item hist-number (second arguments)))
-
+ (cli::print-item-explanation hist-number (getopt :long-name "id")))
(t
(cli::run-item hist-number (rest arguments)
:by-id (getopt :long-name "id")
diff --git a/oneliners.api-client.lisp b/oneliners.api-client.lisp
index bd7ba72..5fc6f10 100644
--- a/oneliners.api-client.lisp
+++ b/oneliners.api-client.lisp
@@ -5,11 +5,11 @@
(defpackage #:ONELINERS.API-CLIENT
(:use :cl :lazybones-client.shared)
(:export #:*host* #:*body* #:*headers* #:*cookies* #:request-with
- #:PUT--CONTRIBUTOR-WHO-PASSWORD
-#:GET--ONELINERS
+ #:GET--ONELINERS
#:GET--ONELINERS-ALL-FLAGGED
#:GET--ONELINERS-NEWEST
#:PUT--ONELINER-ENTRY-FLAG
+#:GET--ONELINER-ENTRY
#:PATCH--ONELINER-ENTRY-EDIT
#:PUT--ONELINER-ONELINER-LOCKED
#:POST--ONELINER
@@ -19,6 +19,7 @@
#:POST--ACCESS
#:POST--INVITE-REDEEM-CODE
#:PUT--CONTRIBUTOR-WHO-SIGNATURE
+#:PUT--CONTRIBUTOR-WHO-PASSWORD
#:PUT--CONTRIBUTOR-WHO-LOCKED
#:GET--CONTRIBUTOR-WHO))
(in-package :ONELINERS.API-CLIENT)
@@ -69,39 +70,6 @@ COOKIES should be an instance of CL-COOKIE:COOKIE-JAR. Defaults to
(dex:response-body ,http-error-var)))))))
-(DEFUN PUT--CONTRIBUTOR-WHO-PASSWORD (WHO &KEY VALUE REPEATED CURRENT TOKEN)
- "Change a contributor's password."
- (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
- (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* "/api"
- (FORMAT NIL "/contributor/~a/password" WHO)
- (WHEN (OR VALUE REPEATED CURRENT TOKEN)
- (LIST "?"
- (IF VALUE
- (CONCATENATE 'STRING (SYMBOL-NAME 'VALUE) "="
- (FORMAT NIL "~a" VALUE))
- "")
- (IF REPEATED
- (CONCATENATE 'STRING "&" (SYMBOL-NAME 'REPEATED)
- "=" (FORMAT NIL "~a" REPEATED))
- "")
- (IF CURRENT
- (CONCATENATE 'STRING "&" (SYMBOL-NAME 'CURRENT) "="
- (FORMAT NIL "~a" CURRENT))
- "")
- (IF TOKEN
- (CONCATENATE 'STRING "&" (SYMBOL-NAME 'TOKEN) "="
- (FORMAT NIL "~a" TOKEN))
- ""))))))
- (IF LAZYBONES-CLIENT.SHARED:*BODY*
- (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT
- LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR
- LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS
- LAZYBONES-CLIENT.SHARED:*HEADERS*)
- (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR
- LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS
- LAZYBONES-CLIENT.SHARED:*HEADERS*))))
-
-
(DEFUN GET--ONELINERS (&KEY TAGS LIMIT NOTFLAGGED)
"A search endpoint returning a JSON encoded array of Oneliner
Entries. TAGS cannot be empty. Returns a [Search
@@ -186,6 +154,16 @@ Result](#search-result) object."
LAZYBONES-CLIENT.SHARED:*HEADERS*))))
+(DEFUN GET--ONELINER-ENTRY (ENTRY)
+ "Gets a oneliner by id."
+ (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
+ (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* "/api"
+ (FORMAT NIL "/oneliner/~a" ENTRY) NIL)))
+ (DEXADOR:GET LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR
+ LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS
+ LAZYBONES-CLIENT.SHARED:*HEADERS*)))
+
+
(DEFUN PATCH--ONELINER-ENTRY-EDIT (ENTRY &KEY TOKEN)
"Edit the fields of a oneliner."
(LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
@@ -337,7 +315,7 @@ Result](#search-result) object."
(DEFUN PUT--CONTRIBUTOR-WHO-SIGNATURE (WHO &KEY TOKEN)
- NIL
+ "Update a [contributor's](#contributor) signature."
(LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
(APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* "/api"
(FORMAT NIL "/contributor/~a/signature" WHO)
@@ -357,8 +335,42 @@ Result](#search-result) object."
LAZYBONES-CLIENT.SHARED:*HEADERS*))))
+(DEFUN PUT--CONTRIBUTOR-WHO-PASSWORD (WHO &KEY VALUE REPEATED CURRENT TOKEN)
+ "Change a contributor's password."
+ (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
+ (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* "/api"
+ (FORMAT NIL "/contributor/~a/password" WHO)
+ (WHEN (OR VALUE REPEATED CURRENT TOKEN)
+ (LIST "?"
+ (IF VALUE
+ (CONCATENATE 'STRING (SYMBOL-NAME 'VALUE) "="
+ (FORMAT NIL "~a" VALUE))
+ "")
+ (IF REPEATED
+ (CONCATENATE 'STRING "&" (SYMBOL-NAME 'REPEATED)
+ "=" (FORMAT NIL "~a" REPEATED))
+ "")
+ (IF CURRENT
+ (CONCATENATE 'STRING "&" (SYMBOL-NAME 'CURRENT) "="
+ (FORMAT NIL "~a" CURRENT))
+ "")
+ (IF TOKEN
+ (CONCATENATE 'STRING "&" (SYMBOL-NAME 'TOKEN) "="
+ (FORMAT NIL "~a" TOKEN))
+ ""))))))
+ (IF LAZYBONES-CLIENT.SHARED:*BODY*
+ (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT
+ LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR
+ LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS
+ LAZYBONES-CLIENT.SHARED:*HEADERS*)
+ (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR
+ LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS
+ LAZYBONES-CLIENT.SHARED:*HEADERS*))))
+
+
(DEFUN PUT--CONTRIBUTOR-WHO-LOCKED (WHO &KEY VALUE TOKEN)
- NIL
+ "Admin users may lock a particular contributor, preventing that
+contributor for making edits or adding new oneliners."
(LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
(APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* "/api"
(FORMAT NIL "/contributor/~a/locked" WHO)
@@ -383,7 +395,7 @@ Result](#search-result) object."
(DEFUN GET--CONTRIBUTOR-WHO (WHO)
- NIL
+ "Return a [contributor](#contributor) data object."
(LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING
(APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* "/api"
(FORMAT NIL "/contributor/~a" WHO) NIL)))
diff --git a/oneliners.cli.asd b/oneliners.cli.asd
index 9b37b4c..1993389 100644
--- a/oneliners.cli.asd
+++ b/oneliners.cli.asd
@@ -1,5 +1,5 @@
(defsystem "oneliners.cli"
- :version "0.3.0"
+ :version "0.4.0"
:author "Colin Okay"
:license "AGPLv3"
:depends-on ("trivial-clipboard"
diff --git a/src/lib.lisp b/src/lib.lisp
index b87ffc6..d990b22 100644
--- a/src/lib.lisp
+++ b/src/lib.lisp
@@ -157,10 +157,11 @@ the directories that appear in the value of that variable."
(nth n contents)))))
(defmacro with-cached-result ((olvar n &optional idp) &body body)
- (a:with-gensyms (nvar)
- `(let ((,nvar ,n))
+ (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 idp `(cached-result ,nvar t) `(cached-result (1- ,nvar))))
+ (a:if-let (,olvar (if ,idpvar (cached-result ,nvar t) (cached-result (1- ,nvar))))
(progn ,@body)
(format t "Could not find the oneliner specified by ~a~%" ,nvar)))))
@@ -172,29 +173,29 @@ the directories that appear in the value of that variable."
;;; API REQUEST FUNCTIONS
-(defun flag-item (item-number)
- (with-cached-result (ol item-number)
+(defun flag-item (item-number &optional idp)
+ (with-cached-result (ol item-number idp)
(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)
- (with-cached-result (ol item-number)
+(defun unflag-item (item-number &optional idp)
+ (with-cached-result (ol item-number idp)
(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)
- (with-cached-result (ol item-number)
+(defun lock-item (item-number &optional idp)
+ (with-cached-result (ol item-number idp)
(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)
- (with-cached-result (ol item-number)
+(defun unlock-item (item-number &optional idp)
+ (with-cached-result (ol item-number idp)
(ensure-config)
(api:request-with
(:host (host))
@@ -249,12 +250,20 @@ 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*)))
- (if by-id
- (with-cached-result (ol item-number t)
- (bind-vars-and-run-oneliner ol args force-clip))
- (with-cached-result (ol item-number)
- (bind-vars-and-run-oneliner ol args force-clip)))))
+ (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 that oneliner with id ~a from the wiki.~%" item-number)
+ (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. Is something wrong?")))))
(defun valid-oneliner-string-p (string)
(and (not (find #\newline string))
@@ -329,10 +338,10 @@ the directories that appear in the value of that variable."
(api:post--oneliner :token (api-token))
(format t "Added~%"))))
-(defun edit-item (n)
+(defun edit-item (n &optional idp)
(ensure-config)
(assert (api-token) () "Cannot edit a oneliner without an api token.")
- (with-cached-result (ol n)
+ (with-cached-result (ol n idp)
(let* ((oneliner
(prompt "Oneliner: "
:expect 'valid-oneliner-string-p
@@ -377,7 +386,9 @@ 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))
- (update-history-item n new-item)
+ (if idp
+ (update-history-item n new-item)
+ (update-cached-item new-item))
(format t "OK~%"))))))
(defun request-invite-code ()
@@ -480,7 +491,15 @@ the directories that appear in the value of that variable."
(ol (nth (1- n) results)))
(when ol
(setf (nth (1- n) results) (append item ol))
- (cache-search-results-to-last-search-file results)))))
+ (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)