init commit
parent
7c244bf69b
commit
9bb2b1d06c
39
README.md
39
README.md
|
@ -1,3 +1,42 @@
|
||||||
# consump
|
# consump
|
||||||
|
|
||||||
|
> 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.
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue