init commit

main
dozens 2023-10-03 13:47:30 -06:00
parent 7c244bf69b
commit 9bb2b1d06c
5 changed files with 243 additions and 1 deletions

View File

@ -1,3 +1,42 @@
# consump
a convoluted pipeline of transformations that creates an html log of tv shows, podcasts, and music from a plain text database.
> it's like goodreads for *x*
CC BY 4.0 2023
## about
a convoluted pipeline of transformations that creates an html log of tv shows, podcasts, and music from a plain text database.
this is what powers <http://tilde.town/~dozens/consume/>
## features
- plain text database!
- ed?
- produces html/css/javascript (js for filtering content type; css for lookin good; html because don't you want to read it??)
- rss feed
## dependencies
- recutils: <https://www.gnu.org/software/recutils/>
- mustache: <https://mustache.github.io/>
- csvjson (csvkit): <https://csvkit.readthedocs.io/>
- jq: <https://stedolan.github.io/jq/>
- (optional) just: <https://github.com/casey/just>
## getting started
1. install dependencies
2. update `templates/feed.mustache` and `templates/html.mustache` to include your own links and information for the generated rss and html. update the `up` recipe in the justfile to put the generated files wherever you want them.
3. run `just new`. or copy the 'new' script from the justfile into a bash file and run it. NOTE: this script runs ed(1), because that's what I like. If you are not familiar with ed(1), change that part of the script to use $EDITOR. If you would *like* to be familiar with ed(1) then check out the links listed below.
4. `just html` and `just rss` will build the html and rss respectively. Again, you can cobble these together from the justfile into a bash script if you don't have/want to install just. `just build` will assemble both the html and the rss.
## resources
- https://elly.town/d/blog/2015-10-03-ed-tutorial.txt
- http://tilde.town/wiki/learn/editors/ed.html
- https://tube.tchncs.de/w/g1ZKSzvDaqbpWQQgxGfW3z

13
db/database.rec 100644
View File

@ -0,0 +1,13 @@
%rec: review
%doc: a review of some media i consumed
%key: id
%unique: id
%type: id int
%type: created date
%type: episode,title line
%typedef: type enum podcast listening watching playing
%auto: id created
%mandatory: title body
%allowed: id created type title episode body
%sort: created

62
justfile 100644
View File

@ -0,0 +1,62 @@
database := "db/database.rec"
# show all commands
default:
just --list --unsorted
# create new entry
new:
#!/usr/bin/env sh
read -p "type (p[o]dcast [l]istening [w]atching [p]laying): " typeshort
read -p "title: " title
read -p "episode? " episode
echo "CAUTION: Incoming ed!"
tmpfile=$(mktemp)
ed "$tmpfile"
body=$(< "$tmpfile")
rm "$tmpfile"
case "$typeshort" in
"o") type="podcast";;
"l") type="listening";;
"w") type="watching";;
"p") type="playing";;
*) echo "Unknown type!"; exit 1;;
esac
recins --verbose -t review \
-f "type" -v "$type" \
-f "title" -v "$title" \
-f "episode" -v "$episode" \
-f "body" -v "$body" \
db/database.rec
# rec -> json
_json:
recsel -S created {{database}} \
| sed -e 's/^body: /body: <p>/' -e 's/^\+ /+ <p>/' -e '/<p>/ s/$/<\/p>/' \
| rec2csv \
| csvjson \
| jq 'reverse \
| map(.body |= gsub("\n"; "\n\n"))' \
| jq '. | { data: . }'
# html
html:
just _json \
| mustache - templates/html.mustache \
> www/index.html
# rss
rss:
just _json \
| mustache - templates/feed.mustache \
> www/feed.xml
# build html and rss
build: html rss
# upload
up:
rsync -azP --exclude=.git www/ tilde:public_html/consume/
# build and upload
all: build up

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>dozens consumes</title>
<link>https://tilde.town/~dozens/consume/index.html</link>
<description>shows movies games podcasts and music</description>
<atom:link rel="self" type="application/rss+xml" href="https://tilde.town/~dozens/consume/feed.xml"/>
{{#data}}
<item>
<title><![CDATA[{{title}}]]></title>
<link>https://tilde.town/~dozens/consume/index.html#{{id}}</link>
<pubDate>{{created}}</pubDate>
<guid>https://tilde.town/~dozens/consume/index.html#{{id}}</guid>
<description>
<![CDATA[
<p>{{created}}</p>
{{#episode}}
<p>Episode: {{.}}</p>
{{/episode}}
{{{body}}}
]]>
</description>
</item>
{{/data}}
</channel>
</rss>

View File

@ -0,0 +1,102 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<link rel="alternate" type="application/rss+xml" href="https://tilde.town/~dozens/consume/feed.xml" title="dozens consumes" />
<title>consump</title>
<style>
body {
max-width: 80ch;
margin: 3rem auto;
line-height: 1.8;
font-size: 20px;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
h1, h2 {
font-family: sans-serif;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
nav a {
color: red;
}
</style>
</head>
<body>
<header>
<nav>
<p>
Filter by:
<a id="filterAll" href="#">All</a> |
<a id="filterWatching" href="#">Watching</a> |
<a id="filterListening" href="#">Listening</a> |
<a id="filterPlaying" href="#">Playing</a> |
<a id="filterPodcast" href="#">Podcast</a>
</p>
</nav>
<h1>All The Media I Consume</h1>
<p><a href="https://www.goodreads.com/user/show/409485-chrisman">except for books</a></p>
<header>
<main>
{{#data}}
<article class={{type}}>
<h2 id="{{id}}">{{title}}</h2>
<p>
<small>
<date>
{{created}}
</date>
{{#episode}}
<span> | Episode: {{.}}</span>
{{/episode}}
</small>
</p>
{{{body}}}
</article>
{{/data}}
</main>
</body>
</html>
<script>
// clicky links
const filterAll = document.querySelector('#filterAll');
const filterWatching = document.querySelector('#filterWatching');
const filterListening = document.querySelector('#filterListening');
const filterPlaying = document.querySelector('#filterPlaying');
const filterPodcast = document.querySelector('#filterPodcast');
// dom nodes
const watching = document.querySelectorAll('.watching')
const listening = document.querySelectorAll('.listening')
const playing = document.querySelectorAll('.playing')
const podcast = document.querySelectorAll('.podcast')
const all = document.querySelectorAll('.watching, .listening, .playing, .podcast')
// event listeners
function hideandshow(fn) {
return function(e) {
e.preventDefault()
all.forEach(x => {
x.style.display = 'none';
})
fn.forEach(x => {
x.style.display = 'block';
})
}
}
filterAll.addEventListener('click', hideandshow(all))
filterWatching.addEventListener('click', hideandshow(watching))
filterListening.addEventListener('click', hideandshow(listening))
filterPlaying.addEventListener('click', hideandshow(playing))
filterPodcast.addEventListener('click', hideandshow(podcast))
</script>