58 lines
1.7 KiB
Common Lisp
58 lines
1.7 KiB
Common Lisp
(defpackage :lispostory
|
|
(:use :cl :alexandria :serapeum)
|
|
(:export :main :create-exe-and-die))
|
|
|
|
(in-package :lispostory)
|
|
|
|
(defun http-get-json (url)
|
|
(multiple-value-bind (body status) (drakma:http-request url)
|
|
(if (/= status 200)
|
|
nil
|
|
(let ((body-str (flexi-streams:octets-to-string body)))
|
|
(shasht:read-json body-str)))))
|
|
|
|
(defun alist (&rest pairs)
|
|
(loop for (key value) on pairs by #'cddr
|
|
collect (cons key value)))
|
|
|
|
(defun map-vector (func vec)
|
|
(map 'vector func vec))
|
|
|
|
(defun string-to-hash-table-key (s)
|
|
(string-replace " " s ""))
|
|
|
|
(defun update-hash (hm key f)
|
|
(setf (@ hm key) (funcall f (@ hm key))))
|
|
|
|
(defun string->bool (s)
|
|
(if (string-equal (string-downcase s) "true") t nil))
|
|
|
|
(defclass data-source ()
|
|
((cache :initform nil :accessor cache)
|
|
(file-path :initarg :file-path :accessor file-path)))
|
|
|
|
(defmacro define-data-source (singular-name)
|
|
(let* ((class-name (symbolicate singular-name '-data-source))
|
|
(constructor-name (symbolicate 'make- singular-name '-data-source))
|
|
(plural-name (concat (symbol-name singular-name) "s"))
|
|
(file-name (concat (string-downcase plural-name) ".json")))
|
|
`(progn
|
|
(defclass ,class-name (data-source) ())
|
|
|
|
(defun ,constructor-name ()
|
|
(make-instance ',class-name :file-path ,file-name)))))
|
|
|
|
(defgeneric data (data-source))
|
|
(defmethod data ((ds data-source))
|
|
(or (cache ds)
|
|
(reload ds)))
|
|
|
|
(defgeneric reload (data-source))
|
|
(defmethod reload ((ds data-source))
|
|
(if (uiop:file-exists-p (file-path ds))
|
|
(let ((data (shasht:read-json (uiop:read-file-string (file-path ds)))))
|
|
(setf (cache ds) data)
|
|
data)))
|
|
|
|
(defgeneric refresh (data-source))
|