From 7675e07d526f889e7917b8f2644ee21603103299 Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Wed, 9 Feb 2022 09:30:06 -0600 Subject: initial outline --- clpmfile.lock | 76 ++++++++++++++++++-------------------- oneliners.api.asd | 2 +- src/main.lisp | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 141 insertions(+), 44 deletions(-) diff --git a/clpmfile.lock b/clpmfile.lock index 5295372..5a28a41 100644 --- a/clpmfile.lock +++ b/clpmfile.lock @@ -31,7 +31,6 @@ :releases ("alexandria" :version "2021-12-09" :source "quicklisp" :systems ("alexandria")) -("arrows" :version "2018-10-18" :source "quicklisp" :systems ("arrows")) ("babel" :version "2020-09-25" :source "quicklisp" :systems ("babel")) ("bknr-datastore" :version "2019-12-27" :source "quicklisp" :systems ("bknr.datastore" "bknr.indices" "bknr.skip-list" "bknr.utils")) @@ -43,29 +42,29 @@ ("cl+ssl" :version "2021-12-30" :source "quicklisp" :systems ("cl+ssl")) ("cl-annot" :version "2015-06-08" :source "quicklisp" :systems ("cl-annot")) ("cl-base64" :version "2020-10-16" :source "quicklisp" :systems ("cl-base64")) +("cl-change-case" :version "2021-04-11" :source "quicklisp" :systems + ("cl-change-case")) ("cl-fad" :version "2021-01-24" :source "quicklisp" :systems ("cl-fad")) ("cl-interpol" :version "2020-12-20" :source "quicklisp" :systems ("cl-interpol")) -("cl-ppcre" :version "2019-05-21" :source "quicklisp" :systems ("cl-ppcre")) +("cl-ppcre" :version "2019-05-21" :source "quicklisp" :systems + ("cl-ppcre" "cl-ppcre-unicode")) +("cl-str" :version "2021-05-31" :source "quicklisp" :systems ("str")) ("cl-syntax" :version "2015-04-07" :source "quicklisp" :systems ("cl-syntax" "cl-syntax-annot")) ("cl-unicode" :version "2021-02-28" :source "quicklisp" :systems ("cl-unicode")) -("clack" :version "2021-12-09" :source "quicklisp" :systems ("clack")) ("closer-mop" :version "2021-12-30" :source "quicklisp" :systems ("closer-mop")) ("dissect" :version "2021-05-31" :source "quicklisp" :systems ("dissect")) -("do-urlencode" :version "2018-10-18" :source "quicklisp" :systems - ("do-urlencode")) ("fast-io" :version "2020-09-25" :source "quicklisp" :systems ("fast-io")) ("flexi-streams" :version "2021-08-07" :source "quicklisp" :systems ("flexi-streams")) ("hunchentoot" :version "2020-06-10" :source "quicklisp" :systems ("hunchentoot")) -("ironclad" :version "2021-10-21" :source "quicklisp" :systems ("ironclad")) ("jonathan" :version "2020-09-25" :source "quicklisp" :systems ("jonathan")) -("lack" :version "2021-12-30" :source "quicklisp" :systems - ("lack" "lack-component" "lack-middleware-backtrace" "lack-util")) -("lazybones" :version (:commit "c57cf07e31037e2d1cfe9a697de7bc228e0290dc") - :source :implicit-vcs :systems ("lazybones")) +("lazybones" :version (:commit "6225e142525d02888d0a1aa83fb716ddb58db907") + :source :implicit-vcs :systems ("lazybones" "lazybones-hunchentoot")) +("lisp-namespace" :version "2021-10-21" :source "quicklisp" :systems + ("lisp-namespace")) ("md5" :version "2021-06-30" :source "quicklisp" :systems ("md5")) ("named-readtables" :version "2021-12-09" :source "quicklisp" :systems ("named-readtables")) @@ -103,11 +102,10 @@ ("alexandria" ((:system :name "yason") (:system :name "alexandria")) ((:system :name "static-vectors") (:system :name "alexandria")) ((:system :name "proc-parse") (:system :name "alexandria")) + ((:system :name "lisp-namespace") (:system :name "alexandria")) ((:system :name "lazybones") (:system :name "alexandria")) ((:system :name "hunchentoot") (:system :name "alexandria")) ((:system :name "fast-io") (:system :name "alexandria")) - ((:system :name "do-urlencode") (:system :name "alexandria")) - ((:system :name "clack") (:system :name "alexandria")) ((:system :name "cl-fad") (:system :name "alexandria")) ((:system :name "cl-annot") (:system :name "alexandria")) ((:system :name "cl+ssl") (:system :name "alexandria")) @@ -118,11 +116,8 @@ ((:system :name "bknr.datastore") (:system :name "alexandria")) ((:system :name "babel") (:system :name "alexandria"))) -("arrows" ((:system :name "lazybones") (:system :name "arrows"))) - ("babel" ((:system :name "proc-parse") (:system :name "babel")) ((:system :name "jonathan") (:system :name "babel")) - ((:system :name "do-urlencode") (:system :name "babel")) ((:system :name "cffi") (:system :name "babel"))) ("bknr-datastore" @@ -133,9 +128,7 @@ ((:system :name "bknr.datastore") (:system :name "bknr.utils"))) ("bordeaux-threads" ((:system :name "rove") (:system :name "bordeaux-threads")) - ((:system :name "ironclad") (:system :name "bordeaux-threads")) ((:system :name "hunchentoot") (:system :name "bordeaux-threads")) - ((:system :name "clack") (:system :name "bordeaux-threads")) ((:system :name "cl-fad") (:system :name "bordeaux-threads")) ((:system :name "cl+ssl") (:system :name "bordeaux-threads")) ((:system :name "bknr.utils") (:system :name "bordeaux-threads"))) @@ -156,33 +149,40 @@ ("cl-base64" ((:system :name "hunchentoot") (:system :name "cl-base64"))) -("cl-fad" ((:system :name "lazybones") (:system :name "cl-fad")) - ((:system :name "hunchentoot") (:system :name "cl-fad"))) +("cl-change-case" ((:system :name "str") (:system :name "cl-change-case"))) + +("cl-fad" ((:system :name "hunchentoot") (:system :name "cl-fad"))) ("cl-interpol" ((:system :name "bknr.utils") (:system :name "cl-interpol")) ((:system :name "bknr.indices") (:system :name "cl-interpol")) ((:system :name "bknr.datastore") (:system :name "cl-interpol"))) -("cl-ppcre" ((:system :name "jonathan") (:system :name "cl-ppcre")) +("cl-ppcre" ((:system :name "str") (:system :name "cl-ppcre")) + ((:system :name "str") (:system :name "cl-ppcre-unicode")) + ((:system :name "lazybones") (:system :name "cl-ppcre")) + ((:system :name "jonathan") (:system :name "cl-ppcre")) ((:system :name "hunchentoot") (:system :name "cl-ppcre")) ((:system :name "cl-unicode") (:system :name "cl-ppcre")) + ((:system :name "cl-ppcre-unicode") (:system :name "cl-ppcre")) + ((:system :name "cl-change-case") (:system :name "cl-ppcre")) + ((:system :name "cl-change-case") (:system :name "cl-ppcre-unicode")) ((:system :name "bknr.utils") (:system :name "cl-ppcre"))) +("cl-str" ((:system :name "lazybones") (:system :name "str"))) + ("cl-syntax" ((:system :name "jonathan") (:system :name "cl-syntax")) ((:system :name "jonathan") (:system :name "cl-syntax-annot")) ((:system :name "cl-syntax-annot") (:system :name "cl-syntax"))) -("cl-unicode" ((:system :name "cl-interpol") (:system :name "cl-unicode"))) +("cl-unicode" ((:system :name "cl-ppcre-unicode") (:system :name "cl-unicode")) + ((:system :name "cl-interpol") (:system :name "cl-unicode"))) -("clack" ((:system :name "lazybones") (:system :name "clack"))) - -("closer-mop" ((:system :name "bknr.indices") (:system :name "closer-mop")) +("closer-mop" ((:system :name "lazybones") (:system :name "closer-mop")) + ((:system :name "bknr.indices") (:system :name "closer-mop")) ((:system :name "bknr.datastore") (:system :name "closer-mop"))) ("dissect" ((:system :name "rove") (:system :name "dissect"))) -("do-urlencode" ((:system :name "lazybones") (:system :name "do-urlencode"))) - ("fast-io" ((:system :name "jonathan") (:system :name "fast-io"))) ("flexi-streams" @@ -190,23 +190,19 @@ ((:system :name "cl+ssl") (:system :name "flexi-streams")) ((:system :name "bknr.utils") (:system :name "flexi-streams"))) -("hunchentoot" ((:system :name "lazybones") (:system :name "hunchentoot"))) - -("ironclad" ((:system :name "lack-util") (:system :name "ironclad"))) +("hunchentoot" + ((:system :name "lazybones-hunchentoot") (:system :name "hunchentoot"))) ("jonathan" ((:system :name "oneliners.api") (:system :name "jonathan")) ((:system :name "lazybones") (:system :name "jonathan"))) -("lack" ((:system :name "lack") (:system :name "lack-component")) - ((:system :name "lack") (:system :name "lack-util")) - ((:system :name "clack") (:system :name "lack")) - ((:system :name "clack") (:system :name "lack-util")) - ((:system :name "clack") (:system :name "lack-middleware-backtrace"))) +("lazybones" + ((:system :name "oneliners.api") (:system :name "lazybones-hunchentoot")) + ((:system :name "lazybones-hunchentoot") (:system :name "lazybones")) + (t (:project :name "lazybones" :branch "master" :source :implicit-vcs))) -("lazybones" ((:system :name "oneliners.api") (:system :name "lazybones")) - (t - (:project :name "lazybones" :commit - "c57cf07e31037e2d1cfe9a697de7bc228e0290dc" :source :implicit-vcs))) +("lisp-namespace" + ((:system :name "lazybones") (:system :name "lisp-namespace"))) ("md5" ((:system :name "hunchentoot") (:system :name "md5")) ((:system :name "bknr.utils") (:system :name "md5"))) @@ -225,8 +221,7 @@ ("rove" ((:system :name "oneliners.api/tests") (:system :name "rove"))) -("split-sequence" ((:system :name "usocket") (:system :name "split-sequence")) - ((:system :name "lazybones") (:system :name "split-sequence"))) +("split-sequence" ((:system :name "usocket") (:system :name "split-sequence"))) ("static-vectors" ((:system :name "fast-io") (:system :name "static-vectors"))) @@ -257,7 +252,6 @@ ("unit-test" ((:system :name "bknr.datastore") (:system :name "unit-test"))) ("usocket" ((:system :name "hunchentoot") (:system :name "usocket")) - ((:system :name "clack") (:system :name "usocket")) ((:system :name "cl+ssl") (:system :name "usocket"))) ("yason" ((:system :name "bknr.datastore") (:system :name "yason"))) diff --git a/oneliners.api.asd b/oneliners.api.asd index 8c6c657..3a6b48f 100644 --- a/oneliners.api.asd +++ b/oneliners.api.asd @@ -2,7 +2,7 @@ :version "0.1.0" :author "Colin Okay" :license "AGPLv3" - :depends-on ("lazybones" + :depends-on ("lazybones-hunchentoot" "bknr.datastore" "jonathan") :components ((:module "src" diff --git a/src/main.lisp b/src/main.lisp index ff073d9..8d01e4a 100644 --- a/src/main.lisp +++ b/src/main.lisp @@ -1,5 +1,108 @@ (defpackage oneliners.api - (:use :cl)) + (:use :cl) + (:local-nicknames (#:lzb #:lazybones) + (#:a #:alexandria) + (#:db #:bknr.datastore)) + (:import-from #:lazybones + #:defendpoint* + #:http-ok + #:http-err)) (in-package :oneliners.api) -;; blah blah blah. +;;; SERVICE CONTROL + +(defvar *server* nil) + +(defun ensure-server (port address) + (unless *server* + (setf *server* (lzb:create-server :port port :address address)) + (lzb:set-canned-response *server* 400 "Bad Request" "text/plain") + (lzb:set-canned-response *server* 404 "Not Found" "text/plain") + (lzb:set-canned-response *server* 500 "Server Error" "text/plain"))) + +(defun start (&optional (port 8888) (address "127.0.0.1")) + (ensure-server port address) + (lzb:install-app *server* (lzb:app)) + (lzb:start-server *server*)) + +(defun stop () + (when *server* + (lzb:stop-server *server*))) + +;;; API DEFINITION AND PROVISIONING + +(defparameter +oneliners-description+ + "TBD") + +(lzb:provision-app () + :title "Oneliners Wiki API" + :version "0.0.1" + :desc +oneliners-description+ + :content-type "application/json" + :auth 'api-token-authorization) + +(defun api-token-authorization () + "TBD" + t) + +;;; ENDPOINT DEFINITIONS + +(defendpoint* :get "/search" () + "A search endpoint returning a JSON encoded array of Command Entries. + +/search accepts the following query parameters: + +- command : The name of a command. E.g. `ls`, `grep`, `netcat`. +- keywords : A comma-separated list of words that may appear in the title or description of a command entry, e.t. `'foo,bar,goo,zar,moo_blar' +- limit : An integer, limiting the number of results returned. Defaults to 10. +- recent : 0 for false 1 for true; sorts results by how recently they were added. Defaults to 0. +- nextpage : 0 for false 1 for true; requests that the query be accompanied by a nextpage key +- page : a nextpage token that will continue from a previous search. These expire after 10 minutes. + +**Note** that either `command` or `keyword` parameters are required. +" + (http-ok "[]")) + +(defendpoint* :put "/command/:command command-by-id:" (:auth t) + "Updates a command entry in the wiki database." + (cond + (command + (update-commmand command (lzb:request-body)) ; throws an error if fails, triggering a 500 + (http-ok "true")) + (t (http-err 404)))) ;no command with the given id. + +(defendpoint* :post "/command" (:auth t) + "Adds a new command entry to the wiki database." + (a:if-let (new-command (add-command-to-db (lzb:request-body))) + (http-ok "{}") ; dummy implementation + (http-err 400))) + + +(defendpoint* :post "/auth" () + "Requests an authorization token") + +;;; HELPERS + +(defun command-by-id (id-string) + "An integer id of a command." + (list :a-dummy-command id-string)) + +(defun valid-command-update-data-p (jsonplist) + "Checks the fields of jsonplist, return t if they are sufficient to update a command entry." + jsonplist);; dummy implementation + +(defun update-commmand (command json-body) + "Accepts a decoded json body, a plist, and " + (assert (valid-command-update-data-p json-body)) + (list command json-body)) ;; dummy implmenetation + +(defun valid-command-init-data-p (plist) + "dchecks the fields in plist,returns t if they are sufficient to create a new command." + plist);; dummy implementation + +(defun add-command-to-db (json-plist) + "adds a new command to the database, returning it upon success " + (assert (valid-command-init-data-p json-plist)) + :dummy-ok) + + -- cgit v1.2.3