initial commit
This commit is contained in:
119
spawns.lisp
Normal file
119
spawns.lisp
Normal file
@@ -0,0 +1,119 @@
|
||||
(in-package :lispostory)
|
||||
|
||||
(defparameter *chronostory-spawns-url-format* "https://docs.google.com/spreadsheets/d/e/2PACX-1vSIUj-72ADgwMqShxt4Dn7OP7dBN54l0wda1IPwlIVTZUN_ZtTlRx5DDidr43VXv2HYQ5RNqccLbbGS/pub?gid=~a&output=csv&single=true")
|
||||
|
||||
(defparameter *chronostory-spawn-gids*
|
||||
(alist
|
||||
:maple-island 415330053
|
||||
:lith-harbor 486394009
|
||||
:kerning-city 0
|
||||
:henesys 898655980
|
||||
:perion 1754196543
|
||||
:ellinia 508846815
|
||||
:nautilus 714441637
|
||||
:sleepywood 615729202
|
||||
:orbis 350970245
|
||||
:el-nath 1897049096
|
||||
:ludibrium 1290087592))
|
||||
|
||||
(defvar *chronostory-spawns* nil)
|
||||
|
||||
(defun chronostory-spawn-url (gid)
|
||||
(format nil *chronostory-spawns-url-format* gid))
|
||||
|
||||
(defun find-first-empty-field (line)
|
||||
"Upon receiving the csvs from google sheets, we need to find the first
|
||||
'empty' header column. That column is the delimiter between two
|
||||
separate csvs."
|
||||
(loop for i from 0 below (- (length line) 1)
|
||||
with comma-count = 0
|
||||
when (char= (char line i) #\,)
|
||||
do (incf comma-count)
|
||||
when (and (char= (char line i) #\,)
|
||||
(char= (char line (+ i 1)) #\,))
|
||||
return comma-count))
|
||||
|
||||
(defun find-char-index-of-field (line field)
|
||||
"Could be an off by one here?"
|
||||
(loop for i from 0 below (length line)
|
||||
with comma-count = 0
|
||||
when (char= (char line i) #\,)
|
||||
do (incf comma-count)
|
||||
when (= comma-count field)
|
||||
return i))
|
||||
|
||||
(defun second-half (line field)
|
||||
(let* ((index (find-char-index-of-field line field))
|
||||
(second-half (subseq line (+ 2 index))))
|
||||
second-half))
|
||||
|
||||
|
||||
(defun string-to-number-p (str)
|
||||
(handler-case
|
||||
(progn
|
||||
(parse-integer str)
|
||||
t)
|
||||
(parse-error () nil)))
|
||||
|
||||
(defun csv-to-hash-tables (csv)
|
||||
(let* ((keys (mapcar (lambda (k)
|
||||
(let ((k2 (string-upcase (serapeum:string-replace " " k ""))))
|
||||
(intern k2 :keyword)))
|
||||
(car csv)))
|
||||
(result (make-array 0 :adjustable t :fill-pointer 0)))
|
||||
(loop for row in csv
|
||||
with mapname = ""
|
||||
for hm = (serapeum:pairhash keys row (serapeum:dict))
|
||||
when (let ((name (gethash :monster hm)))
|
||||
(and (string-not-equal "" name)
|
||||
(string-not-equal "-" name)
|
||||
(string-not-equal "Monster" name)))
|
||||
do (progn
|
||||
(if (and (string-not-equal mapname "") (string-equal (gethash :mapname hm) ""))
|
||||
(setf (gethash :mapname hm) mapname)
|
||||
(setf mapname (gethash :mapname hm)))
|
||||
(vector-push-extend hm result)))
|
||||
result))
|
||||
|
||||
(defun parse-sheet (sheet)
|
||||
(let* ((lines (serapeum:lines sheet))
|
||||
(field (find-first-empty-field (car lines)))
|
||||
(first-half (loop for line in lines
|
||||
when (not (uiop:string-prefix-p ",,," line))
|
||||
collect (let ((index (find-char-index-of-field line field)))
|
||||
(subseq line 0 index))))
|
||||
(second-half (loop for line in lines
|
||||
for second-half = (second-half line field)
|
||||
when (not (uiop:string-prefix-p ",,," second-half))
|
||||
collect second-half))
|
||||
(joined (serapeum:string-join (concatenate 'list first-half second-half) #\Newline)))
|
||||
(csv-to-hash-tables (cl-csv:read-csv joined))))
|
||||
|
||||
(defun refresh-spawn-data ()
|
||||
(let ((spawn-data (serapeum:pairhash
|
||||
(mapcar #'car *chronostory-spawn-gids*)
|
||||
(mapcar (lambda (pair)
|
||||
(let* ((gid (cdr pair))
|
||||
(data (drakma:http-request (chronostory-spawn-url gid))))
|
||||
(uiop:println (serapeum:concat "Requesting data for " (symbol-name (car pair))))
|
||||
(parse-sheet data)))
|
||||
*chronostory-spawn-gids*))))
|
||||
(setf *chronostory-spawns* spawn-data)
|
||||
(alexandria-2:write-string-into-file
|
||||
(shasht:write-json spawn-data nil)
|
||||
"spawns.json"
|
||||
:if-exists :overwrite
|
||||
:if-does-not-exist :create)
|
||||
spawn-data))
|
||||
|
||||
(defun reload-spawn-data ()
|
||||
(let ((spawn-data (shasht:read-json (uiop:read-file-string "spawns.json" :if-does-not-exist nil))))
|
||||
(setf *chronostory-spawns* spawn-data)
|
||||
spawn-data))
|
||||
|
||||
(defun load-spawn-data ()
|
||||
(serapeum:if-not *chronostory-spawns*
|
||||
(reload-spawn-data)
|
||||
*chronostory-spawns*))
|
||||
|
||||
(refresh-spawn-data)
|
||||
Reference in New Issue
Block a user