aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher R. Nelson <christopher.nelson@languidnights.com>2024-01-17 21:05:37 -0500
committerChristopher R. Nelson <christopher.nelson@languidnights.com>2024-01-21 09:59:03 -0500
commita6721bdd6154e2bebd8ab07bf310c25629347a21 (patch)
tree2b0dad144829f726396b08f09a5eaba3c9b18615
parent2f84ed3f877d97d2327f526ccbe981a6fe3acade (diff)
Add shutdown command, and refactor server impl
zmq: refactor server to functions add shutdown function (end recursion) media: fix bug with missing directories rh-client: support shutdown function rh-server: update to use build variables
-rw-r--r--doc/reading-heap.texi136
-rw-r--r--reading-heap/media.scm2
-rw-r--r--reading-heap/zmq.scm73
-rwxr-xr-xscripts/rh-client.in28
-rwxr-xr-xscripts/rh-server.in16
5 files changed, 205 insertions, 50 deletions
diff --git a/doc/reading-heap.texi b/doc/reading-heap.texi
index 5e2735a..d1f2557 100644
--- a/doc/reading-heap.texi
+++ b/doc/reading-heap.texi
@@ -2,15 +2,15 @@
@c -*-texinfo-*-
@c %**start of header
-@setfilename reading-heap.info
+@setfilename guile-reading-heap.info
@documentencoding UTF-8
-@settitle Reading-Heap Reference Manual
+@settitle Reading Heap Reference Manual
@c %**end of header
@include version.texi
@copying
-Copyright @copyright{} 2023 Christopher R. Nelson
+Copyright @copyright{} 2024 Christopher R. Nelson
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -22,11 +22,11 @@ Documentation License''.
@dircategory The Algorithmic Language Scheme
@direntry
-* Reading-Heap: (reading-heap).
+* Reading Heap: (guile-reading-heap). Manage your heap of to-consume media.
@end direntry
@titlepage
-@title The Reading-Heap Manual
+@title The Guile Reading Heap Manual
@author Christopher R. Nelson
@page
@@ -40,21 +40,133 @@ Edition @value{EDITION} @*
@contents
@c *********************************************************************
-@node Top
-@top Reading-Heap
+@node Top, Introduction, (dir), (dir)
+@top Reading Heap
-This document describes Reading-Heap version @value{VERSION}.
+This document describes Reading Heap version @value{VERSION}.
@menu
-* Introduction:: Why Reading-Heap?
+* Introduction:: What is Reading-Heap?
+* Installation:: How to install Reading-Heap?
+* Quickstart:: Getting Started
+* Client Subcommands:: How to operate the client
+
+* Contributing:: Contributing to the Reading Heap project
+* Acknowledgments:: Thanks!
@end menu
@c *********************************************************************
-@node Introduction
+@node Introduction, Installation, Top, Top
@chapter Introduction
-INTRODUCTION HERE
+What is Reading Heap? It's a @emph{heap} of things you want to
+@emph{read}. Shocking, I know. But what does that mean? Simply, it
+means you add a priority when you put an item on the heap, and when
+you ask the heap what to read next, it will take your priorities into
+account and provide you one of the most important entries as a
+suggestion.
+
+How does this improve on the reading list you have taped to your
+refrigerator? Primarily by removing the cognitive burden on choosing
+what's next. It also lets you specify that, for instance, you have in
+your head you want to read ``Battlefield Earth'', but it's really more
+of a sometime before you die thing. You give it the appropriate
+priority, and it won't clutter your heap when what you really should
+be reading about @uref{https://spritely.institute/hoot, Hoot
+WebAssembly}.
+
+@c *********************************************************************
+@node Installation, Quickstart, Introduction, Top
+@chapter Installation
+
+First, check your favorite package manager. Reading Heap will likely
+not be there, but it's the best way to acquire end-user software and
+should be a first port of call.
+
+If (when) that fails, you can continue with the Guile Autotools build.
+
+@heading Using Autotools
+
+Installing Reading Heap should be as easy as:
+@enumerate
+@item
+Install the dependencies:
+@itemize
+@item
+autoconf
+@item
+automake
+@item
+pkg-config
+@item
+guile
+@item
+texinfo
+@item
+guile-config
+@item
+guile-json
+@item
+guile-simple-zmq
+@item
+zeromq
+@end itemize
+@item
+Run @code{autoreconf -vif && ./configure && make && sudo make install}
+@end enumerate
+
+Exactly how you install the dependencies will depend on your distro.
+While installing Guile libraries using autotools you will need to
+augment the @env{GUILE_LOAD_PATH} and the
+@env{GUILE_LOAD_COMPILED_PATH} environment variables to ensure that
+the installed code will be available to Guile & Guile applications.
+You could accomplish this by adding the following to your shell of
+choice's startup files (for example, .bash_profile or .zshrc)
+
+@example
+
+export GUILE_LOAD_PATH=/usr/local/share/guile/site/3.0/
+export GUILE_LOAD_COMPILED_PATH=/usr/local/lib/guile/3.0/site-ccache/
+export PATH=/usr/local/bin/:$PATH
+
+@end example
-This documentation is a stub.
+@c *********************************************************************
+@node Quickstart, Client Subcommands, Installation, Top
+@chapter Quickstart
+
+To get quickly started, run the command @command{rh-server --write}
+
+@c *********************************************************************
+@node Client Subcommands, Contributing, Quickstart, Top
+@chapter Client Subcommands
+
+Reading Heap is sub-divided into different subcommands designed to achieve
+specific tasks. You can pass the @option{--help} switch to any of the
+subcommands to get concise documentation.
+
+@c *********************************************************************
+@node Contributing, Acknowledgments, Client Subcommands, Top
+@chapter Contributing
+
+Reading Heap is an open project and we actively invite contribution.
+Get in touch with the project on
+@email{christopher.nelson@@languidnights.com} or on the
+@uref{https://codeberg.org/languidnights/reading-heap, the project
+forge page}. The project welcomes ideas, bug reports, patches, or
+feedback.
+
+@c *********************************************************************
+@node Acknowledgments, , Contributing, Top
+@chapter Acknowledgments
+
+Reading Heap would be impossible without the input of various people.
+Much of the technical details were ``borrowed'' from guile-hall and
+guile-config. The
+@uref{https://www.gnu.org/software/guile/manual/index.html, Guile
+Manual} is a quite well-written, if occasionally dense, source of
+information on some of the thornier issues. And
+@uref{https://systemcrafters.net, the System Crafters community}
+helped some confidence issues I was having :-)
@bye
diff --git a/reading-heap/media.scm b/reading-heap/media.scm
index a4ffad4..01d2aab 100644
--- a/reading-heap/media.scm
+++ b/reading-heap/media.scm
@@ -27,6 +27,8 @@
(json->media (call-with-input-file filename get-string-all)))
(define (filetree->media-list dirname)
+ (when (not (access? dirname X_OK))
+ (mkdir dirname))
(define (enter? name stat result)
(not (member (basename name) '(".git" ".svn" "archive"))))
(define (leaf name stat result)
diff --git a/reading-heap/zmq.scm b/reading-heap/zmq.scm
index 65cf60e..9635fad 100644
--- a/reading-heap/zmq.scm
+++ b/reading-heap/zmq.scm
@@ -11,38 +11,61 @@
(define (server-setup sock)
(zmq-bind-socket server-socket sock))
+(define (rh-server-next heap)
+ (cond ((heap-empty? heap)
+ (zmq-send server-socket "no media in queue\n"))
+ (#t (zmq-send server-socket (string-append
+ (media->json (heap-get-min heap))
+ "\n")))))
+
+(define (rh-server-new heap write-location)
+ (zmq-send server-socket "ok\n")
+ (let* ((media-raw (zmq-receive server-socket 1500))
+ (media (json->media media-raw))
+ (heap-new (heap-insert (media-priority media)
+ media
+ heap)))
+ (call-with-output-file (string-append
+ write-location
+ "/"
+ (media-title media))
+ (lambda (port)
+ (display media-raw port)))
+ (zmq-send server-socket (string-append
+ (media-title media)
+ " added\n"))
+ heap-new))
+
+(define (rh-server-consume heap write-location archive-location)
+ (let ((media (cond ((heap-empty? heap) "no media in queue\n")
+ (#t (heap-get-min heap))))
+ (heap-new (cond ((heap-empty? heap) heap)
+ (#t (heap-delete-min heap)))))
+ (when (not (access? archive-location X_OK))
+ (mkdir archive-location))
+ (rename-file (string-append write-location
+ "/"
+ (media-title media))
+ (string-append archive-location
+ "/"
+ (media-title media)))
+ heap-new))
+
(define (rh-receive heap write-location archive-location)
(let ((command (zmq-receive server-socket 1500)))
(cond ((string= command "next")
- (cond ((heap-empty? heap)
- (zmq-send server-socket "no media in queue"))
- (#t (zmq-send server-socket (media->json (heap-get-min heap)))))
+ (rh-server-next heap)
(rh-receive heap write-location archive-location))
((string= command "new")
- (zmq-send server-socket "ok")
- (let* ((media-raw (zmq-receive server-socket 1500))
- (media-data (json->media media-raw))
- (heap-new (heap-insert (media-priority media-data) media-data heap)))
- (call-with-output-file (string-append write-location
- "/"
- (media-title media-data))
- (lambda (port)
- (display media-raw port)))
- (zmq-send server-socket "ok")
+ (let ((heap-new (rh-server-new heap write-location)))
(rh-receive heap-new write-location archive-location)))
((string= command "consume")
- (let ((media (cond ((heap-empty? heap) "no media in queue")
- (#t (heap-get-min heap))))
- (heap-new (cond ((heap-empty? heap) heap)
- (#t (heap-delete-min heap)))))
- (rename-file (string-append write-location
- "/"
- (media-title media))
- (string-append archive-location
- "/"
- (media-title media)))
- (zmq-send server-socket "ok")
- (rh-receive heap-new write-location archive-location))))))
+ (let ((heap-new (rh-server-consume heap write-location archive-location)))
+ (rh-receive heap-new write-location archive-location)))
+ ((string= command "shutdown")
+ (zmq-send server-socket "shutting down rh-server\n"))
+ (#t (rh-server-next heap)
+ (rh-receive heap write-location archive-location)))))
(export rh-receive
server-setup)
diff --git a/scripts/rh-client.in b/scripts/rh-client.in
index 64dfde6..8c96acb 100755
--- a/scripts/rh-client.in
+++ b/scripts/rh-client.in
@@ -1,4 +1,5 @@
-#!/usr/bin/env guile
+#!@GUILE@ \
+--no-auto-compile -e main -s
!#
(use-modules (simple-zmq)
(config)
@@ -28,19 +29,19 @@
(switch
(name 'title)
(synopsis "title of the new media")
- (default "Foundation Trilogy")
+ (default "")
(test string?)
(character #t))
(switch
(name 'author)
(synopsis "author of the new media")
- (default "Isaac Asimov")
+ (default "")
(test string?)
(character #t))
(switch
(name 'location)
(synopsis "location of the new media")
- (default "https://openlibrary.org/books/OL20930675M/The_foundation_trilogy")
+ (default "")
(test string?)
(character #t))
(switch
@@ -62,6 +63,10 @@
(configuration
(name 'consume)
(synopsis "remove the next media from the heap")
+ (wanted '((keywords . (service-socket)))))
+ (configuration
+ (name 'shutdown)
+ (synopsis "shutdown the heap")
(wanted '((keywords . (service-socket)))))))
(directory (list (in-home ".reading-heap/")
(path (given
@@ -70,7 +75,11 @@
"/.config"))
"/reading-heap/"))
(eager? #t))))
- (parser sexp-parser)))
+ (parser sexp-parser)
+ (copyright @COPYRIGHT@)
+ (version @HVERSION@)
+ (license @LICENSE@)
+ (author @AUTHOR@)))
(define context (zmq-create-context))
@@ -78,7 +87,7 @@
(define (client-setup sock)
(zmq-connect client-socket sock))
-
+
(define (rh-client-next)
(zmq-send client-socket "next")
(let ((msg (zmq-receive-bytevector client-socket 1500)))
@@ -96,6 +105,10 @@
(zmq-send client-socket "consume")
(display (zmq-receive client-socket 1500)))
+(define (rh-client-shutdown)
+ (zmq-send client-socket "shutdown")
+ (display (zmq-receive client-socket 1500)))
+
(define (json-from-args priority title author location)
(scm->json-string `(("priority" . ,priority)
("title" . ,title)
@@ -118,6 +131,9 @@
((string=? (cadr (full-command options)) "consume")
(client-setup (option-ref options 'service-socket))
(rh-client-consumed))
+ ((string=? (cadr (full-command options)) "shutdown")
+ (client-setup (option-ref options 'service-socket))
+ (rh-client-shutdown))
(#t (emit-help options)))))
(main (command-line))
diff --git a/scripts/rh-server.in b/scripts/rh-server.in
index 9749ec2..a9dd758 100755
--- a/scripts/rh-server.in
+++ b/scripts/rh-server.in
@@ -1,4 +1,5 @@
-#!/usr/bin/env guile
+#!@GUILE@ \
+--no-auto-compile -e main -s
!#
(use-modules (srfi srfi-1)
(config)
@@ -38,7 +39,7 @@
(character #f))
(switch
(name 'serve)
- (synopsis "server the media heap")
+ (synopsis "serve the media heap")
(default #f)
(test boolean?)
(character #t))
@@ -51,16 +52,17 @@
"/reading-heap/"))
(eager? #t))))
(parser sexp-parser)
- (copyright '(2023))
- (version "0.1")
- (license agpl3+)
- (author "Christopher R. Nelson")))
+ (copyright @COPYRIGHT@)
+ (version @HVERSION@)
+ (license @LICENSE@)
+ (author @AUTHOR@)))
(define (main cmd-line)
(let ((options (getopt-config-auto cmd-line config)))
(when (option-ref options 'write)
(options-write options))
- (when (option-ref options 'serve)
+ (when (or (option-ref options 'serve)
+ (not (option-ref options 'write)))
(let* ((media (filetree->media-list (option-ref options 'media-library)))
(priorities (map media-priority media))
(heap (fold heap-insert 'E priorities media)))