<commit_before>(defpackage :wookie-plugin
  (:use :cl :wookie)
  (:export :register-plugin
           :set-plugin-request-data
           :get-plugin-request-data
           :*plugin-folders*
           :*enabled-plugins*
           :load-plugins)
  (:import-from :wookie))
(in-package :wookie-plugin)

(defvar *plugins* nil
  "A hash table holding all registered Wookie plugins.")
(defvar *plugin-config* nil
  "A hash table holding configuration values for all plugins.")
(defvar *plugin-folders* '("./wookie-plugins/")
  "A list of directories where Wookie plugins can be found.")
(defvar *enabled-plugins* nil
  "A list of (keyword) names of enabled plugins.")

(defun register-plugin (plugin-name meta init-function unload-function)
  "Register a plugin in the Wookie plugin system. Generally this is called from
   a plugin.lisp file, but can also be called elsewhere in the plugin. The
   plugin-name argument must be a unique keyword, meta is a plist of information
   about the plugin (name, author, description, etc), and init-fn is the
   initialization function called that loads the plugin (called only once, on
   register)."
  (when (find plugin-name *enabled-plugins*)
    (setf (gethash plugin-name *plugins*)
          (list :name plugin-name :meta meta :unload-function unload-function))
    (funcall init-function)))

(defun unload-plugin (plugin-name)
  "Unload a plugin from the wookie system. If it's currently registered, its
   unload-function will be called."
  (let ((plugin (gethash plugin-name *plugins*)))
    (when plugin
      (funcall (getf plugin :unload-function (lambda ())))
      (remhash plugin-name *plugins*))))

(defun plugin-config (plugin-name)
  "Return the configuration for a plugin. Setfable."
  (unless (hash-table-p *plugin-config*)
    (setf *plugin-config* (make-hash-table :test #'eq)))
  (gethash plugin-name *plugin-config*))

(defun (setf plugin-config) (config plugin-name)
  "Allow setting of plugin configuration via setf."
  (unless (hash-table-p *plugin-config*)
    (setf *plugin-config* (make-hash-table :test #'eq)))
  (setf (gethash plugin-name *plugin-config*) config))

(defun set-plugin-request-data (plugin-name request data)
  "When a plugin wants to store data available to the main app, it can do so by
   storing the data into the request's plugin data. This function allows this by
   taking the plugin-name (keyword), request object passed into the route, and
   the data to store."
  (unless (hash-table-p (request-plugin-data request))<commit_msg>plugins that are loaded/registered cannot be re-loaded until unload-plugin is called on them. load-plugins unloads all plugins before loading the existing ones. this makes it so that the first folders on the *plugin-folders* list are preferential. for isntance, if the :session plugin is loaded from the first folder in that list, then a second :session plugin is encountered, the second will be ignored when it tries to register itself because the first has already loaded.<commit_after>(defpackage :wookie-plugin
  (:use :cl :wookie)
  (:export :register-plugin
           :set-plugin-request-data
           :get-plugin-request-data
           :*plugin-folders*
           :*enabled-plugins*
           :load-plugins)
  (:import-from :wookie))
(in-package :wookie-plugin)

(defvar *plugins* nil
  "A hash table holding all registered Wookie plugins.")
(defvar *plugin-config* nil
  "A hash table holding configuration values for all plugins.")
(defvar *plugin-folders* '("./wookie-plugins/")
  "A list of directories where Wookie plugins can be found.")
(defvar *enabled-plugins* nil
  "A list of (keyword) names of enabled plugins.")

(defun register-plugin (plugin-name meta init-function unload-function)
  "Register a plugin in the Wookie plugin system. Generally this is called from
   a plugin.lisp file, but can also be called elsewhere in the plugin. The
   plugin-name argument must be a unique keyword, meta is a plist of information
   about the plugin (name, author, description, etc), and init-fn is the
   initialization function called that loads the plugin (called only once, on
   register)."
  (when (and (find plugin-name *enabled-plugins*)    ; make sure it's enabled
             (not (gethash plugin-name *plugins*)))  ; make sure it's not loaded already
    (setf (gethash plugin-name *plugins*)
          (list :name plugin-name :meta meta :unload-function unload-function))
    (funcall init-function)))

(defun unload-plugin (plugin-name)
  "Unload a plugin from the wookie system. If it's currently registered, its
   unload-function will be called."
  (let ((plugin (gethash plugin-name *plugins*)))
    (when plugin
      (funcall (getf plugin :unload-function (lambda ())))
      (remhash plugin-name *plugins*))))

(defun plugin-config (plugin-name)
  "Return the configuration for a plugin. Setfable."
  (unless (hash-table-p *plugin-config*)
    (setf *plugin-config* (make-hash-table :test #'eq)))
  (gethash plugin-name *plugin-config*))

(defun (setf plugin-config) (config plugin-name)
  "Allow setting of plugin configuration via setf."
  (unless (hash-table-p *plugin-config*)
    (setf *plugin-config* (make-hash-table :test #'eq)))
  (setf (gethash plugin-name *plugin-config*) config))

(defun set-plugin-request-data (plugin-name request data)
  "When a plugin wants to store data available to the main app, it can do so by
   storing the data into the request's plugin data. This function allows this by
   taking the plugin-name (keyword), request object passed into the route, and
   the data to store."
  (unless (hash-table-p (request-plugin-data request))
{'fraction_non_alphanumeric': 0.10637542177233174, 'fraction_numerical': 0.0, 'mean_word_length': 3.7447346251053073, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4347370', 'n_tokens_mistral': 1631, 'n_tokens_neox': 1611, 'n_words': 653}