(defpackage #:lazybones-client.shared (:intern #:req-string) (:export #:*host* #:*body* #:*headers* #:*cookies*)) (defpackage #:ONELINERS.API-CLIENT (:use :cl :lazybones-client.shared) (:export #:*host* #:*body* #:*headers* #:*cookies* #:request-with #:GET--FOOBAR-NUMBER #:GET--SEARCH #:PATCH--FLAG-ONELINER #:PATCH--EDIT-ONELINER #:PATCH--UNLOCK-ONELINER #:PATCH--LOCK-ONELINER #:POST--ADD-ONELINER #:POST--MAKE-INVITE #:POST--TOKEN-CONTRIBUTOR #:POST--REDEEM-INVITE)) (in-package :ONELINERS.API-CLIENT) (defvar *host* nil "The host to which the client will send its requests.") (defvar *body* nil "Body passed to client post, put, and patch requests") (defvar *cookies* nil "An instance of CL-COOKIE:COOKIE-JAR.") (defvar *headers* nil "A liist of (header-name . header-value) pairs.") (defmacro request-with ((&key host body headers content-type cookies) &body forms) "Make a request in a specific context. HOST is a string, the hostname where the request will be sent. Defaults to *HOST*. BODY should be a string, an alist, or a pathname. Default to *BODY* HEADERS should be an ALIST of (header-name . header-value) string pairs. Defaults to *HEADERS*. CONTENT-TYPE is a convenience for supplying just the Content-Type header. COOKIES should be an instance of CL-COOKIE:COOKIE-JAR. Defaults to *COOKIES*. " (let ((content-type-var (gensym))) `(let ((*host* (or ,host *host*)) (*body* (or ,body *body*)) (*headers* (or ,headers *headers*)) (*cookies* (or ,cookies *cookies*)) (,content-type-var ,content-type)) (when ,content-type-var (push (cons "Content-Type" ,content-type-var) *headers*)) ,@forms))) (DEFUN GET--FOOBAR-NUMBER (NUMBER &KEY NAME AGE) "Doesn't do anything really" (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/foobar/~a" NUMBER) (WHEN (OR NAME AGE) (LIST "?" (IF NAME (CONCATENATE 'STRING (SYMBOL-NAME 'NAME) "=" (FORMAT NIL "~a" NAME)) "") (IF AGE (CONCATENATE 'STRING "&" (SYMBOL-NAME 'AGE) "=" (FORMAT NIL "~a" AGE)) "")))))) (DEXADOR:GET LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS LAZYBONES-CLIENT.SHARED:*HEADERS*))) (DEFUN GET--SEARCH (&KEY TAGS LIMIT NOTFLAGGED) "A search endpoint returning a JSON encoded array of Oneliner Entries. TAGS cannot be empty." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/search") (WHEN (OR TAGS LIMIT NOTFLAGGED) (LIST "?" (IF TAGS (CONCATENATE 'STRING (SYMBOL-NAME 'TAGS) "=" (FORMAT NIL "~a" TAGS)) "") (IF LIMIT (CONCATENATE 'STRING "&" (SYMBOL-NAME 'LIMIT) "=" (FORMAT NIL "~a" LIMIT)) "") (IF NOTFLAGGED (CONCATENATE 'STRING "&" (SYMBOL-NAME 'NOTFLAGGED) "=" (FORMAT NIL "~a" NOTFLAGGED)) "")))))) (DEXADOR:GET LAZYBONES-CLIENT.SHARED::REQ-STRING :COOKIE-JAR LAZYBONES-CLIENT.SHARED:*COOKIES* :HEADERS LAZYBONES-CLIENT.SHARED:*HEADERS*))) (DEFUN PATCH--FLAG-ONELINER (ONELINER) "Flag the oneliner for review. Open to anyone." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/flag/~a" ONELINER) NIL))) (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--EDIT-ONELINER (ONELINER) "Edit the fields of a oneliner." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/edit/~a" ONELINER) NIL))) (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) "Unlocks a oneliner." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/unlock/~a" ONELINER) NIL))) (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--LOCK-ONELINER (ONELINER) "Locks a oneliner. Locked oneliners cannot be edited or flagged." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/lock/~a" ONELINER) NIL))) (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 POST--ADD-ONELINER () "Make a new [oneliner](#oneliner-post-body)." (LET ((LAZYBONES-CLIENT.SHARED::REQ-STRING (APPLY #'CONCATENATE 'STRING LAZYBONES-CLIENT.SHARED:*HOST* (FORMAT NIL "/add-oneliner") NIL))) (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*)))) (DEFUN POST--MAKE-INVITE () "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") NIL))) (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*)))) (DEFUN POST--TOKEN-CONTRIBUTOR (CONTRIBUTOR &KEY PASSWORD) "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)) "")))))) (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*)))) (DEFUN POST--REDEEM-INVITE (INVITE &KEY USERNAME PASSWORD1 PASSWORD2) "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)) "")))))) (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*))))