Demeter release 0.1.0!

https://nyxt.atlas.engineer/article/demeter-release-0.1.0.org

2 Likes

Oh wow, that’s cool! I didnt know about Demeter (I went offline for 2 months). That made me recall about the store. Very nice t-shirts btw. I’ll have to get a few of those. Any documentation about Demeter? Mostly to learn about Demeter functions. From that screenshot seems like theres no unread feeds total number. Neither how many unread feeds there is for each feed. I dont know if the screenshot is up-to-date with current version. But real quick, I could see the total number been displayed where <no url/name> is instead. Im just trowing that around. Note that I havent tested Demeter yet either. Interesting project tho nice to see that it is alive.

Thanks for the kind words!

No documentation outside of the built-in documentation yet!

We don’t keep track yet of read/unread things. Do you think this would be a good feature to have?

Do you think this would be a good feature to have?

Yes indeed. I know the Source code is provided with the purchase. But unfortunately, I cant do it. I cant code any common-lisp. I barely can implement a function in e-lisp. So ya, someone else will have to implement that. Total unread number is a must have, that's for sure. And Thanks again for Nyxt!

1 Like

When I did not have that many feeds, I found both “how many unread items per feed” and “total unread number” to be helpful. Now that I followed some mailing lists with somewhat large volume, they still help estimate how much I read…

Excited about the update! :heart: :grin:

When I try to run with the new download, I see the following error:

Component #:CL-FAD not found, required by
#<SYSTEM "montezuma">

Am I missing something?

PS: Might be useful to tag this thread with the demeter category if possible.

Hm, that is odd, what version of Nyxt are you using? One from the 2-series?

I’m running Nyxt 2.2.3. Here’s the full backtrace, in case it’s helpful:

Error occured:

