<commit_before>(uiop:define-package :next/blocker-mode
  (:use :common-lisp :trivia :next)
  (:documentation "Block resource queries blacklisted hosts."))
(in-package :next/blocker-mode)
(eval-when (:compile-toplevel :load-toplevel :execute)
  (trivial-package-local-nicknames:add-package-local-nickname :alex :alexandria)
  (trivial-package-local-nicknames:add-package-local-nickname :sera :serapeum))

;; TODO: Add convenient interface to block hosts depending on the current URL.

(defclass-export hostlist ()
  ((url :accessor url :initarg :url
        :initform nil
        :type string
        :documentation "URL where to download the list from.  If nil, no attempt
will be made at updating it.")
   (path :accessor path :initarg :path
         :initform nil
         :documentation "Where to find the list locally.
If nil, the list won't be persisted.
If path is relative, it will be set to (xdg-data-home path).")
   (hosts :accessor hosts :initarg :hosts
          :initform '()
          :documentation "The list of domain name.")
   (update-interval :accessor update-interval :initarg :update-interval
                    :initform (* 60 60 24)
                    :documentation "If URL is provided, update the list after
this amount of seconds.")))

(serapeum:export-always 'path)
(defmethod path ((hostlist hostlist))
  (with-slots (path) hostlist
    (if (uiop:absolute-pathname-p path)
        path
        (xdg-data-home path))))

(serapeum:export-always 'make-hostlist)
(defun make-hostlist (&rest args)
  (apply #'make-instance 'hostlist args))

(defmethod update ((hostlist hostlist))
  "Fetch HOSTLIST and return it.
If HOSTLIST has a `path', persist it locally."
  (when (url hostlist)
    (echo "Updating hostlist ~a from ~a" (path hostlist) (url hostlist))
    (let ((hosts (dex:get (url hostlist))))
      (when (path hostlist)
        ;; TODO: In general, we should do more error checking when writing to disk.
        (alex:write-string-into-file hosts (path hostlist)
                                           :if-exists :overwrite
                                           :if-does-not-exist :create))
      hosts)))

(defmethod load-to-memory ((hostlist hostlist))
  "Load hostlist.
Auto-update file if older than UPDATE-INTERVAL seconds."
  (if (and (uiop:file-exists-p (path hostlist))<commit_msg>blocker-mode: Fix URL initform type in hostlist class.<commit_after>(uiop:define-package :next/blocker-mode
  (:use :common-lisp :trivia :next)
  (:documentation "Block resource queries blacklisted hosts."))
(in-package :next/blocker-mode)
(eval-when (:compile-toplevel :load-toplevel :execute)
  (trivial-package-local-nicknames:add-package-local-nickname :alex :alexandria)
  (trivial-package-local-nicknames:add-package-local-nickname :sera :serapeum))

;; TODO: Add convenient interface to block hosts depending on the current URL.

(defclass-export hostlist ()
  ((url :accessor url :initarg :url
        :initform ""
        :type string
        :documentation "URL where to download the list from.  If empty, no attempt
will be made at updating it.")
   (path :accessor path :initarg :path
         :initform nil
         :documentation "Where to find the list locally.
If nil, the list won't be persisted.
If path is relative, it will be set to (xdg-data-home path).")
   (hosts :accessor hosts :initarg :hosts
          :initform '()
          :documentation "The list of domain name.")
   (update-interval :accessor update-interval :initarg :update-interval
                    :initform (* 60 60 24)
                    :documentation "If URL is provided, update the list after
this amount of seconds.")))

(serapeum:export-always 'path)
(defmethod path ((hostlist hostlist))
  (with-slots (path) hostlist
    (if (uiop:absolute-pathname-p path)
        path
        (xdg-data-home path))))

(serapeum:export-always 'make-hostlist)
(defun make-hostlist (&rest args)
  (apply #'make-instance 'hostlist args))

(defmethod update ((hostlist hostlist))
  "Fetch HOSTLIST and return it.
If HOSTLIST has a `path', persist it locally."
  (unless (uiop:emptyp (url hostlist))
    (echo "Updating hostlist ~a from ~a" (path hostlist) (url hostlist))
    (let ((hosts (dex:get (url hostlist))))
      (when (path hostlist)
        ;; TODO: In general, we should do more error checking when writing to disk.
        (alex:write-string-into-file hosts (path hostlist)
                                           :if-exists :overwrite
                                           :if-does-not-exist :create))
      hosts)))

(defmethod load-to-memory ((hostlist hostlist))
  "Load hostlist.
Auto-update file if older than UPDATE-INTERVAL seconds."
  (if (and (uiop:file-exists-p (path hostlist))
{'fraction_non_alphanumeric': 0.11351122405760271, 'fraction_numerical': 0.0025412960609911056, 'mean_word_length': 2.9991532599491957, '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': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '85489', 'n_tokens_mistral': 1443, 'n_tokens_neox': 1381, 'n_words': 474}