commit f6e42dd2b26c6498d643e5355ef2cc72d0b3123f
parent 0b17126aefc21910030d8d5572d9b60aa7df3917
Author: mtmn <miro@haravara.org>
Date: Fri, 10 Apr 2026 12:33:16 +0200
feat: add miniflux
Diffstat:
10 files changed, 452 insertions(+), 0 deletions(-)
diff --git a/flake.nix b/flake.nix
@@ -167,6 +167,7 @@
harmonia = import ./modules/services/harmonia.nix;
attic = import ./modules/services/attic.nix;
static = import ./modules/services/static.nix;
+ miniflux = import ./modules/services/miniflux.nix;
};
deploy = {
diff --git a/hosts/nixaran/configuration.nix b/hosts/nixaran/configuration.nix
Binary files differ.
diff --git a/modules/mixins/dotfiles/bin/_amen-or-not b/modules/mixins/dotfiles/bin/_amen
diff --git a/modules/mixins/dotfiles/config/newsraft/hack/cleanup b/modules/mixins/dotfiles/config/newsraft/hack/cleanup
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+MINIFLUX_URL="$(pass show miniflux-url)"
+MINIFLUX_TOKEN=$(pass show miniflux-token)
+
+curl -s -H "X-Auth-Token: $MINIFLUX_TOKEN" "$MINIFLUX_URL/v1/feeds" |
+ jq -r '.[].id' |
+ xargs -P 10 -I {} curl -s -X DELETE -H "X-Auth-Token: $MINIFLUX_TOKEN" "$MINIFLUX_URL/v1/feeds/{}"
+
+echo "Done"
diff --git a/modules/mixins/dotfiles/config/newsraft/hack/fix_titles b/modules/mixins/dotfiles/config/newsraft/hack/fix_titles
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+import json
+
+c = json.load(open('hack/titles.json'))
+for k, v in c.items():
+ if not v and '?' in k:
+ c[k] = k.split('=')[-1]
+json.dump(c, open('titles.json', 'w'), indent=2, ensure_ascii=False)
diff --git a/modules/mixins/dotfiles/config/newsraft/hack/sync b/modules/mixins/dotfiles/config/newsraft/hack/sync
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+import json
+import re
+import subprocess
+import sys
+import xml.etree.ElementTree as ET
+from pathlib import Path
+from typing import cast
+from urllib.request import Request, urlopen
+from urllib.error import URLError, HTTPError
+
+FEEDS_FILE = Path('feeds')
+CACHE_FILE = Path('hack/titles.json')
+
+MINIFLUX_URL = subprocess.check_output(
+ ['pass', 'show', 'miniflux-url'], text=True
+).strip()
+MINIFLUX_TOKEN = subprocess.check_output(
+ ['pass', 'show', 'miniflux-token'], text=True
+).strip()
+
+cache: dict[str, str] = (
+ json.loads(CACHE_FILE.read_text()) if CACHE_FILE.exists() else {}
+)
+
+
+def fetch_title(url: str) -> str:
+ if url in cache:
+ return cache[url]
+ try:
+ req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
+ with urlopen(req, timeout=10) as response:
+ content_type = (
+ response.headers.get_content_charset() or 'utf-8'
+ )
+ html = cast(bytes, response.read()).decode(
+ content_type, errors='ignore'
+ )
+ match = re.search(r'<title>([^<]+)</title>', html, re.IGNORECASE)
+ if match:
+ cache[url] = match.group(1).strip()
+ return cache[url]
+ except Exception:
+ pass
+ cache[url] = ''
+ return ''
+
+
+root = ET.Element('opml', version='1.0')
+body = ET.SubElement(root, 'body')
+outline = body
+
+for line in FEEDS_FILE.read_text().splitlines():
+ if not (line := line.strip()):
+ continue
+
+ if line.startswith('@'):
+ name = line.split('<')[0].replace('@', '').strip()
+ outline = ET.SubElement(body, 'outline', text=name, title=name)
+ elif line.startswith('http'):
+ url, _, title = line.partition(' ')
+ url = url.strip()
+ title = title.strip() or fetch_title(url)
+
+ if outline == body:
+ outline = ET.SubElement(
+ body, 'outline', text='Uncategorized', title='Uncategorized'
+ )
+
+ elem = ET.SubElement(outline, 'outline', type='rss', xmlUrl=url)
+ if title:
+ elem.set('text', title)
+ elem.set('title', title)
+
+ET.indent(root, space=' ')
+opml_data = cast(bytes, ET.tostring(root, encoding='utf-8', xml_declaration=True))
+
+req = Request(f"{MINIFLUX_URL}/v1/import", data=opml_data, method='POST')
+req.add_header('X-Auth-Token', MINIFLUX_TOKEN)
+req.add_header('Content-Type', 'application/xml')
+
+try:
+ urlopen(req)
+ print('Done')
+except HTTPError as e:
+ print(f"HTTP Error {e.code}", file=sys.stderr)
+except URLError as e:
+ print(f"URL Error: {e.reason}", file=sys.stderr)
+finally:
+ _ = CACHE_FILE.write_text(json.dumps(cache, indent=2, ensure_ascii=False))
diff --git a/modules/mixins/dotfiles/config/newsraft/hack/titles.json b/modules/mixins/dotfiles/config/newsraft/hack/titles.json
@@ -0,0 +1,308 @@
+{
+ "https://amy.is-a.dev/feed.xml": "amy's blog",
+ "https://apenwarr.ca/log/rss.php": "apenwarr",
+ "https://anirudh.fi/blog/feed.xml": "Anirudh Oppiliappan",
+ "https://eli.thegreenplace.net/feeds/all.atom.xml": "Eli Bendersky",
+ "https://brandur.org/articles.atom": "brandur.org",
+ "https://lemire.me/blog/feed/": "Daniel Lemire",
+ "https://computer.rip/rss.xml": "computers are bad",
+ "https://interrupt.memfault.com/feed.xml": "Interrupt",
+ "https://destevez.net/feed": "Daniel EstΓ©vez",
+ "https://ploum.net/atom_en.xml": "Lionel Dricot",
+ "https://fgiesen.wordpress.com/feed": "The ryg blog",
+ "https://jessitron.com/blog/feed": "Jessitron",
+ "https://tratt.net/laurie/news.rss": "Laurence Tratt",
+ "https://www.argmin.net/feed": "arg min",
+ "https://simblob.blogspot.com/feeds/posts/default": "Red Blob Games",
+ "https://huyenchip.com/feed.xml": "Chip Huyen",
+ "https://www.blogger.com/feeds/593563533834706486/posts/default": "",
+ "https://rachelbythebay.com/w/atom.xml": "",
+ "https://utcc.utoronto.ca/~cks/space/blog/?atom": "Wandering Thoughts: Your feed reader has a problem",
+ "https://drewdevault.com/blog/index.xml": "Drew DeVault",
+ "https://leahneukirchen.org/trivium/index.atom": "Leah Neukirchen",
+ "https://endler.dev/rss.xml": "Matthias Endler",
+ "https://vermaden.wordpress.com/feed": "ππππππππ",
+ "https://dataswamp.org/~solene/rss.xml": "Solene",
+ "https://backreaction.blogspot.com/feeds/posts/default": "Sabine Hossenfelder",
+ "https://www.marginalia.nu/index.xml": "marginalia.nu",
+ "https://bugwhisperer.dev/atom.xml": "Andie Keller",
+ "https://fasterthanli.me/index.xml": "fasterthanli.me",
+ "https://oddlama.org/rss.xml": "oddlama's blog",
+ "https://www.openmymind.net/atom.xml": "openmymind.net",
+ "https://arpozine.substack.com/feed": "Call Super's ARPOZINE",
+ "https://brittap.substack.com/feed": "BrittaRiffindots",
+ "https://herbsundays.substack.com/feed": "Herb Sundays",
+ "https://hypertextgarden.com/feed": "Hypertext Garden",
+ "https://infinitespeeds.substack.com/feed": "Infinite Speeds",
+ "https://journalofthemotherbeat.substack.com/feed": "Journal of the Motherbeat",
+ "https://linenoise.substack.com/feed": "Line Noise",
+ "https://naturalmusic.substack.com/feed": "Natural Music",
+ "https://networknotes.motiveunknown.com/feed": "Network Notes",
+ "https://noisenarrative.substack.com/feed": "Noise Narrative",
+ "https://outersignals.substack.com/feed": "Outer Signals",
+ "https://penelopetrappes.substack.com/feed": "My Requiem",
+ "https://plus.briantylercohen.com/feed": "Brian Tyler Cohen",
+ "https://politicsdancingxyz.substack.com/feed": "The Politics of Dancing",
+ "https://ravenewworld.substack.com/feed": "Rave New World",
+ "https://registerspill.thorstenball.com/feed": "Register Spill",
+ "https://resobscura.substack.com/feed": "Res Obscura",
+ "https://robertchristgau.substack.com/feed": "And It Don't Stop",
+ "https://robwalker.substack.com/feed": "The Art of Noticing",
+ "https://samkriss.substack.com/feed": "Numb at the Lodge",
+ "https://smallpotatoes.paulbloom.net/feed": "Small Potatoes",
+ "https://theanarchistgardenersclub.substack.com/feed": "The Anarchist Gardeners Club",
+ "https://thediscovertab.substack.com/feed": "The Discover Tab",
+ "https://thisweekinsound.disquiet.com/feed": "This Week in Sound",
+ "https://toneglow.substack.com/feed": "Tone Glow",
+ "https://tropicalwaste.substack.com/feed": "Waste Mail",
+ "https://www.astralcodexten.com/feed": "Astral Codex Ten",
+ "https://www.cantgetmuchhigher.com/feed": "Can't Get Much Higher",
+ "https://www.computerenhance.com/feed": "Computer, Enhance!",
+ "https://www.cremieux.xyz/feed": "Cremieux Recueil",
+ "https://www.experimental-history.com/feed": "Experimental History",
+ "https://www.statsignificant.com/feed": "Stat Significant",
+ "https://lwn.net/headlines/rss": "LWN.net",
+ "https://www.theregister.com/headlines.atom": "The Register",
+ "https://www.phoronix.com/rss.php": "Phoronix",
+ "https://undeadly.org/cgi?action=rss": "OpenBSD Journal",
+ "https://www.rfc-editor.org/rfcrss.xml": "Recent RFCs",
+ "https://feeds.simplecast.com/L9810DOa": "Signals and Threads",
+ "https://feeds.transistor.fm/oxide-and-friends": "Oxide and Friends",
+ "https://www.twoscomplement.org/podcast/feed.xml": "Two's Complement",
+ "https://feeds.simplecast.com/BqbsxVfO": "99% Invisible",
+ "https://podcasts.files.bbci.co.uk/b006qykl.rss": "In Our Time",
+ "https://feeds.megaphone.fm/GLT4787413333": "The Rest Is History",
+ "https://bikeshedpod.com/rss.xml": "The Bikeshed Pod",
+ "http://feeds.libsyn.com/499093/rss": "FLOSS Weekly",
+ "https://omny.fm/shows/future-of-coding/playlists/podcast.rss": "Feeling of Computing",
+ "https://www.typetheoryforall.com/episodes.mp3.rss": "Type Theory Forall",
+ "https://feed.podbean.com/acmbytecast/feed.xml": "ACM ByteCast",
+ "https://feeds.acast.com/public/shows/disseminate": "Disseminate: The Computer Science Research Podcast",
+ "https://firstfloor.substack.com/feed": "First Floor",
+ "https://boomkat.com/new-releases.rss": "Boomkat New Releases",
+ "https://acloserlisten.substack.com/feed": "a closer listen",
+ "https://andrewryce.substack.com/feed": "Futureproofing",
+ "https://charliefracture.substack.com/feed": "Fracture",
+ "https://futurismrestated.substack.com/feed": "Futurism Restated",
+ "https://loscil.substack.com/feed": "loscil news",
+ "https://martyn3024.substack.com/feed": "Four Things",
+ "https://musicofafrica.substack.com/feed": "Music of Africa",
+ "https://notagspodcast.substack.com/feed": "No Tags",
+ "https://reachsound.substack.com/feed": "Reach",
+ "https://cantilevermusic.substack.com/feed": "Cantilever",
+ "https://soundnvision.substack.com/feed": "Sound + Vision",
+ "https://acousticarchaeologies.substack.com/feed": "Acoustic Archaeologies",
+ "https://andrewtasselmyer.substack.com/feed": "Sound Methods",
+ "https://anoisosard.substack.com/feed": "Anois, Os Ard",
+ "https://vinylvagabond.substack.com/feed": "The Vinyl Vagabond",
+ "https://cloudcollecting.substack.com/feed": "cloud collecting",
+ "https://bc.mtmn.name/?fan=niccoloexad": "niccoloexad",
+ "https://bc.mtmn.name/?fan=wonja": "wonja",
+ "https://bc.mtmn.name/?fan=thetrilogytapes": "thetrilogytapes",
+ "https://bc.mtmn.name/?fan=maxaxa": "maxaxa",
+ "https://bc.mtmn.name/?fan=andriykostyukov": "andriykostyukov",
+ "https://bc.mtmn.name/?fan=c_aromando": "c_aromando",
+ "https://bc.mtmn.name/?fan=cccconrad": "cccconrad",
+ "https://bc.mtmn.name/?fan=carlosdelascuevas": "carlosdelascuevas",
+ "https://bc.mtmn.name/?fan=curated_by": "curated_by",
+ "https://bc.mtmn.name/?fan=philinamaze": "philinamaze",
+ "https://bc.mtmn.name/?fan=abdonoval": "abdonoval",
+ "https://bc.mtmn.name/?fan=ian_mcdowell": "ian_mcdowell",
+ "https://bc.mtmn.name/?fan=eehaw": "eehaw",
+ "https://bc.mtmn.name/?fan=trishak": "trishak",
+ "https://bc.mtmn.name/?fan=lolobcr": "lolobcr",
+ "https://bc.mtmn.name/?fan=weirdpebble": "weirdpebble",
+ "https://bc.mtmn.name/?fan=br_dge": "br_dge",
+ "https://bc.mtmn.name/?fan=senot": "senot",
+ "https://bc.mtmn.name/?fan=luuuc": "luuuc",
+ "https://bc.mtmn.name/?fan=personnealienee": "personnealienee",
+ "https://bc.mtmn.name/?fan=zitinio": "zitinio",
+ "https://bc.mtmn.name/?fan=peak_flow": "peak_flow",
+ "https://bc.mtmn.name/?fan=pugilisttunes": "pugilisttunes",
+ "https://bc.mtmn.name/?fan=willmemotone": "willmemotone",
+ "https://bc.mtmn.name/?fan=oortcloud": "oortcloud",
+ "https://bc.mtmn.name/?fan=shawnreynaldo": "shawnreynaldo",
+ "https://bc.mtmn.name/?fan=finnoftomland": "finnoftomland",
+ "https://bc.mtmn.name/?fan=poponly": "poponly",
+ "https://bc.mtmn.name/?fan=wejamencona": "wejamencona",
+ "https://bc.mtmn.name/?fan=avsluta": "avsluta",
+ "https://bc.mtmn.name/?fan=microchic": "microchic",
+ "https://bc.mtmn.name/?fan=stoneinfocus": "stoneinfocus",
+ "https://bc.mtmn.name/?fan=vannesacarlton": "vannesacarlton",
+ "https://bc.mtmn.name/?fan=kuscheln": "kuscheln",
+ "https://bc.mtmn.name/?fan=kmru": "kmru",
+ "https://bc.mtmn.name/?fan=theslowbrownfox": "theslowbrownfox",
+ "https://bc.mtmn.name/?fan=seafood_soup": "seafood_soup",
+ "https://bc.mtmn.name/?fan=akirayamagata": "akirayamagata",
+ "https://bc.mtmn.name/?fan=tomcolebrook": "tomcolebrook",
+ "https://bc.mtmn.name/?fan=ludwigundotto": "ludwigundotto",
+ "https://bc.mtmn.name/?fan=hugoz": "hugoz",
+ "https://bc.mtmn.name/?fan=rgb1": "rgb1",
+ "https://bc.mtmn.name/?fan=limbotapes": "limbotapes",
+ "https://bc.mtmn.name/?fan=mvachuska": "mvachuska",
+ "https://bc.mtmn.name/?fan=iffiiffi": "iffiiffi",
+ "https://bc.mtmn.name/?fan=ben_aguero": "ben_aguero",
+ "https://bc.mtmn.name/?fan=akse": "akse",
+ "https://bc.mtmn.name/?fan=sselevolave": "sselevolave",
+ "https://bc.mtmn.name/?fan=elephantjams": "elephantjams",
+ "https://bc.mtmn.name/?fan=sleekfata": "sleekfata",
+ "https://bc.mtmn.name/?fan=gibbin": "gibbin",
+ "https://bc.mtmn.name/?fan=jrhartley": "jrhartley",
+ "https://bc.mtmn.name/?fan=time_snark": "time_snark",
+ "https://bc.mtmn.name/?fan=jayfox16": "jayfox16",
+ "https://bc.mtmn.name/?fan=kumiaicho": "kumiaicho",
+ "https://bc.mtmn.name/?fan=enimsajirol": "enimsajirol",
+ "https://bc.mtmn.name/?fan=parcae": "parcae",
+ "https://bc.mtmn.name/?fan=wisecarver": "wisecarver",
+ "https://bc.mtmn.name/?fan=ysksaske": "ysksaske",
+ "https://bc.mtmn.name/?fan=sarahhwreath": "sarahhwreath",
+ "https://bc.mtmn.name/?fan=bossameow": "bossameow",
+ "https://bc.mtmn.name/?fan=oomcl": "oomcl",
+ "https://bc.mtmn.name/?fan=maxmackenzie": "maxmackenzie",
+ "https://bc.mtmn.name/?artist=tinarecords": "tinarecords",
+ "https://bc.mtmn.name/?artist=plasmasources": "plasmasources",
+ "https://bc.mtmn.name/?artist=worst-records": "worst-records",
+ "https://bc.mtmn.name/?artist=detachrecordings": "detachrecordings",
+ "https://bc.mtmn.name/?artist=5gatetemple": "5gatetemple",
+ "https://bc.mtmn.name/?artist=hotreleases": "hotreleases",
+ "https://bc.mtmn.name/?artist=idorecords": "idorecords",
+ "https://bc.mtmn.name/?artist=missile-records": "missile-records",
+ "https://bc.mtmn.name/?artist=lostdomain": "lostdomain",
+ "https://bc.mtmn.name/?artist=abulmogard": "abulmogard",
+ "https://bc.mtmn.name/?artist=silhouettetapes1": "silhouettetapes1",
+ "https://bc.mtmn.name/?artist=auralconduct": "auralconduct",
+ "https://bc.mtmn.name/?artist=southernlightsrec": "southernlightsrec",
+ "https://bc.mtmn.name/?artist=vladislavdelay": "vladislavdelay",
+ "https://bc.mtmn.name/?artist=hoganordrekords": "hoganordrekords",
+ "https://bc.mtmn.name/?artist=invisible-inc": "invisible-inc",
+ "https://bc.mtmn.name/?artist=sizetenrecords": "sizetenrecords",
+ "https://bc.mtmn.name/?artist=bluenightjungle": "bluenightjungle",
+ "https://bc.mtmn.name/?artist=malrecordings": "malrecordings",
+ "https://bc.mtmn.name/?artist=blackteethrecords": "blackteethrecords",
+ "https://bc.mtmn.name/?artist=hayescollective": "hayescollective",
+ "https://bc.mtmn.name/?artist=alwootton": "alwootton",
+ "https://bc.mtmn.name/?artist=chateauflight": "chateauflight",
+ "https://bc.mtmn.name/?artist=relationreset": "relationreset",
+ "https://bc.mtmn.name/?artist=tapehiss": "tapehiss",
+ "https://bc.mtmn.name/?artist=glinted-records": "glinted-records",
+ "https://bc.mtmn.name/?artist=efficientspace": "efficientspace",
+ "https://bc.mtmn.name/?artist=punctumtapes": "punctumtapes",
+ "https://bc.mtmn.name/?artist=emotional-response": "emotional-response",
+ "https://bc.mtmn.name/?artist=12thisle": "12thisle",
+ "https://bc.mtmn.name/?artist=lowtec-workshop-records": "lowtec-workshop-records",
+ "https://bc.mtmn.name/?artist=nonplusrecords": "nonplusrecords",
+ "https://bc.mtmn.name/?artist=fastcastle": "fastcastle",
+ "https://bc.mtmn.name/?artist=bardouinmusic": "bardouinmusic",
+ "https://bc.mtmn.name/?artist=blushtbc": "blushtbc",
+ "https://bc.mtmn.name/?artist=lakeway": "lakeway",
+ "https://bc.mtmn.name/?artist=distal": "distal",
+ "https://bc.mtmn.name/?artist=twtwlondon": "twtwlondon",
+ "https://bc.mtmn.name/?artist=worshipbristol": "worshipbristol",
+ "https://bc.mtmn.name/?artist=pressurerecords": "pressurerecords",
+ "https://bc.mtmn.name/?artist=worship-productions": "worship-productions",
+ "https://bc.mtmn.name/?artist=zamzamrec": "zamzamrec",
+ "https://bc.mtmn.name/?artist=digitalsting": "digitalsting",
+ "https://bc.mtmn.name/?artist=divisi62": "divisi62",
+ "https://bc.mtmn.name/?artist=ana-sound": "ana-sound",
+ "https://bc.mtmn.name/?artist=kashual": "kashual",
+ "https://bc.mtmn.name/?artist=bizaarbazaar": "bizaarbazaar",
+ "https://bc.mtmn.name/?artist=goo1": "goo1",
+ "https://bc.mtmn.name/?artist=doo-solution": "doo-solution",
+ "https://bc.mtmn.name/?artist=oscillasound": "oscillasound",
+ "https://bc.mtmn.name/?artist=appendixfiles": "appendixfiles",
+ "https://bc.mtmn.name/?artist=limbotapes": "limbotapes",
+ "https://bc.mtmn.name/?artist=clam-pressure": "clam-pressure",
+ "https://bc.mtmn.name/?artist=tomvalrecords": "tomvalrecords",
+ "https://bc.mtmn.name/?artist=29speedway1": "29speedway1",
+ "https://bc.mtmn.name/?artist=area127": "area127",
+ "https://bc.mtmn.name/?artist=iliantape": "iliantape",
+ "https://bc.mtmn.name/?artist=flxk1": "flxk1",
+ "https://bc.mtmn.name/?artist=subglow": "subglow",
+ "https://bc.mtmn.name/?artist=northernelectronics": "northernelectronics",
+ "https://bc.mtmn.name/?artist=nosejob": "nosejob",
+ "https://bc.mtmn.name/?artist=nousklaer": "nousklaer",
+ "https://bc.mtmn.name/?artist=delsinrecords": "delsinrecords",
+ "https://bc.mtmn.name/?artist=nullpunktrec": "nullpunktrec",
+ "https://bc.mtmn.name/?artist=nehzarecords": "nehzarecords",
+ "https://bc.mtmn.name/?artist=midgar-records": "midgar-records",
+ "https://bc.mtmn.name/?artist=mapledeathrecords": "mapledeathrecords",
+ "https://bc.mtmn.name/?artist=heatcrimes": "heatcrimes",
+ "https://bc.mtmn.name/?artist=manaabundance": "manaabundance",
+ "https://bc.mtmn.name/?artist=naffrecordings": "naffrecordings",
+ "https://bc.mtmn.name/?artist=pressuredome": "pressuredome",
+ "https://bc.mtmn.name/?artist=timedance": "timedance",
+ "https://bc.mtmn.name/?artist=cherche-encore": "cherche-encore",
+ "https://bc.mtmn.name/?artist=glarc": "glarc",
+ "https://bc.mtmn.name/?artist=acolourfulstorm": "acolourfulstorm",
+ "https://bc.mtmn.name/?artist=siamesetwinsrecords": "siamesetwinsrecords",
+ "https://bc.mtmn.name/?artist=banoffeepiesrecords": "banoffeepiesrecords",
+ "https://bc.mtmn.name/?artist=global-warming-records": "global-warming-records",
+ "https://bc.mtmn.name/?artist=atoldiskz1": "atoldiskz1",
+ "https://bc.mtmn.name/?artist=comicsansrecords": "comicsansrecords",
+ "https://bc.mtmn.name/?artist=organicsigns": "organicsigns",
+ "https://bc.mtmn.name/?artist=bblisss": "bblisss",
+ "https://bc.mtmn.name/?artist=omenwapta": "omenwapta",
+ "https://bc.mtmn.name/?artist=osare-editions": "osare-editions",
+ "https://bc.mtmn.name/?artist=brukrecords": "brukrecords",
+ "https://bc.mtmn.name/?artist=themothclub": "themothclub",
+ "https://bc.mtmn.name/?artist=analog-records": "analog-records",
+ "https://bc.mtmn.name/?artist=shaytoonrecords": "shaytoonrecords",
+ "https://bc.mtmn.name/?artist=poorlyknituk": "poorlyknituk",
+ "https://bc.mtmn.name/?artist=nyegenyegetapes": "nyegenyegetapes",
+ "https://bc.mtmn.name/?artist=accidentalmeetings": "accidentalmeetings",
+ "https://bc.mtmn.name/?artist=berceuseheroique": "berceuseheroique",
+ "https://bc.mtmn.name/?artist=pointless-geometry": "pointless-geometry",
+ "https://bc.mtmn.name/?artist=avonterrorcorps": "avonterrorcorps",
+ "https://bc.mtmn.name/?artist=theyouthlabel": "theyouthlabel",
+ "https://bc.mtmn.name/?artist=westmineral": "westmineral",
+ "https://bc.mtmn.name/?artist=motionward": "motionward",
+ "https://bc.mtmn.name/?artist=plaquebristol": "plaquebristol",
+ "https://bc.mtmn.name/?artist=baroquesunburst": "baroquesunburst",
+ "https://bc.mtmn.name/?artist=maloca": "maloca",
+ "https://bc.mtmn.name/?artist=corruptterritories": "corruptterritories",
+ "https://bc.mtmn.name/?artist=scopeotaku": "scopeotaku",
+ "https://bc.mtmn.name/?artist=eclipsetribez": "eclipsetribez",
+ "https://bc.mtmn.name/?artist=warmwintersltd": "warmwintersltd",
+ "https://bc.mtmn.name/?artist=mappa": "mappa",
+ "https://bc.mtmn.name/?artist=brutaz": "brutaz",
+ "https://bc.mtmn.name/?artist=heart": "heart",
+ "https://bc.mtmn.name/?artist=crowdspacer": "crowdspacer",
+ "https://bc.mtmn.name/?artist=unexplainedsoundsgroup": "unexplainedsoundsgroup",
+ "https://bc.mtmn.name/?artist=zvukolom": "zvukolom",
+ "https://bc.mtmn.name/?artist=bigsciencerecords": "bigsciencerecords",
+ "https://bc.mtmn.name/?artist=shukai": "shukai",
+ "https://bc.mtmn.name/?artist=flippendisks": "flippendisks",
+ "https://bc.mtmn.name/?artist=sneakersocialclub": "sneakersocialclub",
+ "https://bc.mtmn.name/?artist=feveram": "feveram",
+ "https://bc.mtmn.name/?artist=wellstreetrecords": "wellstreetrecords",
+ "https://bc.mtmn.name/?artist=stroomtv": "stroomtv",
+ "https://bc.mtmn.name/?artist=teenagemenopause": "teenagemenopause",
+ "https://bc.mtmn.name/?artist=redstonepress": "redstonepress",
+ "https://bc.mtmn.name/?artist=tempa": "tempa",
+ "https://bc.mtmn.name/?artist=tectonicrecordings": "tectonicrecordings",
+ "https://bc.mtmn.name/?artist=northfieldrecords": "northfieldrecords",
+ "https://bc.mtmn.name/?artist=drownedbylocals": "drownedbylocals",
+ "https://bc.mtmn.name/?artist=ad93": "ad93",
+ "https://bc.mtmn.name/?artist=mindgamesmusic": "mindgamesmusic",
+ "https://bc.mtmn.name/?artist=ruptureldn": "ruptureldn",
+ "https://bc.mtmn.name/?artist=isla": "isla",
+ "https://bc.mtmn.name/?artist=westernlore": "westernlore",
+ "https://bc.mtmn.name/?artist=thetrilogytapes": "thetrilogytapes",
+ "https://bc.mtmn.name/?artist=uvb-76music": "uvb-76music",
+ "https://bc.mtmn.name/?artist=murmursrecordings": "murmursrecordings",
+ "https://bc.mtmn.name/?artist=shortspanrecords": "shortspanrecords",
+ "https://bc.mtmn.name/?artist=trule": "trule",
+ "https://bc.mtmn.name/?artist=painmgmt": "painmgmt",
+ "https://bc.mtmn.name/?artist=canyoufeelthesun": "canyoufeelthesun",
+ "https://bc.mtmn.name/?artist=brainwavescrew": "brainwavescrew",
+ "https://bc.mtmn.name/?artist=yukumusic": "yukumusic",
+ "https://bc.mtmn.name/?artist=yesnowave": "yesnowave",
+ "https://bc.mtmn.name/?artist=fonstret": "fonstret",
+ "https://bc.mtmn.name/?artist=nostilevo": "nostilevo",
+ "https://bc.mtmn.name/?artist=odyseerecordings": "odyseerecordings",
+ "https://bc.mtmn.name/?artist=akuphone": "akuphone",
+ "https://bc.mtmn.name/?artist=annihayarecords": "annihayarecords",
+ "https://bc.mtmn.name/?artist=xterea": "xterea",
+ "https://bc.mtmn.name/?artist=svbkvlt": "svbkvlt",
+ "https://andrewkelley.me/rss.xml": "Andrew Kelley"
+}
diff --git a/modules/services/miniflux.nix b/modules/services/miniflux.nix
@@ -0,0 +1,32 @@
+{
+ config,
+ lib,
+ ...
+}: let
+ cfg = config.services.haravara.miniflux;
+in {
+ options.services.haravara.miniflux = {
+ enable = lib.mkEnableOption "Miniflux RSS Reader";
+ domain = lib.mkOption {
+ type = lib.types.str;
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ age.secrets.miniflux-secrets.file = ../../secrets/miniflux-secrets.age;
+
+ services.miniflux = {
+ enable = true;
+ config = {
+ LISTEN_ADDR = "127.0.0.1:8931";
+ RUN_MIGRATIONS = 1;
+ CREATE_ADMIN = 0;
+ };
+ adminCredentialsFile = config.age.secrets.miniflux-secrets.path;
+ };
+
+ services.caddy.virtualHosts."${cfg.domain}".extraConfig = ''
+ reverse_proxy 127.0.0.1:8931
+ '';
+ };
+}
diff --git a/secrets.nix b/secrets.nix
@@ -13,4 +13,5 @@ in {
"secrets/searx-secret-key.age".publicKeys = allKeys;
"secrets/headscale-api-key.age".publicKeys = allKeys;
"secrets/attic-credentials.age".publicKeys = allKeys;
+ "secrets/miniflux-secrets.age".publicKeys = allKeys;
}
diff --git a/secrets/miniflux-secrets.age b/secrets/miniflux-secrets.age
Binary files differ.