Public archive for the Return to Ritherdon project. https://www.nicolaellisandritherdon.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

138 lines
5.4 KiB

(defpackage #:search
(:use #:cl
#:app-constants
#:cl-json
#:local-time
#:utils)
(:import-from #:dexador
#:request)
(:export #:build-keywords-string
#:build-payload
#:delete-entry
#:find-entry
#:get-id
#:get-keywords
#:submit-entry
#:set-filter-attributes
#:delete-all-entries
#:create-dump))
(in-package #:search)
;; Explains the "~{~A~^,~}" in the format call below.
;; https://stackoverflow.com/questions/8830888/whats-the-canonical-way-to-join-strings-in-a-list
(defun build-keywords-string (id)
"Gets the keywords for `ID' in meilisearch DB and formats into a string.
The string should look something like: 'art,blog post,testing,whatever'. One
thing to note is meilisearch uses the comma to separate and create tokens of the
string. So, the user can have spaces in their keywords but they cannot separate
the keywords with a space. 'art blog post' is classed as three tokens and
'art,blog post' is classes as two."
(format nil "~{~A~^,~}" (search:get-keywords (search:find-entry id))))
(defun build-payload (id-value title-value relative-path-value
thumbnail-path-value publish-month-value publish-year-value keywords-value)
"Creates a JSON object which reflects the schema in the meilsearch database.
Note: The JSON object to encoded as a string."
(cl-json:encode-json-to-string
`((("id" . ,id-value)
("title" . ,title-value)
("relative-path" . ,relative-path-value)
("thumbnail-path" . ,thumbnail-path-value)
("year" . ,publish-year-value)
("month" . ,publish-month-value)
;; ("day" . ,(local-time:timestamp-day created-at-value))
("keywords" . ,(cl-ppcre:split "," keywords-value))))))
(defun build-search-url (path)
"Constructs the URL to connect to the meilisearch instance (beta or prod.)
The function will check to see which environment the current instance of this
site is running in and use the beta or prod. URL's to connect to meilisearch.
`PATH' is the relative path which this function will concatenate onto the end of
the base URL."
(if (ritherdon-archive.config:developmentp)
(concatenate 'string "http://localhost:7700" path)
(concatenate 'string "https://www.nera.com" path)))
(defun delete-entry (id)
"Deletes and entry from the meilisearch database based on its `ID'.
This does not affect this website's (nera) database -- only the meilisearch
one."
(dexador:request
(build-search-url
(format nil "/indexes/nera/documents/~a" id)); (get-id (find-entry id))))
:method :delete
:use-connection-pool nil
:headers `(("Authorization" . ,(meilisearch-api-key)))
:verbose nil))
(defun documents-total ()
"Gets the total number of documents in the meilisearch database."
(rest
(second
(second
(assoc :indexes (cl-json:decode-json-from-string
(dexador:request (build-search-url "/stats")
:method :get
:use-connection-pool nil
:headers `(("Content-Type" . "application/json")
("Authorization" . ,(meilisearch-api-key)))
:verbose nil)))))))
(defun find-entry (title)
"Finds the entry in the meilisearch database by its `TITLE'."
(cl-json:decode-json-from-string
(dexador:request
(build-search-url "/indexes/nera/search")
:method :post
:use-connection-pool nil
:headers `(("Content-Type" . "application/json")
("Authorization" . ,(meilisearch-api-key)))
:content (format nil "{ \"q\": \"~a\", \"limit\": 1 }" title)
:verbose nil)))
(defun get-id (payload)
"Gets the id from the JSON `PAYLOAD', make sure limit is set to 1."
(rest (third (second (first payload)))))
(defun get-keywords (payload)
"Get the keywords from the JSON `PAYLOAD'."
(rest (first (last (last (second (first payload)))))))
(defun meilisearch-api-key ()
"Returns either the beta or prod. API key for meilisearch.
The API key is determined based on which environment this website is
currently running in."
(if (ritherdon-archive.config:developmentp)
"Bearer meilisearch-beta-key"
"Bearer meilisearch-production-key-nera"))
(defun submit-entry (payload)
"Adds a new article to the meilisearch database."
(dexador:request ;;"http://127.0.0.1:7700/indexes/nera/documents"
(build-search-url "/indexes/nera/documents")
:method :post
:use-connection-pool nil
:headers `(("Content-Type" . "application/json")
("Authorization" . ,(meilisearch-api-key)))
:content payload
:verbose nil))
(defun set-filter-attributes ()
"Sets the filter attributes in the Meilisearch database.
These values are hard-coded into the system because they are based on what Nic
has requested. She would like the filtering to consist on years and months."
(utils:run-bash-command
(format nil "curl -X PATCH \'~a\' -H \'Authorization: ~a\' -H \'Content-Type: application/json\' --data-binary \'{ \"filterableAttributes\": [ \"year\", \"month\", \"keywords\" ]}\'"
(build-search-url "/indexes/nera/settings") (meilisearch-api-key))))
(defun delete-all-entries ()
"Deletes all the archive entries in the Meilisearch database -- not the DB."
(utils:run-bash-command
(format nil "curl -X DELETE \'~a\'"
(build-search-url "/indexes/nera/documents"))))
(defun create-dump ()
"Creates a dump of the Meilisearch database."
(utils:run-bash-command
(format nil "curl -X POST \'~a\'" (build-search-url "/dumps"))))