Could not load the init file: Component #:CL-FAD not found, required by
                              #<SYSTEM "montezuma">


Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1001178103}>
0: ((LAMBDA NIL :IN UIOP/IMAGE:PRINT-BACKTRACE))
1: ((FLET "THUNK" :IN UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX))
2: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #<FUNCTION (FLET "THUNK" :IN UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX) {7F0DCCE6CFDB}>)
3: (UIOP/STREAM:CALL-WITH-SAFE-IO-SYNTAX #<FUNCTION (LAMBDA NIL :IN UIOP/IMAGE:PRINT-BACKTRACE) {100920821B}> :PACKAGE :CL)
4: ((FLET "H0" :IN NYXT::LOAD-LISP) Component #:CL-FAD not found, required by #<SYSTEM "montezuma">)
5: (SB-KERNEL::%SIGNAL Component #:CL-FAD not found, required by #<SYSTEM "montezuma">)
6: (ERROR ASDF/FIND-COMPONENT:MISSING-DEPENDENCY :REQUIRED-BY #<ASDF/SYSTEM:SYSTEM "montezuma"> :REQUIRES #:CL-FAD)
7: (ASDF/FIND-COMPONENT:RESOLVE-DEPENDENCY-NAME #<ASDF/SYSTEM:SYSTEM "montezuma"> #:CL-FAD NIL)
8: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/SYSTEM:SYSTEM "montezuma"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {100920760B}>)
9: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
10: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
11: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/SYSTEM:SYSTEM "montezuma"> T)
12: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/COMPONENT:MODULE "montezuma" "src"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {100920721B}>)
13: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
14: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
15: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/COMPONENT:MODULE "montezuma" "src"> T)
16: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "montezuma" "src" "package"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {1009206E0B}>)
17: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
18: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
19: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "montezuma" "src" "package"> T)
20: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "montezuma" "src" "package"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {10092069CB}>)
21: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
22: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
23: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "montezuma" "src" "package"> T)
24: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/COMPONENT:MODULE "montezuma" "src"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {100920657B}>)
25: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
26: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
27: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/COMPONENT:MODULE "montezuma" "src"> T)
28: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "montezuma"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {10092060EB}>)
29: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
30: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
31: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "montezuma"> T)
32: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/SYSTEM:SYSTEM "demeter"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {1008EACE2B}>)
33: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
34: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
35: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/SYSTEM:SYSTEM "demeter"> T)
36: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "demeter" "package"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {1008EAC4FB}>)
37: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
38: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
39: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:PREPARE-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "demeter" "package"> T)
40: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "demeter" "package"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {1008EABF5B}>)
41: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
42: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
43: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "demeter" "package"> T)
44: (ASDF/PLAN:MAP-DIRECT-DEPENDENCIES #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "demeter"> #<FUNCTION (LAMBDA (ASDF/PLAN::O ASDF/PLAN::C) :IN ASDF/PLAN:TRAVERSE-ACTION) {1008EABB2B}>)
45: ((LAMBDA NIL :IN ASDF/PLAN:TRAVERSE-ACTION))
46: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
47: (ASDF/PLAN:TRAVERSE-ACTION #<ASDF/PLAN:SEQUENTIAL-PLAN {1008EAB883}> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "demeter"> T)
48: ((LAMBDA NIL :IN ASDF/PLAN:MAKE-PLAN))
49: ((:METHOD ASDF/OPERATE:OPERATE (ASDF/OPERATION:OPERATION ASDF/COMPONENT:COMPONENT)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "demeter"> :PLAN-CLASS NIL :PLAN-OPTIONS NIL) [fast-method]
50: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "demeter">)
51: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
52: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "demeter">) [fast-method]
53: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> ASDF/LISP-ACTION:LOAD-OP :DEMETER)
54: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
55: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) ASDF/LISP-ACTION:LOAD-OP :DEMETER) [fast-method]
56: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<FUNCTION (LAMBDA NIL :IN ASDF/OPERATE:OPERATE) {100893D41B}> :OVERRIDE T :KEY NIL :OVERRIDE-CACHE T :OVERRIDE-FORCING NIL)
57: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
58: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<FUNCTION (LAMBDA NIL :IN ASDF/OPERATE:OPERATE) {100893C38B}> :OVERRIDE NIL :KEY NIL :OVERRIDE-CACHE NIL :OVERRIDE-FORCING NIL)
59: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) ASDF/LISP-ACTION:LOAD-OP :DEMETER) [fast-method]
60: (ASDF/OPERATE:LOAD-SYSTEM :DEMETER)
61: (SB-INT:SIMPLE-EVAL-IN-LEXENV (ASDF/OPERATE:LOAD-SYSTEM :DEMETER) #<NULL-LEXENV>)
62: (SB-EXT:EVAL-TLF (ASDF/OPERATE:LOAD-SYSTEM :DEMETER) 0 NIL)
63: ((LABELS SB-FASL::EVAL-FORM :IN SB-INT:LOAD-AS-SOURCE) (ASDF/OPERATE:LOAD-SYSTEM :DEMETER) 0)
64: ((LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) (ASDF/OPERATE:LOAD-SYSTEM :DEMETER) :CURRENT-INDEX 0)
65: (SB-C::%DO-FORMS-FROM-INFO #<FUNCTION (LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) {100893BEAB}> #<SB-C::SOURCE-INFO {100893BE73}> SB-C::INPUT-ERROR-IN-LOAD)
66: (SB-INT:LOAD-AS-SOURCE #<SB-INT:FORM-TRACKING-STREAM for "file /home/siva/.config/nyxt/init.lisp" {100893A8E3}> :VERBOSE NIL :PRINT NIL :CONTEXT "loading")
67: ((LABELS SB-FASL::LOAD-STREAM-1 :IN LOAD) #<SB-INT:FORM-TRACKING-STREAM for "file /home/siva/.config/nyxt/init.lisp" {100893A8E3}> NIL)
68: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<FUNCTION (LABELS SB-FASL::LOAD-STREAM-1 :IN LOAD) {7F0DCCE6F87B}> #<SB-INT:FORM-TRACKING-STREAM for "file /home/siva/.config/nyxt/init.lisp" {100893A8E3}> NIL #<SB-INT:FORM-TRACKING-STREAM for "file /home/siva/.config/nyxt/init.lisp" {100893A8E3}>)
69: (LOAD "/home/siva/.config/nyxt/init.lisp" :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :DEFAULT)
70: ((FLET NYXT::UNSAFE-LOAD :IN NYXT::LOAD-LISP))
71: (NYXT::LOAD-LISP "/home/siva/.config/nyxt/init.lisp" :PACKAGE #<PACKAGE "NYXT-USER">)
72: (NYXT::START-BROWSER NIL)
73: (NYXT:START :URLS NIL)
74: ((LAMBDA NIL :IN UIOP/IMAGE:RESTORE-IMAGE))
75: (UIOP/IMAGE:CALL-WITH-FATAL-CONDITION-HANDLER #<FUNCTION (LAMBDA NIL :IN UIOP/IMAGE:RESTORE-IMAGE) {100671BB8B}>)
76: ((FLET SB-UNIX::BODY :IN SB-IMPL::START-LISP))
77: ((FLET "WITHOUT-INTERRUPTS-BODY-1" :IN SB-IMPL::START-LISP))
78: (SB-IMPL::START-LISP)

Indeed it seems that montezuma requires cl-fad and that is not included in Nyxt 2.2.3!

I’ve now added it to the submodules, you can also do this yourself if you desire, but if you redownload, hopefully it will now work for you! (without needing QuickLisp or any other source to fetch cl-fad!).

Thank you for the report :slight_smile:

2 Likes

OPML import sounds great - I could finally read all my 50 feeds in Nyxt! But for now it doesn’t work: import-feeds-from-opml complains that NYXT::PROMPT1 is not defined.

I also tried calling import-feeds-from-opml via Sly, providing the OPML as an optional argument. That opens a prompt in Nyxt and waits for me to fill in an URL. No idea what I am supposed to type there!

I’m sorry, I was using latest master when testing Demeter and I did not realize prompt1 does not exist on the 2-series branch. I will push a fix shortly!

2 Likes

I just pushed a fix that removes prompt1. I also tested on the 2-series branch. It should now officially work! Thanks again for the invaluable reporting! Please re-download.

P.S. in case you are curious, the macro does just this:
Instead of (first (prompt ... )) you could just do (prompt1 ...).

2 Likes

Thanks for fixing this! My problem has evolved :wink:

With the current version, I still cannot do import-feeds-from-opml in Nyxt because it doesn’t show my file in the directory listing. Which makes me wonder if .opml.xml is the right type of file!

That doubt didn’t stop me from trying

(demeter::import-feeds-from-opml :opml-file "/home/hinsen/Downloads/feeds_2022-01-04.opml.xml")

from Sly. That pops up an input prompt in Nyxt, asking me for the title of a feed. I guess that’s not what should happen.

Your file type is correct, it is an XML file. The extension we currently match in the prompt is .opml though. I guess some readers write it as .xml, so I’ve added support for that as well! You can re-download it if you like, or just change your file extension to .opml.

With regards to why Nyxt is asking you for the title of a feed, if you have an entry that doesn’t contain a title as exported by your feed reader, then Nyxt will ask you for the title (the same goes for URLs). If Nyxt is erroneously parsing your OPML file, you can also just hit ESC to cancel the prompt buffer for any given entry, it will still process all the rest of the entries in the OPML file.

Thank you so much for your feedback :slight_smile:

Lastly, I think we should set-up some sort of mechanism that can just redownload the tar.gz and replace it in place, that would probably be useful (with user confirmation prompts of course!). It would certainly make updating a lot easier!

Thanks for the info! Renaming to .opml works just fine.

The entries in my feed file (export from FreshRSS) look like this:

      <outline text="emacs-news" type="rss" xmlUrl="https://sachachua.com/blog/category/emacs-news/feed/" htmlUrl="https://sachachua.com/blog/wp-json/wp/v2/categories/1177" description="Emacs, sketches, and life"/>

There is nothing called “title” anywhere, the appropriate-looking field is called “text”. Are there perhaps different OPML formats?

Finally, a UX issue: if Nyxt asks me for a title during an import, it should at least show me some hint at which entry the title is for!

Yes, there indeed should be an indication for which element it is asking the title for. I’ll have to think about how to solve that from a UX perspective without an excessively long prompt!

IMHO: If someone has enough feeds to use an OPML, adding metadata manually through Nyxt (for multiple entries) is likely to get tedious. I think that the key need (from a UX perspective) is to receive feedback on which entries aren’t successfully/cleanly imported (and specifying the expected format), so one could fix them — either in the OPML file, or in a place where Nyxt stores data about the RSS feeds.