diff options
-rw-r--r-- | oneliners.api-client.lisp | 132 | ||||
-rw-r--r-- | src/lib.lisp | 51 |
2 files changed, 75 insertions, 108 deletions
diff --git a/oneliners.api-client.lisp b/oneliners.api-client.lisp index d66ce65..2ae2c65 100644 --- a/oneliners.api-client.lisp +++ b/oneliners.api-client.lisp @@ -5,16 +5,16 @@ (defpackage #:ONELINERS.API-CLIENT (:use :cl :lazybones-client.shared) (:export #:*host* #:*body* #:*headers* #:*cookies* #:request-with - #:GET--SEARCH -#:PATCH--FLAG-ONELINER -#:PATCH--EDIT-ONELINER -#:PATCH--UNLOCK-ONELINER -#:PATCH--LOCK-ONELINER -#:POST--ADD-ONELINER -#:POST--MAKE-INVITE -#:POST--REVOKE-CONTRIBUTOR -#:POST--TOKEN-CONTRIBUTOR -#:POST--REDEEM-INVITE)) + #:GET--ONELINERS + #:GET--ONELIERS + #:PUT--ONELINER-ENTRY-FLAG + #:PATCH--ONELINER-ENTRY-EDIT + #:PUT--ONELINER-ONELINER-LOCKED + #:POST--ONELINER + #:POST--INVITE + #:DELETE--ACCESS-CONTRIBUTOR + #:POST--ACCESS + #:POST--INVITE-REDEEM-CODE)) (in-package :ONELINERS.API-CLIENT) @@ -63,13 +63,13 @@ COOKIES should be an instance of CL-COOKIE:COOKIE-JAR. Defaults to (dex:response-body ,http-error-var))))))) -(DEFUN GET--SEARCH (&KEY TAGS LIMIT NOTFLAGGED) +(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 Result](#search-result) object." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/search") + (FORMAT NIL "/oneliers") (WHEN (OR TAGS LIMIT NOTFLAGGED) (LIST "?" (IF TAGS @@ -89,11 +89,11 @@ Result](#search-result) object." LAZYBONES-CLIENT.SHARED:*HEADERS*))) -(DEFUN PATCH--FLAG-ONELINER (ONELINER &KEY TOKEN) - "Flag the oneliner for review. Open to anyone." +(DEFUN PUT--ONELINER-ENTRY-FLAG (ENTRY &KEY TOKEN) + "Flag the oneliner for review." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/flag/~a" ONELINER) + (FORMAT NIL "/oneliner/~a/flag" ENTRY) (WHEN (OR TOKEN) (LIST "?" (IF TOKEN @@ -101,41 +101,20 @@ Result](#search-result) object." (FORMAT NIL "~a" TOKEN)) "")))))) (IF LAZYBONES-CLIENT.SHARED:*BODY* - (DEXADOR:PATCH LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT + (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS LAZYBONES-CLIENT.SHARED:*HEADERS*) - (DEXADOR:PATCH LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR + (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS LAZYBONES-CLIENT.SHARED:*HEADERS*)))) -(DEFUN PATCH--EDIT-ONELINER (ONELINER &KEY TOKEN) +(DEFUN PATCH--ONELINER-ENTRY-EDIT (ENTRY &KEY TOKEN) "Edit the fields of a oneliner." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/edit/~a" ONELINER) - (WHEN (OR TOKEN) - (LIST "?" - (IF TOKEN - (CONCATENATE 'STRING (SYMBOL-NAME 'TOKEN) "=" - (FORMAT NIL "~a" TOKEN)) - "")))))) - (IF LAZYBONES-CLIENT.SHARED:*BODY* - (DEXADOR:PATCH LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT - LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR - LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS - LAZYBONES-CLIENT.SHARED:*HEADERS*) - (DEXADOR:PATCH LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR - LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS - LAZYBONES-CLIENT.SHARED:*HEADERS*)))) - - -(DEFUN PATCH--UNLOCK-ONELINER (ONELINER &KEY TOKEN) - "Unlocks a oneliner." - (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING - (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/unlock/~a" ONELINER) + (FORMAT NIL "/oneliner/~a/edit" ENTRY) (WHEN (OR TOKEN) (LIST "?" (IF TOKEN @@ -152,32 +131,36 @@ Result](#search-result) object." LAZYBONES-CLIENT.SHARED:*HEADERS*)))) -(DEFUN PATCH--LOCK-ONELINER (ONELINER &KEY TOKEN) - "Locks a oneliner. Locked oneliners cannot be edited or flagged." +(DEFUN PUT--ONELINER-ONELINER-LOCKED (ONELINER &KEY TOKEN VALUE) + "Sets the locked value of the specified oneliner" (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/lock/~a" ONELINER) - (WHEN (OR TOKEN) + (FORMAT NIL "/oneliner/~a/locked" ONELINER) + (WHEN (OR TOKEN VALUE) (LIST "?" (IF TOKEN (CONCATENATE 'STRING (SYMBOL-NAME 'TOKEN) "=" (FORMAT NIL "~a" TOKEN)) + "") + (IF VALUE + (CONCATENATE 'STRING "&" (SYMBOL-NAME 'VALUE) "=" + (FORMAT NIL "~a" VALUE)) "")))))) (IF LAZYBONES-CLIENT.SHARED:*BODY* - (DEXADOR:PATCH LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT + (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS LAZYBONES-CLIENT.SHARED:*HEADERS*) - (DEXADOR:PATCH LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR + (DEXADOR:PUT LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS LAZYBONES-CLIENT.SHARED:*HEADERS*)))) -(DEFUN POST--ADD-ONELINER (&KEY TOKEN) +(DEFUN POST--ONELINER (&KEY TOKEN) "Make a new [oneliner](#oneliner)." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/add-oneliner") + (FORMAT NIL "/oneliner") (WHEN (OR TOKEN) (LIST "?" (IF TOKEN @@ -194,11 +177,11 @@ Result](#search-result) object." LAZYBONES-CLIENT.SHARED:*HEADERS*)))) -(DEFUN POST--MAKE-INVITE (&KEY TOKEN) +(DEFUN POST--INVITE (&KEY TOKEN) "On success, return an object containing a new [invite token](#invite-token)." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/make-invite") + (FORMAT NIL "/invite") (WHEN (OR TOKEN) (LIST "?" (IF TOKEN @@ -215,40 +198,27 @@ Result](#search-result) object." LAZYBONES-CLIENT.SHARED:*HEADERS*)))) -(DEFUN POST--REVOKE-CONTRIBUTOR (CONTRIBUTOR &KEY TOKEN) - "A contributor can revoke their own access (if for some reason their - API key ends up out of their control), or an admin can revoke - anybody's access token, forcing the to re-authenticate." +(DEFUN DELETE--ACCESS-CONTRIBUTOR (CONTRIBUTOR &KEY TOKEN) + NIL (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/revoke/~a" CONTRIBUTOR) + (FORMAT NIL "/access/~a" CONTRIBUTOR) (WHEN (OR TOKEN) (LIST "?" (IF TOKEN (CONCATENATE 'STRING (SYMBOL-NAME 'TOKEN) "=" (FORMAT NIL "~a" TOKEN)) "")))))) - (IF LAZYBONES-CLIENT.SHARED:*BODY* - (DEXADOR:POST LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT - LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR - LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS - LAZYBONES-CLIENT.SHARED:*HEADERS*) - (DEXADOR:POST LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR - LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS - LAZYBONES-CLIENT.SHARED:*HEADERS*)))) + (DEXADOR:DELETE LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR + LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS + LAZYBONES-CLIENT.SHARED:*HEADERS*))) -(DEFUN POST--TOKEN-CONTRIBUTOR (CONTRIBUTOR &KEY PASSWORD) - "Authenticate a contributor and reply with an [api token](#access-token)" +(DEFUN POST--ACCESS () + "Authenticate a contributor and reply with an [API token](#access-token)" (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/token/~a" CONTRIBUTOR) - (WHEN (OR PASSWORD) - (LIST "?" - (IF PASSWORD - (CONCATENATE 'STRING (SYMBOL-NAME 'PASSWORD) "=" - (FORMAT NIL "~a" PASSWORD)) - "")))))) + (FORMAT NIL "/access") NIL))) (IF LAZYBONES-CLIENT.SHARED:*BODY* (DEXADOR:POST LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR @@ -259,25 +229,11 @@ Result](#search-result) object." LAZYBONES-CLIENT.SHARED:*HEADERS*)))) -(DEFUN POST--REDEEM-INVITE (INVITE &KEY USERNAME PASSWORD1 PASSWORD2) +(DEFUN POST--INVITE-REDEEM-CODE (CODE) "Redeem an [invite code](#invite-code) and create a new [contributor](#new-contributor-post-body)" (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* - (FORMAT NIL "/redeem/~a" INVITE) - (WHEN (OR USERNAME PASSWORD1 PASSWORD2) - (LIST "?" - (IF USERNAME - (CONCATENATE 'STRING (SYMBOL-NAME 'USERNAME) "=" - (FORMAT NIL "~a" USERNAME)) - "") - (IF PASSWORD1 - (CONCATENATE 'STRING "&" (SYMBOL-NAME 'PASSWORD1) - "=" (FORMAT NIL "~a" PASSWORD1)) - "") - (IF PASSWORD2 - (CONCATENATE 'STRING "&" (SYMBOL-NAME 'PASSWORD2) - "=" (FORMAT NIL "~a" PASSWORD2)) - "")))))) + (FORMAT NIL "/invite/redeem/~a" CODE) NIL))) (IF LAZYBONES-CLIENT.SHARED:*BODY* (DEXADOR:POST LAZYBONES-CLIENT.SHARED::REQ-STRING :CONTENT LAZYBONES-CLIENT.SHARED:*BODY* :COOKIE-JAR diff --git a/src/lib.lisp b/src/lib.lisp index d174c6a..332dd07 100644 --- a/src/lib.lisp +++ b/src/lib.lisp @@ -92,15 +92,22 @@ the directories that appear in the value of that variable." (princ prompt out-stream) (force-output out-stream) (read-line in-stream)) +(defun history (&optional n) + (when (uiop:file-exists-p (last-search-file)) + (let ((contents (with-open-file (input (last-search-file)) (read input)))) + (if n + (nth n contents) + contents)))) + ;;; API REQUEST FUNCTIONS -;; (defun flag-item (item-number) -;; (ensure-config) -;; (api:request-with -;; (:host (host)) -;; (a:if-let ((token (api-token)) -;; (oneliner (history item-number))) -;; (api:patch--flag-oneliner (getf oneliner :id) :token token)))) +(defun flag-item (item-number) + (assert (plusp item-number) () "Item number must be ") + (ensure-config) + (api:request-with + (:host (host)) + (a:when-let (oneliner (history (1- item-number))) + (api:put--oneliner-entry-flag (getf oneliner :id) :token (api-token))))) (defun add-new-oneliner () (ensure-config) @@ -126,22 +133,26 @@ the directories that appear in the value of that variable." :brief brief :explanation explanation)) :content-type "application/json") - (api:post--add-oneliner :token (api-token)) + (api:post--oneliner :token (api-token)) (format t "Added~%")))) (defun request-invite-code () (ensure-config) (api:request-with (:host (host)) - (format t "Invite Code: ~a~%" - (getf (jonathan:parse (api:post--make-invite :token (api-token))) :code)))) + (let ((invite (api:post--invite :token (api-token)))) + (format t "Invite Code: ~a~%Expires: ~a~%" + (getf invite :code) + (getf invite :expires))))) (defun login (user pass) (ensure-config) (a:when-let (response (jonathan:parse (api:request-with - (:host (host)) - (api:post--token-contributor user :password pass)))) + (:host (host) + :body (jonathan:to-json (list :password pass :handle user)) + :content-type "application/json") + (api:post--access)))) (setf (api-token) (getf response :token)) (write-config-to-disk) (format t "Access token written to ~a~%" (config-file)))) @@ -149,11 +160,11 @@ the directories that appear in the value of that variable." (defun redeem-invite (token name pass) (ensure-config ) (api:request-with - (:host (host)) - (api:post--redeem-invite token - :username name - :password1 pass - :password2 pass))) + (:host (host) + :body (jonathan:to-json (list :handle name :password1 pass :password2 pass)) + :content-type "application/json") + (api:post--invite-redeem-code token) + (format t "Account made for ~a. You may log in now~%" name))) (defun cache-search-results-to-last-search-file (results) (with-open-file (output (last-search-file) :direction :output :if-exists :supersede) @@ -175,9 +186,9 @@ the directories that appear in the value of that variable." (let ((response (api:request-with (:host (host)) - (api:get--search :tags (str:join "," terms) - :limit limit - :notflagged (if not-flagged-p "true" "false"))))) + (api:get--oneliners :tags (str:join "," terms) + :limit limit + :notflagged (if not-flagged-p "true" "false"))))) (handler-case (a:when-let (oneliners (getf (jonathan:parse response) :oneliners)) |