atlas-engineer / nfiles

User configuration and data file management
BSD 3-Clause "New" or "Revised" License
18 stars 5 forks source link

Allow providing content and raw content on file initialization #27

Open aartaka opened 1 year ago

aartaka commented 1 year ago

This way, the user can override file contents while still having most of Nfiles benefits like file fetching, caching, smart parsing (in case they only provided raw contents). In particular, allowing to pass contents will simplify user scripts and blocker hostlists in Nyxt. Dramatically.

aartaka commented 1 year ago

See https://github.com/atlas-engineer/nyxt/issues/3248 and https://github.com/aartaka/nx-dark-reader as the place where the user script code is provided on initialization.

Ambrevar commented 11 months ago

Can you give an example of what you have in mind?

A specialization of read-file seems to do what you want, no?

aartaka commented 11 months ago

A specialization of read-file seems to do what you want, no?

That's the problem: one has to define a method just to have custom contents for the file. This is especially problematic with user-facing configuration.


Here's how we currently handle blocker-mode hostlist in Nyxt. We define the class with a slot representing the contents of the file and poorly mimicking file management that Nfiles provides natively:

(define-class hostlist (files:data-file nyxt-remote-file)
  ((hosts
    '()
    :type (or (cons string *) null)
    :documentation "List of hosts to ignore.
This is useful to reference hosts manually instead of via `nfiles:url'.")
   #| ... |#)
  #| ... |#)

(defmethod hosts :around ((hostlist hostlist))
  (or (call-next-method)
      (let ((path (files:expand hostlist)))
        (unless (uiop:file-exists-p path)
          (echo "Updating hostlist ~s..." path))
        (setf (slot-value hostlist 'hosts)
              (files:content hostlist
                             :force-update (not (uiop:file-exists-p path)))))))

Then, when the user configures it, they have to provide hosts. And they have to provide it as this custom slot value.

(defvar *my-blocked-hosts*
  (nyxt/mode/blocker:make-hostlist
   :hosts '("platform.twitter.com"
            "syndication.twitter.com"
            "m.media-amazon.com")))

It will simplify the design a lot if Nfiles allowed to provide contents at initialization. This way, one doesn't have to add proxy slots and has automatic (de)serialization, caching etc.

With such a change, hostlist initialization would look like:

(defvar *my-blocked-hosts*
  (nyxt/mode/blocker:make-hostlist
   :content '("platform.twitter.com"
              "syndication.twitter.com"
              "m.media-amazon.com")))

And the use of the hostlist would turn into a simple nfiles:content call instead of this proxy slot access.