Files
lispostory/utils.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))