1
0
mirror of https://github.com/kmein/niveum synced 2026-03-16 18:21:07 +01:00

144 Commits

Author SHA1 Message Date
b9a222855e pi: update plugins 2026-03-04 17:59:51 +01:00
f8bb3c04bf pdf-ocr: fix 2026-03-04 17:59:51 +01:00
dce42c7e80 mp3player-write: do not check disk space 2026-03-04 17:59:51 +01:00
5bedd897c9 switch manakish and kabsa 2026-03-04 17:59:51 +01:00
d952ecf17a meteora: host on ful 2026-03-04 17:59:51 +01:00
df36954fed kpaste: reenable 2026-03-04 17:59:51 +01:00
697100f85f cyberlocker-tools: reenable 2026-03-04 17:59:51 +01:00
8eccb752dc getty: always enable autologinOnce 2026-03-04 17:59:51 +01:00
6bb16ff6ed Revert "cuda: build ollama"
This reverts commit fb86f8c7f7.
2026-03-04 17:59:51 +01:00
8fe9e80522 panoptikon: use from new repo 2026-03-04 17:59:51 +01:00
314848d877 update secrets 2026-02-21 16:26:55 +01:00
377b338979 disable zram 2026-02-21 16:26:48 +01:00
26231912cf opencrow: use new agent 2026-02-21 16:26:36 +01:00
a5532f1e9d panoptikon: use from new repo 2026-02-21 16:26:19 +01:00
d878b73ab5 hyprland: use more niphas tools 2026-02-21 16:25:21 +01:00
3216cd19f5 openclaw: rip 2026-02-18 18:19:20 +01:00
14494ca1f7 wip: fix makanek deploy 2026-02-18 18:18:08 +01:00
201e9e5f60 opencrow 2026-02-18 18:17:45 +01:00
2b59d2a68e opencrow: open up 2026-02-17 23:08:26 +01:00
722b1e9d14 add opencrow Matrix bot on ful
Uses upstream NixOS module (systemd-nspawn container with sandboxing).

- User: @fable:4d2.org on matrix.4d2.org
- Provider: GitHub Copilot (OAuth, one-time interactive login)
- pkgs.pi added via extraPackages (available on PATH inside container)
- Secrets via agenix: matrix token as environmentFile,
  soul bind-mounted into the container
- Sessions + pi-agent state in /var/lib/opencrow, backed up via restic

To complete setup:
1. Create secrets/opencrow-matrix-token.age (OPENCROW_MATRIX_ACCESS_TOKEN=...)
2. Create secrets/opencrow-soul.age (SOUL.md content)
3. One-time Copilot login inside the container:
   sudo nixos-container root-login opencrow
   PI_CODING_AGENT_DIR=/var/lib/opencrow/pi-agent pi
   # Run /login, select GitHub Copilot, complete OAuth flow
2026-02-17 22:37:16 +01:00
bfbe2da850 openclaw: soften the hardening 2026-02-17 22:30:38 +01:00
c34647a800 pi llm 2026-02-17 22:30:38 +01:00
e5c86818d9 nextcloud: upgrade 2026-02-17 22:28:09 +01:00
e885753c7f weechat: run in screen 2026-02-17 22:28:09 +01:00
87e39cc30b aerc: use correct cock port 2026-02-17 22:28:09 +01:00
b46f06a462 add opencrow Matrix bot on ful
Uses upstream NixOS module (systemd-nspawn container with sandboxing).

- User: @fable:4d2.org on matrix.4d2.org
- Provider: GitHub Copilot (OAuth, one-time interactive login)
- Secrets via agenix: matrix token as environmentFile,
  soul bind-mounted into the container
- Sessions + pi-agent state in /var/lib/opencrow, backed up via restic

To complete setup:
1. Create secrets/opencrow-matrix-token.age (OPENCROW_MATRIX_ACCESS_TOKEN=...)
2. Create secrets/opencrow-soul.age (SOUL.md content)
3. One-time Copilot login inside the container:
   sudo nixos-container root-login opencrow
   PI_CODING_AGENT_DIR=/var/lib/opencrow/pi-agent pi
   # Run /login, select GitHub Copilot, complete OAuth flow
2026-02-17 22:25:42 +01:00
9041e4cb11 restore secrets.txt
Accidentally emptied by a previous 'git add -A' in a working tree
where the secrets submodule was not initialized.
2026-02-17 21:55:24 +01:00
6d2acd2e3c fix zaatar build: move printer groups to configs/default.nix
printing.nix can't conditionally set users.users.me.extraGroups —
any mention of users.users.me in the module system creates the user
entry and triggers the isNormalUser/isSystemUser assertion on machines
without a 'me' user (like zaatar).

Move lp/scanner groups to configs/default.nix where users.users.me is
defined. On zaatar, root gets lp/scanner groups directly.
2026-02-17 21:50:21 +01:00
ca6157a4f0 remove dead modules/retiolum.nix
This was an old copy of the krebs retiolum module with NIX_PATH lookups
(<retiolum/hosts>, <system-secrets/...>). It was never imported — the
upstream retiolum.nixosModules.retiolum from the flake input is used
instead (in profiles.default), with configs/retiolum.nix overriding
the key paths to agenix secrets.
2026-02-17 21:39:11 +01:00
6550c1c077 replace niveum-* aliases with direct niphas-* references
- configs/i3.nix: niveum-terminal → niphas-terminal, etc.
- configs/graphical/home-manager.nix: same
- configs/default.nix: same
- flake.nix: remove the three overlay aliases
2026-02-17 21:37:47 +01:00
6fe970ae3a update AGENTS.md with current state
- Remove resolved issues (broken refs, orphaned packages, dead code)
- Add coding conventions section (lib.getExe, writer patterns)
- Fix machine table (kibbeh/zaatar/tabula/tahina profiles are correct now)
- Trim improvement ideas to remaining items only
2026-02-17 21:36:09 +01:00
e67d6d7df2 use lib.getExe and lib.getExe' in packaged scripts
Replace all ${pkg}/bin/name patterns with:
- lib.getExe pkg (for main executables: curl, jq, gnused, ffmpeg, etc.)
- lib.getExe' pkg "name" (for specific binaries: coreutils, util-linux, etc.)
2026-02-17 21:35:28 +01:00
4fc29ff0fe package .bin/ scripts as proper nix packages, delete .bin/
Packaged 14 scripts from .bin/ into packages/ with proper dependency
declarations (writers.writeDashBin/writeBashBin/writePython3Bin):
- 256color → two56color (terminal color chart)
- avesta.sed → avesta (Avestan transliteration)
- bvg.sh → bvg (Berlin transit disruptions)
- unicode → charinfo (Unicode character info)
- chunk-pdf → chunk-pdf (split PDFs by page count)
- csv2json → csv2json (CSV to JSON converter)
- fix-sd.sh → fix-sd (exFAT SD card recovery, improved output handling)
- json2csv → json2csv (JSON to CSV converter)
- mp3player-write → mp3player-write (audio conversion for MP3 players)
- mushakkil.sh → mushakkil (Arabic diacritization)
- nix-haddock-index → nix-haddock-index (GHC Haddock index generator)
- pdf-ocr.sh → pdf-ocr (OCR PDFs via tesseract)
- prospekte.sh → prospekte (German supermarket flyer browser)
- readme → readme (GitHub README as man page)

All added to overlay and packages output. .bin/ directory removed.
2026-02-17 21:32:10 +01:00
dbbad1e146 delete obsolete scripts from .bin/
Removed 27 scripts that are dead, obsolete, or no longer relevant:
- work-specific: elm-publish-private, watson2fdf.sh
- hardcoded creds/sessions: libib.sh, ttrss-unread
- broken/bitrotted: proxies.sh, dummy-alert, playlist_entries.sh, screencap.sh
- trivial/unused: toposort.nix, tuesday-1800, mud.sh, load.sh, calendars.sh
- no longer used: anki-poem.sh, browser, candyman, horoscope.sh, lieferando.sh,
  space.py, notetags.sh, sample-pdf.sh, lit.awk, countdown, json2csv.jq
- dead mail tooling: mail-current-part, mail-current-query-find-part-by-*

Remaining scripts will be packaged properly.
2026-02-17 21:25:40 +01:00
36132b0454 fix broken references to deleted files, remove dead code
Build-breaking fixes:
- kibbeh: remove imports of deleted admin-essentials, nix, zsh configs
  (all provided by niphas via profiles.default + profiles.desktop)
- tabula, tahina: remove imports of deleted admin-essentials, nix configs
  (provided by niphas via profiles.default)
- zaatar: remove import of deleted tmux config
  (provided by niphas via profiles.default)

Dead code removal:
- flake.nix: remove nixosModules.zsh-kmein (referenced deleted config/zsh.nix)
- flake.nix: remove unused wallpapers input
- packages/gpt.nix, hora.nix, k-lock.nix: orphaned, not in overlay or referenced
- configs/hledger.nix: remove hora reference (package deleted)
2026-02-17 21:10:27 +01:00
3bebe25adb remove duplicates already provided by niphas
- Delete configs/bash.nix (identical to niphas, was dead code)
- Delete configs/direnv.nix (dead code, niphas provides direnv)
- Delete packages/vimv.nix (identical to niphas)
- Remove vimv from overlay and packages output
- Alias niveum-terminal/browser/filemanager to niphas equivalents
- Remove 17 duplicate packages from configs/packages.nix
- Remove nil from configs/editor.nix (niphas provides it)
- Remove dead dmenu packageOverride from configs/default.nix
2026-02-17 20:53:52 +01:00
21029d3bbc openclaw: add backups 2026-02-15 22:39:47 +01:00
d8bad81090 openclaw: give it a browser to play with 2026-02-15 22:36:29 +01:00
f12beaa69e picoclaw 2026-02-15 22:14:20 +01:00
a94dacb64c openclaw 2026-02-15 22:13:26 +01:00
fb86f8c7f7 cuda: build ollama 2026-02-15 16:47:29 +01:00
86b5e4da9f radio-news: use newer gemini model 2026-02-15 16:47:29 +01:00
15ab8ac8a8 autologin: fix module use 2026-02-15 16:47:29 +01:00
f202be220b manakish: fix imports 2026-02-15 16:47:29 +01:00
267124dfd1 format 2026-02-15 16:47:29 +01:00
ca05785b26 yt-dlp-master 2026-02-15 16:47:29 +01:00
f1610d08dc mpv: configure with wrappers 2026-02-15 16:47:29 +01:00
9aaaaff724 lix: try out 2026-02-15 16:47:29 +01:00
c6a11c1d79 hold overlays correctly 2026-02-10 22:02:34 +01:00
8c6363881d niphas: update 2026-02-07 16:40:45 +01:00
01019fffac printing: enable scanning 2026-02-07 16:40:35 +01:00
84f1a2688f ensure ashell from unstable 2026-02-06 17:13:14 +01:00
d4cfb63a11 editor: enable copilot and colorscheme 2026-02-06 17:12:57 +01:00
b038278af3 use shared config from niphas 2026-02-04 17:07:52 +01:00
e264f13885 zsh: export config as module 2026-02-03 16:42:47 +01:00
b90cec1a73 update 2026-01-31 17:48:00 +01:00
8e47deb2ab remove legacy displaymanager settings 2026-01-31 15:45:07 +01:00
f883d0ce6f hyprland: fix configure Amo monitor 2026-01-31 14:51:04 +01:00
7aef7e7cf6 hyprland: configure Amo monitor 2026-01-27 09:00:53 +01:00
7d82e284cd applicative: fix config 2026-01-27 09:00:36 +01:00
e99103226d deploy scripts: use substitutes 2026-01-25 13:48:12 +01:00
8a0bf14e4e mp3player-write: turn into potato quality 2026-01-25 13:48:03 +01:00
91a650953a wetter 2026-01-25 13:47:49 +01:00
eae1a7a71b applicative: limit to fatteh 2026-01-25 13:47:28 +01:00
16f8cfbf4c applicative: enable auto-login if not present 2026-01-25 13:46:48 +01:00
e24fdaedf3 mp3player-write: default to length 3 prefix 2026-01-21 07:01:33 +01:00
09b28ce523 exodus 2026-01-20 18:02:39 +01:00
25f1a2ac1e update 2026-01-20 18:02:28 +01:00
db05a76863 waydroid 2026-01-20 18:02:06 +01:00
3155b8f2a5 let other users access The Good Music 2026-01-12 06:30:07 +01:00
3d59940948 hyprland: add some more rice 2026-01-10 11:57:26 +01:00
f373accdd5 hyprland: more sensible keybind for togglesplit 2026-01-10 07:44:22 +01:00
6e25f42def mako: timeout after 10 seconds 2026-01-10 07:13:02 +01:00
ff1b274d5e dawn-editor 2026-01-10 07:13:02 +01:00
7bdf78df40 hyprland: left-align all monitors 2026-01-10 07:12:37 +01:00
3c461efc41 cuda: enable opengl 2026-01-10 07:12:24 +01:00
34a7b6f905 hyprland: localisation 2026-01-10 07:12:13 +01:00
1e736dbfaa regreet: deduplicate libinput code 2026-01-09 12:39:21 +01:00
ab3404b356 ruff 2026-01-09 12:38:57 +01:00
a21583b199 stylix: decrease terminal size 2026-01-09 12:38:51 +01:00
a5db2944c6 hyprland: resize more courageously 2026-01-09 12:38:32 +01:00
98e95b1475 mpv: remove visualizer 2026-01-09 12:38:11 +01:00
8a9e8bf06a hyprland: defancy 2026-01-09 12:37:58 +01:00
e0b904b87a hyprland: disable touchscreen, position Samsung monitor correctly 2026-01-09 12:37:31 +01:00
b4c838d65d git: add pushf alias 2026-01-09 12:37:02 +01:00
028b282d0c dunst: remove 2026-01-09 12:36:55 +01:00
58d355e682 work profile 2026-01-09 12:36:46 +01:00
4701080f28 fatteh: enable cuda 2026-01-09 12:36:13 +01:00
cecc249daa move to wayland 2026-01-06 22:46:12 +01:00
3d9a48c65e hyprland 2026-01-04 14:30:06 +01:00
ad7fc115c6 himalaya: fix config and add neovim wrapper 2026-01-04 12:36:51 +01:00
c93806909f machines: add internal and tor 2026-01-03 11:41:44 +01:00
1ce21c9bcd update 2026-01-03 10:10:15 +01:00
ebd017cd20 tlp: disable 2026-01-03 10:10:05 +01:00
187d7ec12b remove more fysi 2026-01-03 10:09:48 +01:00
c05422c8e4 docker: remove 2026-01-02 21:50:00 +01:00
f0ec0e99c3 autoUpgrade all 2026-01-02 21:43:52 +01:00
9f806822a4 applicative user 2026-01-02 17:05:01 +01:00
d47de27423 wallabag: run on podman, autoupdate 2026-01-02 06:32:22 +01:00
fc4b32dd24 update 2026-01-02 06:21:48 +01:00
27be00fd34 machines: add zaatar local IP 2026-01-01 10:29:30 +01:00
35f309e4b4 dawn editor 2026-01-01 10:29:07 +01:00
6d931c589f kabsa, fatteh: add internal IP 2025-12-30 21:28:01 +01:00
8ab1ec895f kabsa: add tor address 2025-12-30 20:20:52 +01:00
8d1ec7b1ef streams: add byte fm 2025-12-30 19:45:57 +01:00
65ced40c4c gimp: fix 2025-12-29 23:18:01 +01:00
b4f8503c16 use more lib.getExe 2025-12-29 21:05:02 +01:00
30e54f5e4e comma 2025-12-29 17:56:07 +01:00
e5d2bda7ad clean up flake.lock 2025-12-29 17:54:39 +01:00
98e9083763 nix-topology 2025-12-29 16:31:56 +01:00
ea61c3024a flake: remove empty lib 2025-12-29 16:21:49 +01:00
c5379bf926 nixos-hardware 2025-12-29 16:21:35 +01:00
31a6cb384e i3: remove old keybinds 2025-12-29 16:20:26 +01:00
fdff04c94b format 2025-12-29 15:26:13 +01:00
69e752bb6b flake: document ControlPath=none 2025-12-29 15:23:53 +01:00
be0a9620a4 niveum-ssh: install 2025-12-29 13:35:17 +01:00
afb621a98e try-connect: check localhost first 2025-12-29 13:32:13 +01:00
6259075f40 try-connect: use for deploy scripts 2025-12-29 13:17:42 +01:00
f70383c732 tor: enable ssh 2025-12-29 12:27:40 +01:00
c3dc7b9e51 unify profiles 2025-12-29 12:22:30 +01:00
4188968ee1 pun-sort 2025-12-28 22:34:42 +01:00
6a873fb764 writeHaskellBin: no need for readfile 2025-12-28 13:54:56 +01:00
bd92b75278 nixos-rebuild-ng 2025-12-28 13:50:45 +01:00
c15f5375e2 format 2025-12-28 13:39:42 +01:00
51533efeda use treefmt-nix 2025-12-28 13:39:36 +01:00
977e733ace vim-typewriter: fix 2025-12-28 13:29:27 +01:00
29571bce10 remove specialArgs inputs 2025-12-28 13:23:49 +01:00
ab895d9f7b systems -> machines 2025-12-28 12:49:10 +01:00
2d6294e44b ditch nixinate 2025-12-28 12:40:45 +01:00
c33cbe3817 update old system code 2025-12-28 12:05:59 +01:00
de6e08fa23 morris: remove boost-libdir flag 2025-12-27 23:03:13 +01:00
c3db0404b3 format 2025-12-27 22:22:54 +01:00
cb0307e8bf gaming: add boardgames 2025-12-27 19:39:15 +01:00
bafb872730 neovim: alias to vi(m) manually 2025-12-27 19:39:03 +01:00
b82636ff12 morris: package 2025-12-27 17:11:21 +01:00
624df65fee flake: format packages 2025-12-27 15:30:10 +01:00
7b96a2a326 fatteh: configure 39c3 networking 2025-12-27 15:30:01 +01:00
111d9aa8de vim wrappers: use exraName 2025-12-27 08:04:20 +01:00
6c7645a9c8 neovim: set editor and aliases correctly 2025-12-27 08:04:08 +01:00
1a8295a5a5 remove pkgs.niveum.lib.defaultApplications 2025-12-27 07:58:20 +01:00
95e5a58f15 secure mktemp 2025-12-27 07:53:49 +01:00
b233c18709 pls: download on like 2025-12-27 07:36:33 +01:00
8d3020ef84 vim-typewriter: fullscreen on start 2025-12-27 06:51:42 +01:00
d058da7198 vim-typewriter 2025-12-27 06:45:42 +01:00
263 changed files with 5698 additions and 6113 deletions

View File

@@ -1,38 +0,0 @@
#! /bin/sh
set -euf
pl() {
for i in $(seq $1 $(expr $2 - 1)); do
printf '\e[38;5;%sm%03i\e[m ' $i $i
done
printf '\e[38;5;%sm%03i\e[m\n' $2 $2
}
p() {
printf '\e[38;5;%sm%03i\e[m ' $1 $1
}
pn() {
printf '\e[38;5;%sm%03i\e[m\n' $1 $1
}
p6x6() {
for i in $(seq 0 5); do
for j in $(seq 0 5); do
p $(expr $1 + $i + $j \* 6)
done
echo
done
}
pl 0 7
pl 8 15
p6x6 16
p6x6 52
p6x6 88
p6x6 124
p6x6 160
p6x6 196
pl 232 243
pl 244 255

View File

@@ -1,29 +0,0 @@
#!/bin/sh
file="${1?please supply a poetry file}"
[ -f "$file" ] || {
echo "'$file' is no file"
exit 1
}
poem="$(mktemp)"
clean () {
rm "$poem"
}
trap clean EXIT
sed '/^$/d' "$file" > "$poem"
htmlize() {
awk 'ORS="<br/>"' \
| head -c -5 # remove final <br/> characters
}
for line_number in $(seq 1 "$(wc -l "$poem" | cut -d' ' -f1)"); do
if [ "$line_number" -gt 3 ] && [ "$line_number" -gt 1 ]; then
sed -n "$((line_number - 3)),$((line_number - 1))p" "$poem"
else
sed -n "1,$((line_number - 1))p" "$poem"
fi | htmlize
printf '\t'
sed -n "${line_number},+1p" "$poem" | htmlize
printf '\n'
done

View File

@@ -1,54 +0,0 @@
#!/usr/bin/env -S sed -f
s/ā̊/𐬃/g
s//𐬝/g
s/ṣ̌/𐬴/g
s/š́/𐬳/g
s/ą̄/𐬅/g
s/ŋᵛ/𐬤/g
s/ə̄/𐬇/g
s/ŋ́/𐬣/g
s//𐬒/g
s/xᵛ/𐬓/g
s/a/𐬀/g
s/ā/𐬁/g
s/å/𐬂/g
s/ą/𐬄/g
s/ə/𐬆/g
s/e/𐬈/g
s/ē/𐬉/g
s/o/𐬊/g
s/ō/𐬋/g
s/i/𐬌/g
s/ī/𐬍/g
s/u/𐬎/g
s/ū/𐬏/g
s/k/𐬐/g
s/x/𐬑/g
s/g/𐬔/g
s/ġ/𐬕/g
s/γ/𐬖/g
s/c/𐬗/g
s/j/𐬘/g
s/t/𐬙/g
s/θ/𐬚/g
s/d/𐬛/g
s/δ/𐬜/g
s/p/𐬞/g
s/f/𐬟/g
s/b/𐬠/g
s/β/𐬡/g
s/ŋ/𐬢/g
s/n/𐬥/g
s/ń/𐬦/g
s//𐬧/g
s/m/𐬨/g
s//𐬩/g
s//𐬫/g
s/y/𐬪/g
s/v/𐬬/g
s/r/𐬭/g
s/s/𐬯/g
s/z/𐬰/g
s/š/𐬱/g
s/ž/𐬲/g
s/h/𐬵/g

View File

@@ -1,24 +0,0 @@
#!/bin/sh -e
#
# Usage: browser
# pipe html to a browser
# e.g.
# $ echo '<h1>hi mom!</h1>' | browser
# $ ron -5 man/rip.5.ron | browser
if [ -t 0 ]; then
if [ -n "$1" ]; then
open $1
else
cat <<usage
Usage: browser
pipe html to a browser
$ echo '<h1>hi mom!</h1>' | browser
$ ron -5 man/rip.5.ron | browser
usage
fi
else
f="/tmp/browser.$RANDOM.html"
cat /dev/stdin > $f
xdg-open $f
fi

View File

@@ -1,46 +0,0 @@
#!/bin/sh
interesting="U6 N6 140 M46 184 N84"
curl -sSL 'https://www.bvg.de/disruption-reports/q' \
--data-raw '{"variables":{},"query":"{
allDisruptions {
disruptions {
meldungsId
linie
verkehrsmittel
__typename
... on Traffic {
datum
gueltigVonDatum
gueltigVonZeit
gueltigBisDatum
gueltigBisZeit
richtungName
richtungHafasId
beginnAbschnittName
beginnAbschnittHafasId
endeAbschnittName
endeAbschnittHafasId
textIntUrsache
sev
textIntAuswirkung
umfahrung
textWAPSMSUrsache
textWAPSMSAuswirkung
prioritaet
__typename
}
}
__typename
}
}"}' \
| jq --arg interesting "$interesting" '
.data.allDisruptions.disruptions
| map(select(
(.linie as $linie
| $interesting
| split(" ")
| index($linie))
and (.["__typename"] == "Traffic")
))
'

View File

@@ -1,19 +0,0 @@
#!/bin/sh
directory="$(mktemp -d)"
trap clean EXIT
clean() {
rm -rf "$directory"
}
year=$(date +%Y)
output=/tmp/$year.pdf
for month in $(seq 1 12); do
printf "\r%d" "$month" 1>&2
astrolog -zN Berlin -qm "$month" "$year" -X -K -XA -Xr -Xm -Xb -Xo "$(printf "%s/%02d.bmp" "$directory" "$month")" -Xw 1080 720 2>/dev/null
done
printf "\r"
convert "$directory/*.bmp" "$output"
echo "$output"

View File

@@ -1,25 +0,0 @@
#!/bin/sh
set -efu
usage() {
echo >&2 "$0 add-{reddit,telegram,youtube,twitch,twitter} NAME"
exit 1
}
candyman() {
curl -fsSv http://news.r/api -H content-type:application/json -d "$(jq -n "
{
command: \"PRIVMSG\",
params: [\"#all\", \"candyman: $1 $2\"]
}
")"
}
[ $# -ge 2 ] || usage
case "$1" in
add-reddit|add-telegram|add-youtube|add-twitter|add-twitch)
candyman "$@"
;;
*) usage;;
esac

View File

@@ -1,23 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p pdftk gnugrep
set -efu
INPUT_FILE="${2:?Pass the PDF path as second argument.}"
PAGES_PER_REPORT="${1:?Pass the chunk size as first argument.}"
if [ ! -f "$INPUT_FILE" ]; then
echo >&2 "File $INPUT_FILE does not exist."
exit 1
fi
TOTAL_PAGES="$(pdftk "$INPUT_FILE" dump_data | grep NumberOfPages | cut -f2 -d' ')"
RUNS=$((TOTAL_PAGES/PAGES_PER_REPORT))
for run in $(seq 0 "$((RUNS-1))"); do
start_page=$((run*PAGES_PER_REPORT+1))
end_page=$(((run+1)*PAGES_PER_REPORT))
output_file="chunk_$((run+1)).pdf"
echo "splitting $INPUT_FILE from $start_page to $end_page into $output_file"
pdftk "$INPUT_FILE" cat "$start_page-$end_page" output "$output_file"
done

View File

@@ -1,13 +0,0 @@
#!/usr/bin/env -S awk -f
function z() {
getline < "/proc/uptime"
close("/proc/uptime")
return $0
}
BEGIN {
x = z()
while (1) {
y = z()
printf "%02d:%05.2f\r", (y - x) / 60, (y - x) % 60
}
}

View File

@@ -1,14 +0,0 @@
#!/usr/bin/env python3
import csv
import json
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--delimiter", "-d", default=",", help="CSV field separator")
args = parser.parse_args()
if __name__ == "__main__":
json.dump(list(csv.DictReader(sys.stdin, delimiter=args.delimiter)), sys.stdout)

View File

@@ -1,43 +0,0 @@
#!/bin/bash
name=$RANDOM
url='http://localhost:9093/api/v1/alerts'
echo "firing up alert $name"
# change url o
curl -XPOST $url -d "[{
\"status\": \"firing\",
\"labels\": {
\"alertname\": \"$name\",
\"service\": \"my-service\",
\"severity\":\"warning\",
\"instance\": \"$name.example.net\"
},
\"annotations\": {
\"summary\": \"High latency is high!\"
},
\"generatorURL\": \"http://prometheus.int.example.net/<generating_expression>\"
}]"
echo ""
echo "press enter to resolve alert"
read
echo "sending resolve"
curl -XPOST $url -d "[{
\"status\": \"resolved\",
\"labels\": {
\"alertname\": \"$name\",
\"service\": \"my-service\",
\"severity\":\"warning\",
\"instance\": \"$name.example.net\"
},
\"annotations\": {
\"summary\": \"High latency is high!\"
},
\"generatorURL\": \"http://prometheus.int.example.net/<generating_expression>\"
}]"
echo ""

View File

@@ -1,7 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -p "(import <nixpkgs> { overlays = [ (import ~/work/fysiweb/engiadina-pwa/devops/pkgs) ]; }).elm-publish-private"
#! nix-shell -i bash
set -efux
exec elm-publish-private "$@"

View File

@@ -1,21 +0,0 @@
#!/bin/sh
set -xfu
drive="$1"
mountpoint="/media/sd-card-$(date +%s)"
backup_directory="$(pwd)"
trap clean EXIT
clean() {
umount "$mountpoint"
rmdir "$mountpoint"
fsck.exfat "$drive"
}
filenames="$(fsck.exfat "$drive" 2>&1 | sed -nE "s/.* file '(.*?)' is not allocated.*/\1/p")"
mkdir "$mountpoint"
mount "$drive" "$mountpoint"
echo "$filenames" | while read -r filename; do
find "$mountpoint" -type f -name "$filename" -exec mv {} "$backup_directory" \;
done

View File

@@ -1,34 +0,0 @@
#!/bin/sh
set -efu
# Berlin: -d lodeg=13 -d lomin=22 -d losec=41 -d lodir=E -d ladeg=52 -d lamin=27 -d lasec=42 -d ladir=N -d usecoords=1 \
# Kassel: -d lodeg=9 -d lomin=32 -d losec=5 -d lodir=E -d ladeg=51 -d lamin=18 -d lasec=17 -d ladir=N -d usecoords=1 \
[ $# -eq 1 ] || {
echo >&2 Usage: "$0" TIMESTAMP
exit 1
}
export TZ=UTC
chart_path="$(mktemp /tmp/chart_XXX.pdf)"
timestamp="$1"
year="$(date -d "@$timestamp" +%Y)"
month="$(date -d "@$timestamp" +%m)"
day="$(date -d "@$timestamp" +%d)"
hour="$(date -d "@$timestamp" +%H)"
minute="$(date -d "@$timestamp" +%M)"
curl -sSL 'https://edifyingfellowship.org/astro/' \
-d lodeg=9 -d lomin=32 -d losec=5 -d lodir=E -d ladeg=51 -d lamin=18 -d lasec=17 -d ladir=N -d usecoords=1 \
-d ybyr="$year" -d ybmo="$month" -d ybdy="$day" -d ybhr="$hour" -d ybmi="$minute" -d ybsc=0 -d ybtz="$TZ" \
-d currenttime=0 \
-d title="$timestamp" \
-d options[]=VancouverWheel -d options[]=Arrow -d options[]=XBold -d options[]=HouseLabels -d options[]=Placidus \
-d options[]=Sun -d options[]=Moon -d options[]=Mercury -d options[]=Venus -d options[]=Mars -d options[]=Jupiter -d options[]=Saturn -d options[]=Uranus -d options[]=Neptune -d options[]=Pluto -d options[]=Ascendant -d options[]=MC -d options[]=Lilith -d options[]=MeanNode -d options[]=TrueNode \
-d aspectpct=100 -d format=PDF -d Submit= -o "$chart_path"
zathura "$chart_path"

View File

@@ -1,24 +0,0 @@
#!/usr/bin/env python3
import csv
import json
import sys
if __name__ == "__main__":
json_list = json.load(sys.stdin)
if not isinstance(json_list, list):
print("JSON object is not a list.", file=sys.stderr)
sys.exit(1)
if len(json_list) == 0:
print("JSON list is empty.", file=sys.stderr)
sys.exit(1)
keys = set()
for element in json_list:
if isinstance(element, dict):
keys |= element.keys()
else:
print("Non-dict element:", element, file=sys.stderr)
sys.exit(1)
writer = csv.DictWriter(sys.stdout, fieldnames=list(keys))
writer.writeheader()
for element in json_list:
writer.writerow(element)

View File

@@ -1,5 +0,0 @@
#!/usr/bin/env -S jq -r -f
(map(keys) | add | unique) as $cols
| map(. as $row | $cols | map($row[.])) as $rows
| $cols, $rows[]
| @csv

View File

@@ -1,15 +0,0 @@
#!/usr/bin/env bash
session_id=7b638c194d9bda74f80043045018cc9e
declare -A libraries
libraries["Literatur"]=344428
libraries["Sprache"]=344160
libraries["Miscellanea"]=344427
libraries["Wissenschaft"]=344429
libraries["Relicta"]=565920
for library in ${!libraries[@]}
do
curl -sSL 'https://www.libib.com/library/functions/csv-export.php' -H "Cookie: PHPSESSID=$session_id" -d export="${libraries[$library]}" > "$library.csv"
done

View File

@@ -1,81 +0,0 @@
#!/bin/sh
set -efu
if echo "$1" | grep -Eq '[[:digit:]]{5}'; then
PLZ="$1"
else
echo >&2 "Usage: $0 PLZ"
exit 1
fi
lieferando_dir=/tmp/lieferando
mkdir -p "$lieferando_dir/$PLZ"
fetch_restaurants() {
cache_path="$lieferando_dir/$PLZ.json"
if [ -r "$cache_path" ]; then
cat "$cache_path"
else
w3m -dump_source "http://www.lieferando.de/$PLZ" \
| gunzip \
| sed -n '/var restaurants/,/];$/p' \
| sed 's/var restaurants =//;$s/;$//' \
| prettier --parser=json \
| jq '
map({
name: .[30] | .name,
category: .[30] |.categories | split(", "),
url: "http://lieferando.de\(.[30] | .url)",
minutes: .[19],
minimum: .[10],
delivery: .[14]
})' \
| tee "$cache_path"
fi
}
fetch_menu() {
[ $# -eq 1 ] || exit 1
slug="$(echo "$1" | sed 's!.*/!!')"
cache_path="$lieferando_dir/$PLZ/$slug.json"
if [ -r "$cache_path" ]; then
cat "$cache_path"
else
w3m -dump_source "$1" \
| gunzip \
| sed -n '/var MenucardProducts/,/\];/p' \
| sed 's/var MenucardProducts =//;s/;$//' \
| jq -r '
unique_by(.productId)
| group_by(.categoryId)
| flatten
' \
| tee "$cache_path"
fi
}
data="$(fetch_restaurants)"
# echo "$data" | jq -c '.[]' | while read -r restaurant; do
# fetch_menu "$(echo "$restaurant" | jq -r .url)"
# done
selected_categories="$(echo "$data" | jq -r 'map(.category) | flatten | unique | .[]' | fzf -m)"
selected_restaurant_url="$(echo "$selected_categories" | jq --argjson restaurants "$data" -sRr '
split("\n")[:-1] as $categories
| $restaurants[]
| select(.category - $categories != .category)
| "\(.name) [🚴\(.minutes)min 💰\(.minimum)€ + \(.delivery)€] (\(.url))"
' \
| fzf \
| sed 's/.*(//;s/)$//'
)"
fetch_menu "$selected_restaurant_url" \
| jq -r '.[] | "\(.price)\t\(.name)"' \
| fzf -m \
| awk '{print $0; sum += $1} END {print "-----"; print sum}'

View File

@@ -1,17 +0,0 @@
BEGIN {
if (!comment) comment = "--";
if (!begin) begin = "\\begin{code}";
if (!end) end = "\\end{code}";
}
{
if ($0 == begin) {
code = 1;
print comment, $0;
} else if ($0 == end) {
code = 0;
print comment, $0;
} else {
if (code) print $0;
else print comment, $0;
}
}

View File

@@ -1,3 +0,0 @@
#! /bin/sh
set -efu
exec curl -fSs --unix-socket /tmp/much.api.sock http://localhost/current/part

View File

@@ -1,27 +0,0 @@
#! /bin/sh
# usage: mail-current-query-find-part-by-name NAME
set -efu
name=$1
query=$(mail-current-query)
result=$(notmuch show --entire-thread=false --format=json "$query")
part_id=$(printf %s "$result" | jq --arg name "$name" '
[
recurse |
select(type == "object") |
{ id, name: .filename } |
select(.id != null and .name != null)
] |
map(select(.name == $name))[0].id
')
if test "$part_id" = null; then
printf 'error: could not find part with name %s\n' \
"$name" \
>&2
exit 1
fi
exec notmuch show --part="$part_id" "$query"

View File

@@ -1,39 +0,0 @@
#! /bin/sh
# usage: mail-current-query-find-part-by-type TYPE
set -efu
type=$1
query=$(mail-current-query)
result=$(notmuch show --entire-thread=false --format=json "$query")
part_id=$(printf %s "$result" | jq --arg type "$type" '
#flatten|map(select(.!=null))[0].body[0] |
#
#if .["content-type"] == $type then
# .id
#elif .["content-type"] | test("^multipart/") then
# .content|map(select(.["content-type"]==$type))[0].id
#else
# null
#end
[
recurse |
select(type == "object") |
{ id, type: .["content-type"] } |
select(.id != null and .type != null)
] |
map(select(.type == $type))[0].id
')
if test "$part_id" = null; then
printf 'error: could not find part with type %s\n' \
"$type" \
>&2
exit 1
fi
exec notmuch show --part="$part_id" "$query"

View File

@@ -1,114 +0,0 @@
#!/usr/bin/env bash
# Usage:
# ./mp3_transfer.sh -s 1.3 /mnt/mp3player file1.m4a file2.m4a ...
set -e
# Default speed
SPEED=1.0
# Parse options
while getopts ":s:" opt; do
case $opt in
s)
SPEED=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires a value." >&2
exit 1
;;
esac
done
# Shift past the options
shift $((OPTIND -1))
# Check arguments
if [ "$#" -lt 2 ]; then
echo "Usage: $0 [-s speed] MOUNT_POINT FILE1 [FILE2 ...]"
exit 1
fi
MOUNT_POINT=$1
shift
FILES=("$@")
# Check mount point exists
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: Mount point '$MOUNT_POINT' does not exist."
exit 1
fi
# Estimate required space
TOTAL_SIZE=0
for f in "${FILES[@]}"; do
if [ ! -f "$f" ]; then
echo "Warning: File '$f' does not exist, skipping."
continue
fi
# Get file size in bytes
FILE_SIZE=$(stat --printf="%s" "$f")
# Estimate mp3 output size: roughly 1/2 of original m4a (adjust if needed)
TOTAL_SIZE=$((TOTAL_SIZE + FILE_SIZE / 2))
done
# Get available space in bytes
AVAILABLE=$(df --output=avail "$MOUNT_POINT" | tail -n 1)
AVAILABLE=$((AVAILABLE * 1024)) # df reports in KB
if [ "$TOTAL_SIZE" -gt "$AVAILABLE" ]; then
echo "Error: Not enough space on device. Required: $TOTAL_SIZE bytes, Available: $AVAILABLE bytes"
exit 1
fi
echo "Enough space available. Starting conversion..."
sanitize_filename() {
local name="$1"
# Remove path, keep only base name
name=$(basename "$name" .m4a)
# Replace spaces and special chars with underscore
name=$(echo "$name" | tr ' ' '_' | tr -cd '[:alnum:]_-')
# Truncate to max 50 chars
echo "${name:0:50}"
}
# Convert and copy files
for f in "${FILES[@]}"; do
if [ ! -f "$f" ]; then
continue
fi
# Determine the next prefix
existing_prefixes=$(ls "$MOUNT_POINT" | grep -E '^[0-9].*\.mp3$' | sed -E 's/^([0-9]).*/\1/' | sort -n | uniq)
for i in {0..9}; do
if ! echo "$existing_prefixes" | grep -q "^$i$"; then
PREFIX=$i
break
fi
done
echo "Using prefix: $PREFIX"
BASENAME=$(sanitize_filename "$f")
OUT_PATTERN="$MOUNT_POINT/${PREFIX}%02d_${BASENAME}.mp3"
echo "Converting '$f' to '$OUT_PATTERN' at speed $SPEED..."
ffmpeg -i "$f" \
-filter:a "atempo=$SPEED" -ar 44100 -ac 2 -c:a libmp3lame -b:a 128k \
-f segment -segment_time 300 \
"$OUT_PATTERN"
# Update prefix for next file
# Count how many segments were created
SEG_COUNT=$(ls "$MOUNT_POINT" | grep -E "^${PREFIX}[0-9]{2}_" | wc -l)
PREFIX=$((PREFIX + SEG_COUNT))
done
echo "All files processed successfully."

View File

@@ -1 +0,0 @@
ssh mud@hotdog.r -t "MUD_NICKNAME=$LOGNAME mud"

View File

@@ -1,6 +0,0 @@
#!/bin/sh
curl -sSL 'https://diac.alsharekh.org/Diac/DiacText' \
-H "Content-Type: application/json" \
--data-raw "$(jq --raw-input '{word: ., type: 1}')" \
--compressed \
| jq -r .diacWord

View File

@@ -1,93 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p coreutils gnugrep gnused graphviz
#
# usage: nix-haddock-index
#
# Run this script in an environment where either NIX_GHC is set, or the ghc
# executable exists, to generate an HTML index file pointing to all Haddock
# files accessible to the respective ghc version.
#
# Additionally, an SVG dependency graph of all packages is linked at the
# bottom of the index file.
#
# Note: all files will be generated in /tmp, and won't be deleted automatically
#
set -efux
if test -z "${NIX_GHC-}"; then
NIX_GHC=$(readlink -f "$(type -P ghc)")
fi
if ! echo $NIX_GHC | grep -q '^/nix/store/'; then
printf '%s: error: unsupported GHC executable path (not in Nix store): %q\n' \
"$0" \
"$NIX_GHC" \
>&2
exit -1
fi
NIX_GHC_PREFIX=$(dirname "$(dirname "$NIX_GHC")")
NIX_GHC_DOCDIR=$NIX_GHC_PREFIX/share/doc/ghc/html
main() {
hash=$(echo $NIX_GHC_PREFIX | sed -n 's|^/nix/store/\([a-z0-9]\+\).*|\1|p')
title="Haddock index for $NIX_GHC_PREFIX"
header=$(
printf 'Haddock index for <a href="%s">%s</a>\n' \
$NIX_GHC_PREFIX \
$NIX_GHC_PREFIX \
)
suffix=${hash:+-$hash}
index_file=/tmp/haddock$suffix-index.html
svg_file=/tmp/haddock$suffix.svg
#if ! test -e $index_file; then
eval "$(
echo 'gen_index() {'
echo ' html_head'
"$NIX_GHC_PREFIX"/bin/ghc-pkg dump | sed -n '
s/^---$/ reset/p
s/^\(name\|version\):\s*\([-A-Za-z0-9_.]\+\)$/ \1=\2/p
s/^haddock-html:\s*\([-A-Za-z0-9_./]\+\)$/ haddock_html \1/p
'
echo ' html_foot'
echo '}'
)"
gen_index > $index_file
#fi
#if ! test -e $svg_file; then
"$NIX_GHC_PREFIX"/bin/ghc-pkg dot | tred | dot -Tsvg | sed '
s/<svg width="[0-9]\+pt" height="[0-9]\+pt"/<svg width="3600px" height="100%"/
' > $svg_file
#fi
echo $index_file
}
reset() {
unset name version
}
haddock_html() {
printf '<li>'
printf '<a href="%s/index.html">%s</a>' "$1" "$name-$version"
printf '</li>\n'
}
html_head() {
printf '<!doctype html>\n'
printf '<title>%s</title>\n' "$title"
printf '<link href="%s" rel="stylesheet" type="text/css">\n' \
"$NIX_GHC_DOCDIR/libraries/ocean.css"
printf '<h1>%s</h1>\n' "$header"
printf '<ul>\n'
}
html_foot() {
printf '</ul>\n'
printf '<a href="%s">graph</a>\n' "$svg_file"
}
main "$@"

View File

@@ -1,15 +0,0 @@
#!/bin/sh
# inspired by https://github.com/connermcd/bin/blob/1d38cb98812906d8b95dc6e51e1149e29261617d/notetags
cd "$HOME/notes/" || exit
[ -f tags ] && rm tags
grep -r 'tags:' ./* | while read -r line; do
file=$(echo "$line" | cut -d: -f1)
unparsed_tags=$(echo "$line" | cut -d: -f3) #
tags=$(echo "$unparsed_tags" | sed -e 's/tags: *//g' -e 's/[][,]//g')
for tag in $tags; do
echo "$tag $file /^$unparsed_tags$/;" >> tags
done
done

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p poppler_utils tesseract4
set -eu
pdf_path="$(realpath "$1")"
[ -f "$pdf_path" ] || {
echo "Usage: $0 FILE.pdf" >&2
exit 1
}
tmpdir="$(mktemp -d)"
trap 'rm -rf $tmpdir' EXIT
cd "$tmpdir"
pdftoppm -png "$pdf_path" pdf-ocr
for png in pdf-ocr*.png; do
tesseract "$png" "$png.txt" 2>/dev/null
done
cat pdf-ocr-*.txt

View File

@@ -1,2 +0,0 @@
#!/bin/sh
youtube-dl -ij "$*" | jq -sr '.[] | .webpage_url'

View File

@@ -1,65 +0,0 @@
#!/bin/sh
lidl() {
echo LIDL
curl -sSL 'https://endpoints.lidl-flyer.com/v3/region-overview/lidl/de-DE/0.json' \
| jq -r '
.categories
| map(select(.name == "Filial-Angebote") | .subcategories | map(.flyers))
| flatten
| flatten
| .[]
| .pdfUrl
'
}
aldi_nord() {
echo ALDI nord
echo 'https://magazine.aldi-nord.de/aldi-nord/aldi-aktuell/GetPDF.ashx'
echo 'https://magazine.aldi-nord.de/aldi-nord/aldi-vorschau/GetPDF.ashx'
}
rewe_berlin() {(
store_id=662366923
publisher_id=1062
echo REWE
curl -sSL 'https://www.bonialserviceswidget.de/de/stores/'$store_id'/brochures?storeId='$store_id'&publisherId='$publisher_id | while read -r brochure_id; do
curl -sSL 'https://www.bonialserviceswidget.de/de/v5/brochureDetails/'"$brochure_id"'?publisherId='$publisher_id | jq -r .pdfUrl
done
)}
kaufland() {(
region_code=8920
echo KAUFLAND
curl -sSL https://filiale.kaufland.de/prospekte.html | htmlq --attribute href '.flyer a' | grep -Eo 'DE_de_KDZ[^/]*' | sed "s/_3000_/_${region_code}_/" | while read -r flyer_id; do
curl -sSL "https://endpoints.leaflets.kaufland.com/v3/$flyer_id/flyer.json?regionCode=$region_code" | jq -r .flyer.pdfUrl
done
)}
netto_schwarz() {
echo 'NETTO (schwarz)'
curl -sSL 'https://squid-api.tjek.com/v2/catalogs?dealer_ids=90f2VL&order_by=created' \
| jq -r '.[] | .id' \
| while read -r flyer_id; do
curl -sSL "https://squid-api.tjek.com/v2/catalogs/$flyer_id/download" \
| jq -r .pdf_url
done
}
dir="$(mktemp -d)"
trap clean EXIT
clean() {
rm -rf "$dir"
}
prospekt_url="$( (
lidl
aldi_nord
rewe_berlin
kaufland
netto_schwarz
) | fzf)"
curl -sSL "$prospekt_url" -o "$dir/prospekt.pdf"
zathura "$dir/prospekt.pdf"

View File

@@ -1,17 +0,0 @@
#!/bin/sh
curl -sSL https://www.netzwelt.de/proxy/index.html \
| pup ".tblc" \
| xml-to-json /dev/stdin \
| jq '
.div.table.tbody.tr
| map(
.td
| {
ip: .[0].a.value,
port: .[1],
country: .[2] | (if type == "string" then . else .a.value end),
security: .[3],
protocol: .[4]
}
)
'

View File

@@ -1,4 +0,0 @@
#!/bin/sh
curl -sSL "https://raw.githubusercontent.com/$*/master/README.md" \
| pandoc -f gfm -t man -s \
| man -l -

View File

@@ -1,6 +0,0 @@
#!/bin/sh
filepath="$(shuf --head-count=1)"
pages="$(pdfinfo "$filepath" | awk '/^Pages:/{print $2}')"
random_page="$(shuf --input-range="1-$pages" --head-count=1)"
zathura --page="$random_page" "$filepath"

View File

@@ -1,16 +0,0 @@
#! /usr/bin/env nix-shell
#! nix-shell -i sh -p coreutils byzanz xorg.xwininfo gnused
# shellcheck shell=sh
# ref https://gist.github.com/aforemny/0994cb7f06ea30d56c8b9681ff5d2054
set -eux
eval "$(xwininfo | \
sed -n -e 's/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p' \
-e 's/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p' \
-e 's/^ \+Width: \+\([0-9]\+\).*/w=\1/p' \
-e 's/^ \+Height: \+\([0-9]\+\).*/h=\1/p')"
trap "pkill -f 'sleep 360d'" INT
byzanz-record -e "sleep 360d" -c -x $x -y $y -w $w -h $h "$@"

View File

@@ -1,49 +0,0 @@
import ephem
from datetime import datetime, date, timedelta
now = datetime.now()
limit = now + timedelta(days=365)
def events_until(limit):
initial_date = ephem.Date(datetime.now())
events = {}
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_full_moon(now)
events[now] = "🌕"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_new_moon(now)
events[now] = "🌑"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_vernal_equinox(now)
events[now] = "spring equinox"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_autumnal_equinox(now)
events[now] = "fall equinox"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_winter_solstice(now)
events[now] = "winter solstice"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_summer_solstice(now)
events[now] = "summer solstice"
return events
events = events_until(limit)
for date, event in sorted(events.items(), key=lambda x: x[0]):
if ephem.localtime(date) < limit:
print(ephem.localtime(date), event)

View File

@@ -1,50 +0,0 @@
let
lib = import <nixpkgs/lib>;
in rec {
inherit lib;
input = [
{
x = ["pool" "zfs"];
y = ["mdadm" "raid1"];
}
{
x = ["pool" "zfs"];
y = ["disk" "sda"];
}
{
x = ["mdadm" "raid1"];
y = ["disk" "sdb"];
}
{
x = ["mdadm" "raid1"];
y = ["disk" "sdc"];
}
];
outNodes = node: graph:
lib.unique
(builtins.map (e: e.y)
(builtins.filter (v: v.x == node) graph));
vertices = graph:
lib.unique
(builtins.map (x: x.y) graph ++ builtins.map (x: x.x) graph);
deleteVertex = node: graph: (builtins.filter (v: v.x != node && v.y != node) graph);
findSink = graph:
lib.findFirst
(v: outNodes v graph == [])
(lib.trace graph (builtins.abort "No sink found"))
(vertices graph);
topSort = graph:
if graph == []
then []
else if builtins.length graph == 1
then let only = builtins.head graph; in [only.y only.x]
else let sink = findSink graph; in [sink] ++ topSort (deleteVertex sink graph);
output = topSort input;
}

View File

@@ -1,18 +0,0 @@
#/usr/bin/env -S deno run -A:q
set -x
session_cache="$HOME/.cache/tt-rss.session"
ttrss_endpoint=https://feed.kmein.de/api/
ttrss_user=k
ttrss_password=$(pass shared/tt-rss/password)
login() {
if [ -f "$session_cache" ]; then
session_id="$(cat "$session_cache")"
else
session_id="$(curl -d '{"op":"login","user":"'"$ttrss_user"'","password":"'"$ttrss_password"'"}' "$ttrss_endpoint" | jq -r .content.session_id)"
echo "$session_id" > "$session_cache"
fi
}
login
curl -d '{"sid":"'"$session_id"'","op":"getUnread"}' "$ttrss_endpoint" | jq .content

View File

@@ -1,16 +0,0 @@
#!/bin/sh
set -efux
expected_max_results=1024 # the upper bound on the number of restaurants
radius=250
echo '[out:json];node(id:260050809)->.cbase;
(
node(around.cbase:'$radius')[amenity=fast_food];
node(around.cbase:'$radius')[amenity=restaurant];
);out;' \
| curl -sSL -d @- -X POST http://overpass-api.de/api/interpreter \
| jq --argjson random "$(shuf -i 0-$expected_max_results -n 1)" '
.elements
| length as $length
| .[$random % $length]
'

View File

@@ -1,8 +0,0 @@
import sys
import unicodedata
for index, character in enumerate(sys.stdin.read().strip()):
try:
print(index, character, hex(ord(character)), unicodedata.category(character), unicodedata.name(character))
except:
print(index, character, hex(ord(character)))

View File

@@ -1,26 +0,0 @@
project=Filli
year=2022
for month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec; do
from="$(date +%F -d "$month 1, $year")"
to="$(date +%F -d "$month 1, $year + 1 month")"
watson report --json --from "$from" --to "$to" --project "$project"
done | jq --slurp '
def in_array($arr):
. as $value | any($arr[]; . == $value);
map(
["engadin-app","fysiweb","val-muestair","mia-engiadina","ol"] as $official_projects
| (.timespan.from | .[0:7]) as $timespan
| .projects | .[0]
| .time as $total_time
| .tags
| select(. != null)
| map(select(.name | in_array($official_projects)))
| (map(.time)|add) as $official_time
| map({key:.name, value:.time}) | from_entries
| .other |= ($total_time - $official_time)
| map_values(. / (60*60) | ceil)
| .month |= $timespan
)
'

View File

@@ -2,7 +2,7 @@ name: Update flake.lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
- cron: "0 0 * * 0" # runs weekly on Sunday at 00:00
jobs:
lockfile:

View File

@@ -7,33 +7,33 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
system: [makanek,manakish,kabsa,zaatar,ful,fatteh]
system: [makanek, manakish, kabsa, zaatar, ful, fatteh]
steps:
- uses: actions/checkout@v3
- name: Install QEMU (ARM)
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static
if: ${{ matrix.system == 'ful' }}
- name: Install Nix (ARM)
uses: cachix/install-nix-action@v16
if: ${{ matrix.system == 'ful' }}
with:
extra_nix_config: |
system = aarch64-linux
- name: Install Nix (x86_64)
uses: cachix/install-nix-action@v16
if: ${{ matrix.system != 'ful' }}
- name: nixos-rebuild dry-build
run: |
# remove secrets: ref https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/36593218
git submodule deinit -f secrets
rm -rf .git/modules/secrets
git rm -f secrets
- uses: actions/checkout@v3
- name: Install QEMU (ARM)
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static
if: ${{ matrix.system == 'ful' }}
- name: Install Nix (ARM)
uses: cachix/install-nix-action@v16
if: ${{ matrix.system == 'ful' }}
with:
extra_nix_config: |
system = aarch64-linux
- name: Install Nix (x86_64)
uses: cachix/install-nix-action@v16
if: ${{ matrix.system != 'ful' }}
- name: nixos-rebuild dry-build
run: |
# remove secrets: ref https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/36593218
git submodule deinit -f secrets
rm -rf .git/modules/secrets
git rm -f secrets
# recreate secrets
mkdir secrets
cat secrets.txt | while read -r path; do touch $path; done
git add secrets
# recreate secrets
mkdir secrets
cat secrets.txt | while read -r path; do touch $path; done
git add secrets
nix run nixpkgs#nixos-rebuild -- dry-build --flake $GITHUB_WORKSPACE#${{matrix.system}}
nix run nixpkgs#nixos-rebuild -- dry-build --flake $GITHUB_WORKSPACE#${{matrix.system}}

96
AGENTS.md Normal file
View File

@@ -0,0 +1,96 @@
# niveum — Agent Notes
## What This Is
A NixOS flake managing ~9 machines (desktops, servers, family laptops) for one user (kmein/kfm).
Levantine food-themed hostnames: fatteh, kabsa, kibbeh, makanek, manakish, tabula, tahina, zaatar, ful.
## Repository Structure
```
flake.nix # ~670 lines — inputs, overlay, nixosConfigurations, apps, packages output
configs/ # ~50 NixOS config fragments imported by systems
default.nix # 200+ line mega-module for desktop machines (user, shell, gnupg, i18n, etc.)
graphical/ # Hyprland + home-manager config (415 lines in home-manager.nix)
packages.nix # ~250 lines of environment.systemPackages
bots/ # Telegram/Mastodon/Matrix bot configs
keyboard/ # XKB layouts (Coptic, Avestan, Gothic, etc.)
configs/*.nix # Individual concerns: bluetooth, sound, printing, ssh, fonts, etc.
modules/ # Proper NixOS modules with options (retiolum, telegram-bot, passport, power-action, etc.)
packages/ # ~107 package files (scripts, wrappers, small tools)
systems/<name>/ # Per-machine: configuration.nix + hardware-configuration.nix + extras
lib/ # default.nix (niveum helpers), machines.nix (IP/key inventory), panoptikon.nix
secrets/ # agenix-encrypted .age files (empty dir in checkout, tracked via secrets.txt)
```
## Key Relationships
- **niphas** (input): Provides shared "how I like things" config — nixosModules (shell, editor, git, desktop, nix, udiskie) and overlay (niphas-* packages). Used in `profiles.default` and `profiles.desktop`.
- **configs/default.nix**: The "big desktop profile" — imported by fatteh, kabsa, manakish (the main desktop machines). NOT imported by servers or family laptops.
- **profiles** (in flake.nix): `profiles.default`, `profiles.desktop`, `profiles.server` — lists of modules composed per machine.
- **lib.niveum**: Custom lib injected via overlay (`pkgs.lib.niveum`) — used everywhere for machine addresses, SSH port, helper functions.
## Coding Conventions
- Packages use `writers.writeDashBin`, `writers.writeBashBin`, or `writers.writePython3Bin`
- Dependencies are referenced via `lib.getExe pkg` (main executable) or `lib.getExe' pkg "name"` (specific binary)
- For packages needing many commands via PATH, use `lib.makeBinPath` instead (see `packages/prospekte.nix`)
- Overlay entries use `prev.callPackage packages/foo.nix { }` pattern
- Packages are exported via `inherit (pkgs) ...` in the `packages` output
## Known Bugs / Broken References
All previously broken references have been fixed (see commits `36132b04`, `e67d6d7d`).
Remaining issues:
- `modules/retiolum.nix` uses `<retiolum/hosts>` and `<system-secrets/...>` NIX_PATH lookups — breaks flake purity but works with current `NIX_PATH` setup
## Architectural Issues
### 1. configs/default.nix is a grab-bag (200+ lines, ~15 inline anonymous modules)
It's a list of `imports` mixing inline `{ ... }` blocks with file imports. Hard to find what's defined where.
### 2. Retiolum secret boilerplate repeated 9 times
Every system has a near-identical block:
```nix
age.secrets.retiolum-rsa = { file = ../../secrets/${hostname}-retiolum-privateKey-rsa.age; mode = "400"; owner = "tinc-retiolum"; ... };
age.secrets.retiolum-ed25519 = { ... same ... };
```
Could be a function or module parameterized by hostname.
### 3. Nginx + ACME boilerplate duplicated
ful and makanek have identical nginx recommended settings + ACME config.
### 4. niveum-* overlay aliases
`niveum-terminal`, `niveum-browser`, `niveum-filemanager` are aliases to niphas equivalents. Could be removed by updating ~6 references in configs/ to use niphas-* names directly.
### 5. The `pkgs.lib.niveum` pattern
Custom lib injected via overlay into `pkgs.lib`. Unconventional — only available where overlay is applied. A `specialArgs` approach or standalone lib would be cleaner.
### 6. Restic backup config scattered
`services.restic.backups.niveum` is configured in configs/backup.nix, configs/applicative.nix, and extended in 5+ system files. Hard to see what a given machine backs up.
### 7. configs/ vs modules/ distinction blurry
`configs/` has both stateless config fragments (spacetime.nix = timezone) and stateful ones (backup.nix, cloud.nix). `modules/` has proper option-declaring modules. Some configs/ files import from modules/.
## Machines Overview
| Machine | Role | Profile | Arch | Notes |
|-----------|--------------|------------------|---------|---------------------------------------|
| fatteh | Desktop | default+desktop | x86_64 | ThinkPad T480, CUDA, main daily |
| kabsa | Desktop | default+desktop | x86_64 | ThinkPad X220, constrained (2 jobs) |
| manakish | Desktop | default+desktop | x86_64 | ThinkPad X230 |
| kibbeh | Desktop | default+desktop | x86_64 | Pantheon DE, travel laptop |
| ful | Server | default+server | aarch64 | Oracle/Hetzner, nginx, web services |
| makanek | Server | default+server | x86_64 | Hetzner, gitea, nextcloud, weechat |
| zaatar | Server/Home | default+server | x86_64 | Home assistant, backup server |
| tabula | Family laptop| default | x86_64 | LXQt, user "xenos" |
| tahina | Family laptop| default | x86_64 | Pantheon, user "xenos", German |
## Remaining Improvement Ideas
1. **Extract retiolum secret boilerplate** into a function/module
2. **Break up configs/default.nix** into proper named files
3. **Extract nginx+ACME server profile**
4. **Replace niveum-* aliases** with direct niphas-* references
5. **Fix modules/retiolum.nix** NIX_PATH usage for flake purity

View File

@@ -5,13 +5,14 @@
> [nĭvĕus](https://logeion.uchicago.edu/niveus), a, um, adj. [nix], _of_ or _from snow, snowy, snow-_ (poet.)
>
> 1. Lit.: aggeribus niveis informis, Verg. G. 3, 354: aqua, _cooled with snow_, Mart. 12, 17, 6; cf. id. 14, 104 and 117: mons, _covered with snow_, Cat. 64, 240.—
>
> 2. Transf., _snow-white, snowy_ (mostly poet.): a similitudine sic: Corpore niveum candorem, aspectu igneum ardorem assequebatur, Auct. Her. 4, 33, 44: lacerti, Verg. A. 8, 387: lac, id. E. 2, 20: hanc si capite niveae agnae exorari judicas, Sen. Q. N. 2, 36: Briseis niveo colore, Hor. C. 2, 4, 3: vestis, Ov. M. 10, 432: candidior nivei folio, Galatea, ligustri, id. ib. 13, 789: dens, id. H. 18, 18: quā notam duxit niveus videri, Hor. C. 4, 2, 59: panis, Juv. 5, 70: flumen, _clear, pellucid_, Sen. Hippol. 504: undae, Mart. 7, 32, 11: tribuni, _clothed in white togas_, Calp. Ecl. 7, 29; so, Quirites, Juv. 10, 45.
## Pressestimmen
> das ist ja pure poesie —[riotbib](https://github.com/riotbib/)
> Deine Configs sind wunderschön <3 —[flxai](https://github.com/flxai/)
## To do
- [ ] get rid of `nixinate`
🦗

View File

@@ -1,118 +0,0 @@
{
pkgs,
lib,
...
}: let
darwin = lib.strings.hasSuffix "-darwin" pkgs.stdenv.hostPlatform.system;
in {
environment.systemPackages =
[
pkgs.htop
pkgs.w3m
pkgs.wget
# ARCHIVE TOOLS
pkgs.unzip
pkgs.unrar
pkgs.p7zip
pkgs.sshuttle
pkgs.zip
# MONITORS
pkgs.iftop # interface bandwidth monitor
pkgs.lsof # list open files
# SHELL
pkgs.sqlite
pkgs.fd # better find
pkgs.tree
pkgs.parallel # for parallel, since moreutils shadows task spooler
pkgs.ripgrep # better grep
pkgs.rlwrap
pkgs.progress # display progress bars for pipes
pkgs.file # determine file type
pkgs.gdu # ncurses disk usage (ncdu is broken)
pkgs.rmlint # remove duplicate files
pkgs.jq # json toolkit
pkgs.jless # less(1) for json
pkgs.fq # toolkit for yaml, xml and binaries
pkgs.bc # calculator
pkgs.pari # gp -- better calculator
pkgs.ts
pkgs.vimv
pkgs.vg
pkgs.fkill
pkgs.cyberlocker-tools
pkgs.untilport
pkgs.kpaste
# HARDWARE
pkgs.pciutils # for lspci
]
++ lib.optionals (!darwin) [
pkgs.usbutils # for lsusb
pkgs.lshw # for lshw
pkgs.iotop # I/O load monitor
pkgs.psmisc # for killall, pstree
];
security.wrappers = {
pmount = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.pmount}/bin/pmount";
};
pumount = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.pmount}/bin/pumount";
};
};
environment.shellAliases = let
take = pkgs.writers.writeDash "take" ''
mkdir "$1" && cd "$1"
'';
cdt = pkgs.writers.writeDash "cdt" ''
cd "$(mktemp -d)"
pwd
'';
wcd = pkgs.writers.writeDash "wcd" ''
cd "$(readlink "$(${pkgs.which}/bin/which --skip-alias "$1")" | xargs dirname)/.."
'';
where = pkgs.writers.writeDash "where" ''
readlink "$(${pkgs.which}/bin/which --skip-alias "$1")" | xargs dirname
'';
in
{
nixi = "nix repl nixpkgs";
take = "source ${take}";
wcd = "source ${wcd}";
where = "source ${where}";
# temporary files and directories
cdt = "source ${cdt}";
vit = "$EDITOR $(mktemp)";
# file safety
mv = "${pkgs.coreutils}/bin/mv --interactive";
rm = "${pkgs.coreutils}/bin/rm --interactive";
cp = "${pkgs.coreutils}/bin/cp --interactive";
# colours
cat = "${pkgs.bat}/bin/bat --theme=ansi --style=plain";
l = "${pkgs.coreutils}/bin/ls --color=auto --time-style=long-iso --almost-all";
ls = "${pkgs.coreutils}/bin/ls --color=auto --time-style=long-iso";
ll = "${pkgs.coreutils}/bin/ls --color=auto --time-style=long-iso -l";
la = "${pkgs.coreutils}/bin/ls --color=auto --time-style=long-iso --almost-all -l";
}
// (
if darwin
then {}
else {
"ß" = "${pkgs.util-linux}/bin/setsid";
ip = "${pkgs.iproute2}/bin/ip -c";
# systemd
s = "${pkgs.systemd}/bin/systemctl";
us = "${pkgs.systemd}/bin/systemctl --user";
j = "${pkgs.systemd}/bin/journalctl";
uj = "${pkgs.systemd}/bin/journalctl --user";
}
);
}

View File

@@ -91,7 +91,7 @@
imap.host = mailhost;
imap.port = 993;
smtp.host = mailhost;
smtp.port = 25;
smtp.port = 587;
smtp.tls.useStartTls = true;
};
ical-ephemeris =
@@ -128,7 +128,6 @@
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-posteo.path}";
himalaya = {
enable = true;
settings.backend = "imap";
};
aerc.extraAccounts.pgp-key-id = "9EDE82CC72A343A95266D0F444857074A3ACC8B7";
};
@@ -306,7 +305,7 @@
openers =
let
as-pdf = pkgs.writers.writeDash "as-pdf" ''
d=$(mktemp -d)
d=$(mktemp -p "$XDG_RUNTIME_DIR" -d)
trap clean EXIT
clean() {
rm -rf "$d"

View File

@@ -1,33 +1,7 @@
{
pkgs,
lib,
...
}: let
in {
environment.variables.TERMINAL = "alacritty";
home-manager.users.me = {
programs.alacritty = {
enable = true;
settings = {
keyboard.bindings = [
{
key = "Plus";
mods = "Control";
action = "IncreaseFontSize";
}
{
key = "Minus";
mods = "Control";
action = "DecreaseFontSize";
}
{
key = "Key0";
mods = "Control";
action = "ResetFontSize";
}
];
};
};
};
}

View File

@@ -1,5 +1,5 @@
{
programs.adb.enable = true;
users.users.me.extraGroups = ["adbusers"];
users.users.me.extraGroups = [ "adbusers" ];
}

56
configs/applicative.nix Normal file
View File

@@ -0,0 +1,56 @@
{
config,
pkgs,
lib,
...
}:
{
users.users.applicative = {
name = "asg";
description = "Applicative Systems";
hashedPasswordFile = config.age.secrets.kfm-password.path;
home = "/home/applicative";
uid = 1001;
isNormalUser = true;
extraGroups = [
"pipewire"
"audio"
];
};
nixpkgs.overlays = [
(final: prev: {
niphas-wallpaper = prev.callPackage ../packages/applicative-wallpaper.nix {
inherit (config.lib.stylix) colors;
};
})
];
# to run nspawn in nix sandbox
nix.settings = {
auto-allocate-uids = true;
system-features = [ "uid-range" ];
experimental-features = [
"auto-allocate-uids"
"cgroups"
];
trusted-users = [ config.users.users.applicative.name ];
};
services.restic.backups.niveum = {
extraBackupArgs = [
"--exclude=${config.users.users.applicative.home}/src/nixpkgs/.git"
];
paths = [
config.users.users.applicative.home
];
};
security.sudo.extraRules = [
{
# still required for systemd-nspawn
users = [ config.users.users.applicative.name ];
commands = [ "ALL" ];
}
];
}

View File

@@ -41,7 +41,7 @@
${pkgs.restic}/bin/restic -r ${pkgs.lib.niveum.restic.repository} -p ${config.age.secrets.restic.path} "$@"
'')
(pkgs.writers.writeDashBin "restic-mount" ''
mountdir=$(mktemp -d)
mountdir=$(mktemp -p "$XDG_RUNTIME_DIR" -d "restic-mount-XXXXXXX")
trap clean EXIT
clean() {
rm -r "$mountdir"

View File

@@ -1,10 +0,0 @@
{pkgs, ...}: {
programs.bash = {
promptInit = ''
PS1="$(${pkgs.ncurses}/bin/tput bold)\w \$([[ \$? == 0 ]] && echo \"\[\033[1;32m\]\" || echo \"\[\033[1;31m\]\")\$$(${pkgs.ncurses}/bin/tput sgr0) "'';
interactiveShellInit = ''
set -o vi
'';
completion.enable = true;
};
}

View File

@@ -1,4 +1,5 @@
{pkgs, ...}: {
{ pkgs, ... }:
{
hardware.bluetooth = {
enable = true;
settings.general = {

View File

@@ -1,20 +1,19 @@
{
config,
inputs,
pkgs,
...
}: let
autorenkalender = inputs.autorenkalender.packages.x86_64-linux.default;
in {
}:
{
niveum.bots.autorenkalender = {
enable = true;
time = "07:00";
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = ["@autorenkalender"];
chatIds = [ "@autorenkalender" ];
parseMode = "Markdown";
};
command = "${autorenkalender}/bin/autorenkalender";
command = "${pkgs.autorenkalender}/bin/autorenkalender";
};
niveum.passport.services = [

View File

@@ -3,64 +3,69 @@
lib,
config,
...
}: {
}:
{
niveum.bots.celan = {
enable = true;
time = "08:00";
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = ["@PaulCelan"];
chatIds = [ "@PaulCelan" ];
};
mastodon = {
enable = true;
tokenFile = config.age.secrets.mastodon-token-celan.path;
language = "de";
};
command = toString (pkgs.writers.writePython3 "random-celan.py" { libraries = [pkgs.python3Packages.lxml]; } ''
from lxml import etree
import random
command = toString (
pkgs.writers.writePython3 "random-celan.py" { libraries = [ pkgs.python3Packages.lxml ]; } ''
from lxml import etree
import random
def xml_text(elements):
return "".join("".join(t.itertext()) for t in elements).strip()
def xml_text(elements):
return "".join("".join(t.itertext()) for t in elements).strip()
tree = etree.parse('${pkgs.fetchurl {
url = "http://c.krebsco.de/celan.tei.xml";
hash = "sha256-HgNmJYfhuwyfm+FcNtnnYWpJpIIU1ElHLeLiIFjF9mE=";
}}')
root = tree.getroot()
tree = etree.parse('${
pkgs.fetchurl {
url = "http://c.krebsco.de/celan.tei.xml";
hash = "sha256-HgNmJYfhuwyfm+FcNtnnYWpJpIIU1ElHLeLiIFjF9mE=";
}
}')
root = tree.getroot()
tei = {"tei": "http://www.tei-c.org/ns/1.0"}
tei = {"tei": "http://www.tei-c.org/ns/1.0"}
poems = root.xpath(".//tei:lg[@type='poem']", namespaces=tei)
poems = root.xpath(".//tei:lg[@type='poem']", namespaces=tei)
poem = random.choice(poems)
poem = random.choice(poems)
for stanza in poem.xpath("./tei:lg[@type='stanza']", namespaces=tei):
for line in stanza.xpath('./tei:l', namespaces=tei):
if line.text:
print(line.text.strip())
print()
for stanza in poem.xpath("./tei:lg[@type='stanza']", namespaces=tei):
for line in stanza.xpath('./tei:l', namespaces=tei):
if line.text:
print(line.text.strip())
print()
current_element = poem
while current_element is not None:
if current_element.tag == "{http://www.tei-c.org/ns/1.0}text":
text_element = current_element
current_element = poem
while current_element is not None:
if current_element.tag == "{http://www.tei-c.org/ns/1.0}text":
text_element = current_element
title = xml_text(text_element.xpath("./tei:front/tei:docTitle",
namespaces=tei))
print(f"Aus: #{title.replace(" ", "_")}", end=" ")
title = xml_text(text_element.xpath("./tei:front/tei:docTitle",
namespaces=tei))
print(f"Aus: #{title.replace(" ", "_")}", end=" ")
if date := xml_text(text_element.xpath("./tei:front/tei:docDate",
namespaces=tei)):
print(f"({date})")
break
current_element = current_element.getparent()
if date := xml_text(text_element.xpath("./tei:front/tei:docDate",
namespaces=tei)):
print(f"({date})")
break
current_element = current_element.getparent()
print("\n\n#PaulCelan #Celan #Lyrik #poetry")
'');
print("\n\n#PaulCelan #Celan #Lyrik #poetry")
''
);
};
age.secrets = {

View File

@@ -1,14 +1,13 @@
{
config,
pkgs,
lib,
inputs,
...
}: let
telebots = inputs.telebots.defaultPackage.x86_64-linux;
}:
let
reverseDirectory = "/run/telegram-reverse";
proverbDirectory = "/run/telegram-proverb";
in {
in
{
imports = [
./logotheca.nix
./transits.nix
@@ -25,13 +24,21 @@ in {
telegram-token-kmein.file = ../../secrets/telegram-token-kmein.age;
};
systemd.tmpfiles.rules = map (path:
pkgs.lib.niveum.tmpfilesConfig {
type = "d";
mode = "0750";
age = "1h";
inherit path;
}) [reverseDirectory proverbDirectory];
systemd.tmpfiles.rules =
map
(
path:
pkgs.lib.niveum.tmpfilesConfig {
type = "d";
mode = "0750";
age = "1h";
inherit path;
}
)
[
reverseDirectory
proverbDirectory
];
niveum.passport.services = [
{
@@ -59,12 +66,12 @@ in {
};
systemd.services.telegram-reverse = {
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
description = "Telegram reverse bot";
path = [pkgs.ffmpeg];
enable = true;
path = [ pkgs.ffmpeg ];
enable = false;
script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-reverse
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-reverse
'';
serviceConfig.Restart = "always";
serviceConfig.WorkingDirectory = reverseDirectory;
@@ -72,33 +79,33 @@ in {
};
systemd.services.telegram-streaming-link = {
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
description = "Telegram bot converting YouTube Music <-> Spotify";
enable = true;
enable = false;
script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-streaming-link
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-streaming-link
'';
serviceConfig.Restart = "always";
serviceConfig.LoadCredential = "token:${config.age.secrets.telegram-token-streaming-link.path}";
};
systemd.services.telegram-betacode = {
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
description = "Telegram beta code bot";
enable = true;
enable = false;
script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-betacode
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-betacode
'';
serviceConfig.Restart = "always";
serviceConfig.LoadCredential = "token:${config.age.secrets.telegram-token-betacode.path}";
};
systemd.services.telegram-proverb = {
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
description = "Telegram proverb bot";
enable = true;
enable = false;
script = ''
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${telebots}/bin/telegram-proverb
TELEGRAM_BOT_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" ${pkgs.telebots}/bin/telegram-proverb
'';
serviceConfig.Restart = "always";
serviceConfig.WorkingDirectory = proverbDirectory;

View File

@@ -1,12 +1,9 @@
{
pkgs,
config,
inputs,
lib,
...
}: let
hesychius = inputs.scripts.outPath + "/hesychius/hesychius.txt";
in {
}:
{
niveum.bots.hesychius = {
enable = true;
time = "08:00";
@@ -18,9 +15,9 @@ in {
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = ["@HesychiosAlexandreus"];
chatIds = [ "@HesychiosAlexandreus" ];
};
command = "${pkgs.coreutils}/bin/shuf -n1 ${hesychius}";
command = "${pkgs.coreutils}/bin/shuf -n1 ${pkgs.hesychius}";
};
systemd.timers.bot-hesychius.timerConfig.RandomizedDelaySec = "10h";

View File

@@ -2,14 +2,15 @@
pkgs,
config,
...
}: {
}:
{
niveum.bots.logotheca = {
enable = true;
time = "08/6:00";
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = ["-1001760262519"];
chatIds = [ "-1001760262519" ];
parseMode = "Markdown";
};
matrix = {

View File

@@ -3,31 +3,36 @@
config,
lib,
...
}: let
nachtischsatan-bot = {tokenFile}:
pkgs.writers.writePython3 "nachtischsatan-bot" {
libraries = [pkgs.python3Packages.python-telegram-bot];
} ''
from telegram.ext import Application, ContextTypes, MessageHandler, filters
from telegram import Update
import random
import time
}:
let
nachtischsatan-bot =
{ tokenFile }:
pkgs.writers.writePython3 "nachtischsatan-bot"
{
libraries = [ pkgs.python3Packages.python-telegram-bot ];
}
''
from telegram.ext import Application, ContextTypes, MessageHandler, filters
from telegram import Update
import random
import time
async def flubber(update: Update, context: ContextTypes.DEFAULT_TYPE):
time.sleep(random.randrange(4000) / 1000)
await update.message.reply_text("*flubberflubber*")
async def flubber(update: Update, context: ContextTypes.DEFAULT_TYPE):
time.sleep(random.randrange(4000) / 1000)
await update.message.reply_text("*flubberflubber*")
with open('${tokenFile}', 'r') as tokenFile:
token = tokenFile.read().strip()
application = Application.builder().token(token).build()
application.add_handler(MessageHandler(filters.ALL, flubber))
application.run_polling()
'';
in {
with open('${tokenFile}', 'r') as tokenFile:
token = tokenFile.read().strip()
application = Application.builder().token(token).build()
application.add_handler(MessageHandler(filters.ALL, flubber))
application.run_polling()
'';
in
{
systemd.services.telegram-nachtischsatan = {
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
description = "*flubberflubber*";
enable = true;
script = toString (nachtischsatan-bot {

View File

@@ -2,7 +2,8 @@
config,
pkgs,
...
}: {
}:
{
niveum.bots.nietzsche = {
enable = true;
time = "08:00";
@@ -11,15 +12,17 @@
tokenFile = config.age.secrets.mastodon-token-nietzsche.path;
language = "de";
};
command = toString (pkgs.writers.writeBash "random-nietzsche" ''
set -efu
random_number=$(( ($RANDOM % 10) + 1 ))
if [ "$random_number" -eq 1 ]; then
${pkgs.random-zeno}/bin/random-zeno "/Literatur/M/Nietzsche,+Friedrich"
else
${pkgs.random-zeno}/bin/random-zeno "/Philosophie/M/Nietzsche,+Friedrich"
fi
'');
command = toString (
pkgs.writers.writeBash "random-nietzsche" ''
set -efu
random_number=$(( ($RANDOM % 10) + 1 ))
if [ "$random_number" -eq 1 ]; then
${pkgs.random-zeno}/bin/random-zeno "/Literatur/M/Nietzsche,+Friedrich"
else
${pkgs.random-zeno}/bin/random-zeno "/Philosophie/M/Nietzsche,+Friedrich"
fi
''
);
};
systemd.timers.bot-nietzsche.timerConfig.RandomizedDelaySec = "10h";

View File

@@ -3,7 +3,8 @@
pkgs,
lib,
...
}: {
}:
{
niveum.bots.smyth = {
enable = true;
time = "08:00";
@@ -15,42 +16,44 @@
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = ["@HerbertWeirSmyth"];
chatIds = [ "@HerbertWeirSmyth" ];
};
command = toString (pkgs.writers.writeDash "random-smyth" ''
set -efu
command = toString (
pkgs.writers.writeDash "random-smyth" ''
set -efu
good_curl() {
${pkgs.curl}/bin/curl "$@" \
--compressed \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'DNT: 1' \
-H 'Connection: keep-alive' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: cross-site' \
-H 'Priority: u=0, i' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache'
}
good_curl() {
${pkgs.curl}/bin/curl "$@" \
--compressed \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'DNT: 1' \
-H 'Connection: keep-alive' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: cross-site' \
-H 'Priority: u=0, i' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache'
}
RANDOM_SECTION=$(
good_curl -sSL http://www.perseus.tufts.edu/hopper/xmltoc?doc=Perseus%3Atext%3A1999.04.0007%3Asmythp%3D1 \
| ${pkgs.gnugrep}/bin/grep -o 'ref="[^"]*"' \
| ${pkgs.coreutils}/bin/shuf -n1 \
| ${pkgs.gnused}/bin/sed 's/^ref="//;s/"$//'
)
RANDOM_SECTION=$(
good_curl -sSL http://www.perseus.tufts.edu/hopper/xmltoc?doc=Perseus%3Atext%3A1999.04.0007%3Asmythp%3D1 \
| ${pkgs.gnugrep}/bin/grep -o 'ref="[^"]*"' \
| ${pkgs.coreutils}/bin/shuf -n1 \
| ${pkgs.gnused}/bin/sed 's/^ref="//;s/"$//'
)
url="http://www.perseus.tufts.edu/hopper/text?doc=$RANDOM_SECTION"
good_curl -sSL "$url"\
| ${pkgs.htmlq}/bin/htmlq '#text_main' \
| ${pkgs.gnused}/bin/sed 's/<\/\?hr>//g' \
| ${pkgs.pandoc}/bin/pandoc -f html -t plain --wrap=none
url="http://www.perseus.tufts.edu/hopper/text?doc=$RANDOM_SECTION"
good_curl -sSL "$url"\
| ${pkgs.htmlq}/bin/htmlq '#text_main' \
| ${pkgs.gnused}/bin/sed 's/<\/\?hr>//g' \
| ${pkgs.pandoc}/bin/pandoc -f html -t plain --wrap=none
printf '\n%s\n\n#AncientGreek' "$url"
'');
printf '\n%s\n\n#AncientGreek' "$url"
''
);
};
systemd.timers.bot-smyth.timerConfig.RandomizedDelaySec = "10h";

View File

@@ -2,138 +2,153 @@
pkgs,
config,
...
}: let
}:
let
mastodonEndpoint = "https://social.krebsco.de";
in {
in
{
systemd.services.bot-tlg-wotd = {
# TODO reenable
# once https://github.com/NixOS/nixpkgs/pull/462893 is in stable NixOS
enable = true;
wants = ["network-online.target"];
wants = [ "network-online.target" ];
startAt = "9:30";
path = [ pkgs.jq pkgs.curl pkgs.recode pkgs.deno pkgs.imagemagick pkgs.gawk pkgs.gnugrep pkgs.coreutils ];
path = [
pkgs.jq
pkgs.curl
pkgs.recode
pkgs.deno
pkgs.imagemagick
pkgs.gawk
pkgs.gnugrep
pkgs.coreutils
];
environment = {
NPM_CONFIG_CACHE = "/tmp";
CLTK_DATA = "/tmp";
};
script = ''
set -efux
set -efux
chat_id=@tlgwotd
chat_id=@tlgwotd
export TELEGRAM_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/telegram-token")"
export MASTODON_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/mastodon-token")"
export TELEGRAM_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/telegram-token")"
export MASTODON_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/mastodon-token")"
json_data=$(curl -sSL http://stephanus.tlg.uci.edu/Iris/Wotd | recode html..utf8)
json_data=$(curl -sSL http://stephanus.tlg.uci.edu/Iris/Wotd | recode html..utf8)
word=$(echo "$json_data" | jq -r '.word')
compact_word=$(echo "$word" | sed 's/,.*$//')
definition=$(echo "$json_data" | jq -r '.definition | sub("<.*>"; "") | rtrimstr(" ")')
first_occurrence=$(echo "$json_data" | jq -r '.firstOccurrence')
total_occurrences=$(echo "$json_data" | jq -r '.totalOccurrences')
telegram_caption="*$word* $definition
word=$(echo "$json_data" | jq -r '.word')
compact_word=$(echo "$word" | sed 's/,.*$//')
definition=$(echo "$json_data" | jq -r '.definition | sub("<.*>"; "") | rtrimstr(" ")')
first_occurrence=$(echo "$json_data" | jq -r '.firstOccurrence')
total_occurrences=$(echo "$json_data" | jq -r '.totalOccurrences')
telegram_caption="*$word* $definition
First occurrence (century): $first_occurrence
Number of occurrences (in all Ancient Greek texts): $total_occurrences"
mastodon_caption="$word $definition
First occurrence (century): $first_occurrence
Number of occurrences (in all Ancient Greek texts): $total_occurrences"
mastodon_caption="$word $definition
First occurrence (century): $first_occurrence
Number of occurrences (in all Ancient Greek texts): $total_occurrences"
First occurrence (century): $first_occurrence
Number of occurrences (in all Ancient Greek texts): $total_occurrences"
#ancientgreek #classics #wotd #wordoftheday
#ancientgreek #classics #wotd #wordoftheday
transliteration=$(${pkgs.writers.writePython3 "translit.py" {
libraries = py: [ py.cltk ];
} ''
import sys
from cltk.phonology.grc.transcription import Transcriber
transliteration=$(${
pkgs.writers.writePython3 "translit.py"
{
libraries = py: [ py.cltk ];
}
''
import sys
from cltk.phonology.grc.transcription import Transcriber
probert = Transcriber("Attic", "Probert")
text = " ".join(sys.argv[1:])
ipa = probert.transcribe(text)
probert = Transcriber("Attic", "Probert")
text = " ".join(sys.argv[1:])
ipa = probert.transcribe(text)
print(ipa)
''} "$compact_word")
print(ipa)
''
} "$compact_word")
photo_path=/tmp/output.png
photo_path=/tmp/output.png
hex_to_rgb() {
hex="$1"
r=$(printf "%d" "0x$(echo "$hex" | cut -c2-3)")
g=$(printf "%d" "0x$(echo "$hex" | cut -c4-5)")
b=$(printf "%d" "0x$(echo "$hex" | cut -c6-7)")
echo "$r $g $b"
}
hex_to_rgb() {
hex="$1"
r=$(printf "%d" "0x$(echo "$hex" | cut -c2-3)")
g=$(printf "%d" "0x$(echo "$hex" | cut -c4-5)")
b=$(printf "%d" "0x$(echo "$hex" | cut -c6-7)")
echo "$r $g $b"
}
calculate_luminance() {
r="$1"
g="$2"
b="$3"
calculate_luminance() {
r="$1"
g="$2"
b="$3"
r_l=$(echo "$r" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
g_l=$(echo "$g" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
b_l=$(echo "$b" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
r_l=$(echo "$r" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
g_l=$(echo "$g" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
b_l=$(echo "$b" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
echo "$r_l $g_l $b_l" | awk '{print 0.2126*$1 + 0.7152*$2 + 0.0722*$3}'
}
echo "$r_l $g_l $b_l" | awk '{print 0.2126*$1 + 0.7152*$2 + 0.0722*$3}'
}
hex_color="#$(echo "$compact_word" | md5sum | cut -c 1-6)"
if echo "$hex_color" | grep -qE '^#[0-9A-Fa-f]{6}$'; then
set -- $(hex_to_rgb "$hex_color")
r="$1"
g="$2"
b="$3"
fi
hex_color="#$(echo "$compact_word" | md5sum | cut -c 1-6)"
if echo "$hex_color" | grep -qE '^#[0-9A-Fa-f]{6}$'; then
set -- $(hex_to_rgb "$hex_color")
r="$1"
g="$2"
b="$3"
fi
luminance=$(calculate_luminance "$r" "$g" "$b")
luminance=$(calculate_luminance "$r" "$g" "$b")
threshold="0.1"
echo "$r $g $b"
if [ "$(echo "$luminance" | awk -v threshold="$threshold" '{print ($1 > threshold)}')" -eq 1 ]; then
color1="black"
color2="#333"
else
color1="white"
color2=lightgrey
fi
threshold="0.1"
echo "$r $g $b"
if [ "$(echo "$luminance" | awk -v threshold="$threshold" '{print ($1 > threshold)}')" -eq 1 ]; then
color1="black"
color2="#333"
else
color1="white"
color2=lightgrey
fi
magick -size 1400x846 \
xc:"$hex_color" \
-font "${pkgs.gentium}/share/fonts/truetype/GentiumBookPlus-Bold.ttf" \
-fill "$color1" \
-pointsize 150 -gravity west \
-annotate +100-160 "$compact_word" \
-font "${pkgs.gentium}/share/fonts/truetype/GentiumBookPlus-Regular.ttf" \
-fill "$color2" \
-pointsize 60 -gravity west \
-annotate +100+00 "$transliteration" \
-fill "$color1" \
-annotate +100+120 "$definition" \
-fill "$color2" \
-pointsize 40 -gravity southwest \
-annotate +100+60 "attested $total_occurrences times" \
-pointsize 40 -gravity southeast \
-annotate +100+60 "$(date -I)" \
"$photo_path"
magick -size 1400x846 \
xc:"$hex_color" \
-font "${pkgs.gentium}/share/fonts/truetype/GentiumBookPlus-Bold.ttf" \
-fill "$color1" \
-pointsize 150 -gravity west \
-annotate +100-160 "$compact_word" \
-font "${pkgs.gentium}/share/fonts/truetype/GentiumBookPlus-Regular.ttf" \
-fill "$color2" \
-pointsize 60 -gravity west \
-annotate +100+00 "$transliteration" \
-fill "$color1" \
-annotate +100+120 "$definition" \
-fill "$color2" \
-pointsize 40 -gravity southwest \
-annotate +100+60 "attested $total_occurrences times" \
-pointsize 40 -gravity southeast \
-annotate +100+60 "$(date -I)" \
"$photo_path"
curl -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendPhoto" \
-F "chat_id=\"$chat_id\"" \
-F "photo=@$photo_path" \
-F parse_mode=Markdown \
-F caption="$telegram_caption"
curl -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendPhoto" \
-F "chat_id=\"$chat_id\"" \
-F "photo=@$photo_path" \
-F parse_mode=Markdown \
-F caption="$telegram_caption"
mastodon_upload_response=$(curl -X POST "${mastodonEndpoint}/api/v2/media" \
-H "Authorization: Bearer $MASTODON_TOKEN" \
-F "file=@$photo_path" \
-F "description=$word $definition")
mastodon_image_id=$(echo $mastodon_upload_response | jq -r .id)
curl -X POST "${mastodonEndpoint}/api/v1/statuses" \
-H "Authorization: Bearer $MASTODON_TOKEN" \
-d "status=$mastodon_caption" \
-d "visibility=public" \
-d "media_ids[]=$mastodon_image_id"
mastodon_upload_response=$(curl -X POST "${mastodonEndpoint}/api/v2/media" \
-H "Authorization: Bearer $MASTODON_TOKEN" \
-F "file=@$photo_path" \
-F "description=$word $definition")
mastodon_image_id=$(echo $mastodon_upload_response | jq -r .id)
curl -X POST "${mastodonEndpoint}/api/v1/statuses" \
-H "Authorization: Bearer $MASTODON_TOKEN" \
-d "status=$mastodon_caption" \
-d "visibility=public" \
-d "media_ids[]=$mastodon_image_id"
'';
serviceConfig = {
Type = "oneshot";

View File

@@ -3,7 +3,8 @@
pkgs,
lib,
...
}: let
}:
let
toSymbols = pkgs.writers.writeDash "to-symbols" ''
${pkgs.gnused}/bin/sed '
s/\bTri\b//;
@@ -40,7 +41,8 @@
s/^\s*//
'
'';
in {
in
{
niveum.bots.transits = {
enable = true;
time = "*:0/1";
@@ -51,19 +53,21 @@ in {
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = ["-1001796440545"];
chatIds = [ "-1001796440545" ];
};
command = toString (pkgs.writers.writeDash "common-transits" ''
set -efu
command = toString (
pkgs.writers.writeDash "common-transits" ''
set -efu
now=$(${pkgs.coreutils}/bin/date +%_H:%M | ${pkgs.gnused}/bin/sed 's/^\s*//')
date=$(${pkgs.coreutils}/bin/date +'%m %d %Y')
(
cd ${pkgs.astrolog}/bin
# ./astrolog -Yt -Yd -q 10 22 1999 6:32 -zN Kassel -td $date -R Uranus Neptune Pluto "North Node"
./astrolog -qd $date -zN Berlin -Yt -Yd -d -R Uranus Neptune Pluto "North Node" -A 2
) | ${toSymbols} | ${pkgs.coreutils}/bin/sort -n | ${pkgs.gnugrep}/bin/grep "^$now" || :
'');
now=$(${pkgs.coreutils}/bin/date +%_H:%M | ${pkgs.gnused}/bin/sed 's/^\s*//')
date=$(${pkgs.coreutils}/bin/date +'%m %d %Y')
(
cd ${pkgs.astrolog}/bin
# ./astrolog -Yt -Yd -q 10 22 1999 6:32 -zN Kassel -td $date -R Uranus Neptune Pluto "North Node"
./astrolog -qd $date -zN Berlin -Yt -Yd -d -R Uranus Neptune Pluto "North Node" -A 2
) | ${toSymbols} | ${pkgs.coreutils}/bin/sort -n | ${pkgs.gnugrep}/bin/grep "^$now" || :
''
);
};
age.secrets = {

View File

@@ -2,7 +2,8 @@
config,
pkgs,
...
}: {
}:
{
environment.systemPackages = [
pkgs.cro
pkgs.tor-browser
@@ -13,76 +14,78 @@
home-manager.users.me = {
programs.firefox = {
enable = true;
profiles = let
defaultSettings = {
"beacon.enabled" = false;
"browser.bookmarks.showMobileBookmarks" = true;
"browser.newtab.preload" = false;
"browser.search.isUS" = false;
"browser.search.region" = "DE";
"browser.send_pings" = false;
"browser.shell.checkDefaultBrowser" = false;
"browser.startup.homepage" = "chrome://browser/content/blanktab.html";
"browser.uidensity" = 1;
"browser.urlbar.placeholderName" = "Search";
"datareporting.healthreport.service.enabled" = false;
"datareporting.healthreport.uploadEnabled" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.sessions.current.clean" = true;
"distribution.searchplugins.defaultLocale" = "de-DE";
"general.smoothScroll" = true;
"identity.fxaccounts.account.device.name" = config.networking.hostName;
"network.cookie.cookieBehavior" = 1;
"privacy.donottrackheader.enabled" = true;
"privacy.trackingprotection.enabled" = true;
"privacy.trackingprotection.pbmode.enabled" = true;
"privacy.trackingprotection.socialtracking.enabled" = true;
"services.sync.declinedEngines" = "passwords";
"services.sync.engine.passwords" = false;
"signon.autofillForms" = false;
"signon.rememberSignons" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.cachedClientID" = "";
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.hybridContent.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.prompted" = 2;
"toolkit.telemetry.rejected" = true;
"toolkit.telemetry.server" = "";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.unifiedIsOptIn" = false;
"toolkit.telemetry.updatePing.enabled" = false;
"ui.prefersReducedMotion" = 1;
profiles =
let
defaultSettings = {
"beacon.enabled" = false;
"browser.bookmarks.showMobileBookmarks" = true;
"browser.newtab.preload" = false;
"browser.search.isUS" = false;
"browser.search.region" = "DE";
"browser.send_pings" = false;
"browser.shell.checkDefaultBrowser" = false;
"browser.startup.homepage" = "chrome://browser/content/blanktab.html";
"browser.uidensity" = 1;
"browser.urlbar.placeholderName" = "Search";
"datareporting.healthreport.service.enabled" = false;
"datareporting.healthreport.uploadEnabled" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.sessions.current.clean" = true;
"distribution.searchplugins.defaultLocale" = "de-DE";
"general.smoothScroll" = true;
"identity.fxaccounts.account.device.name" = config.networking.hostName;
"network.cookie.cookieBehavior" = 1;
"privacy.donottrackheader.enabled" = true;
"privacy.trackingprotection.enabled" = true;
"privacy.trackingprotection.pbmode.enabled" = true;
"privacy.trackingprotection.socialtracking.enabled" = true;
"services.sync.declinedEngines" = "passwords";
"services.sync.engine.passwords" = false;
"signon.autofillForms" = false;
"signon.rememberSignons" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.cachedClientID" = "";
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.hybridContent.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.prompted" = 2;
"toolkit.telemetry.rejected" = true;
"toolkit.telemetry.server" = "";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.unifiedIsOptIn" = false;
"toolkit.telemetry.updatePing.enabled" = false;
"ui.prefersReducedMotion" = 1;
};
in
{
default = {
id = 0;
isDefault = true;
settings = defaultSettings;
# extensions = with pkgs.nur.repos.rycee.firefox-addons; [
# ublock-origin
# darkreader
# sponsorblock
# consent-o-matic
# i-dont-care-about-cookies
# # auto-tab-discard TODO what is this
# ];
userChrome = ''
#TabsToolbar {
visibility: collapse !important;
}
'';
};
};
in {
default = {
id = 0;
isDefault = true;
settings = defaultSettings;
# extensions = with pkgs.nur.repos.rycee.firefox-addons; [
# ublock-origin
# darkreader
# sponsorblock
# consent-o-matic
# i-dont-care-about-cookies
# # auto-tab-discard TODO what is this
# ];
userChrome = ''
#TabsToolbar {
visibility: collapse !important;
}
'';
};
};
};
};
home-manager.users.me = {
stylix.targets.firefox.profileNames = ["default"];
stylix.targets.firefox.profileNames = [ "default" ];
};
environment.variables.BROWSER = "firefox";

View File

@@ -1,29 +1,38 @@
{pkgs, ...}:
# https://paste.sr.ht/~erictapen/11716989e489b600f237041b6d657fdf0ee17b34
let
name = "dst-root-ca-x3.pem";
certificate = pkgs.stdenv.mkDerivation {
inherit name;
src = builtins.toFile "${name}.sed" ''
1,/DST Root CA X3/d
1,/-----END CERTIFICATE-----/p
'';
nativeBuildInputs = with pkgs; [cacert gnused];
phases = "installPhase";
installPhase = ''
${pkgs.gnused}/bin/sed -n -f $src ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt > $out
'';
};
in {
networking.wireless.networks."36C3" = {
auth = ''
key_mgmt=WPA-EAP
eap=TTLS
identity="kmein"
password=" "
ca_cert="${certificate}"
altsubject_match="DNS:radius.c3noc.net"
phase2="auth=PAP"
'';
{ pkgs, ... }:
{
networking.networkmanager.ensureProfiles.profiles = {
"39C3" = {
connection = {
id = "39C3";
type = "wifi";
};
wifi = {
mode = "infrastructure";
ssid = "39C3";
};
wifi-security = {
auth-alg = "open";
key-mgmt = "wpa-eap";
};
"802-1x" = {
anonymous-identity = "39C3";
eap = "ttls;";
identity = "39C3";
password = "39C3";
phase2-auth = "pap";
altsubject-matches = "DNS:radius.c3noc.net";
ca-cert = "${builtins.fetchurl {
url = "https://letsencrypt.org/certs/isrgrootx1.pem";
sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92";
}}";
};
ipv4 = {
method = "auto";
};
ipv6 = {
addr-gen-mode = "default";
method = "auto";
};
};
};
}

View File

@@ -2,6 +2,7 @@
config,
pkgs,
...
}: {
}:
{
services.clipmenu.enable = true;
}

View File

@@ -3,7 +3,8 @@
lib,
pkgs,
...
}: {
}:
{
systemd.user.services.systemd-tmpfiles-clean = {
enable = true;
wantedBy = [ "default.target" ];
@@ -14,27 +15,40 @@
};
};
systemd.user.tmpfiles.users.me.rules = map pkgs.lib.niveum.tmpfilesConfig [
{
type = "d";
mode = "0755";
age = "7d";
path = "${config.users.users.me.home}/sync/Downloads";
}
{
type = "d";
mode = "0755";
age = "7d";
path = "${config.users.users.me.home}/cloud/nextcloud/tmp";
}
] ++ map (path: pkgs.lib.niveum.tmpfilesConfig {
type = "L+";
user = config.users.users.me.name;
group = config.users.users.me.group;
mode = "0755";
argument = "${config.users.users.me.home}/sync/${path}";
path = "${config.users.users.me.home}/${path}";
}) [".ssh" ".gnupg" ".pki" ".local/share/aerc"];
systemd.user.tmpfiles.users.me.rules =
map pkgs.lib.niveum.tmpfilesConfig [
{
type = "d";
mode = "0755";
age = "7d";
path = "${config.users.users.me.home}/sync/Downloads";
}
{
type = "d";
mode = "0755";
age = "7d";
path = "${config.users.users.me.home}/cloud/nextcloud/tmp";
}
]
++
map
(
path:
pkgs.lib.niveum.tmpfilesConfig {
type = "L+";
user = config.users.users.me.name;
group = config.users.users.me.group;
mode = "0755";
argument = "${config.users.users.me.home}/sync/${path}";
path = "${config.users.users.me.home}/${path}";
}
)
[
".ssh"
".gnupg"
".pki"
".local/share/aerc"
];
services.gnome.gnome-keyring.enable = true;
security.pam.services.lightdm.enableGnomeKeyring = true;
@@ -48,20 +62,22 @@
systemd.user.services.nextcloud-syncer = {
enable = false;
wants = ["network-online.target"];
wantedBy = ["default.target"];
wants = [ "network-online.target" ];
wantedBy = [ "default.target" ];
startAt = "*:00/10";
script = let
kieran = {
user = "kieran";
passwordFile = config.age.secrets.nextcloud-password-kieran.path;
endpoint = "https://cloud.kmein.de";
target = "${config.users.users.me.home}/notes";
};
in ''
mkdir -p ${lib.escapeShellArg kieran.target}
${pkgs.nextcloud-client}/bin/nextcloudcmd --non-interactive --user ${kieran.user} --password "$(cat ${kieran.passwordFile})" --path /Notes ${lib.escapeShellArg kieran.target} ${kieran.endpoint}
'';
script =
let
kieran = {
user = "kieran";
passwordFile = config.age.secrets.nextcloud-password-kieran.path;
endpoint = "https://cloud.kmein.de";
target = "${config.users.users.me.home}/notes";
};
in
''
mkdir -p ${lib.escapeShellArg kieran.target}
${pkgs.nextcloud-client}/bin/nextcloudcmd --non-interactive --user ${kieran.user} --password "$(cat ${kieran.passwordFile})" --path /Notes ${lib.escapeShellArg kieran.target} ${kieran.endpoint}
'';
serviceConfig = {
Type = "oneshot";
Restart = "on-failure";
@@ -77,19 +93,22 @@
} | ${pkgs.fzf}/bin/fzf)"
exec ${pkgs.zathura}/bin/zathura "$book"
'')
(let
kieran = {
user = "kieran.meinhardt@gmail.com";
passwordFile = config.age.secrets.mega-password.path;
};
megatools = command: ''${pkgs.megatools}/bin/megatools ${command} --username ${lib.escapeShellArg kieran.user} --password "$(cat ${kieran.passwordFile})"'';
in
(
let
kieran = {
user = "kieran.meinhardt@gmail.com";
passwordFile = config.age.secrets.mega-password.path;
};
megatools =
command:
''${pkgs.megatools}/bin/megatools ${command} --username ${lib.escapeShellArg kieran.user} --password "$(cat ${kieran.passwordFile})"'';
in
pkgs.writers.writeDashBin "book-mega" ''
set -efu
selection="$(${megatools "ls"} | ${pkgs.fzf}/bin/fzf)"
test -n "$selection" || exit 1
tmpdir="$(mktemp -d)"
tmpdir="$(mktemp -p "$XDG_RUNTIME_DIR" -d)"
trap clean EXIT
clean() {
rm -rf "$tmpdir"
@@ -100,7 +119,8 @@
${megatools "get"} "$selection"
exec ${pkgs.zathura}/bin/zathura "$(basename "$selection")"
)
'')
''
)
];
age.secrets.mega-password = {
@@ -122,13 +142,22 @@
devices = pkgs.lib.niveum.syncthingIds;
folders = {
"${config.users.users.me.home}/sync" = {
devices = ["kabsa" "manakish" "fatteh"];
devices = [
"kabsa"
"manakish"
"fatteh"
];
label = "sync";
versioning.type = "trashcan";
versioning.params.cleanoutDays = 100;
};
"${config.users.users.me.home}/mobile" = {
devices = ["kabsa" "manakish" "fatteh" "kibbeh"];
devices = [
"kabsa"
"manakish"
"fatteh"
"kibbeh"
];
id = "mobile";
label = "mobile";
versioning.type = "trashcan";

View File

@@ -2,7 +2,6 @@
pkgs,
lib,
config,
inputs,
...
}:
let
@@ -10,8 +9,6 @@ let
in
{
imports = [
inputs.self.nixosModules.system-dependent
inputs.self.nixosModules.power-action
{
boot.supportedFilesystems = [ "ntfs" ];
}
@@ -19,9 +16,6 @@ in
nixpkgs = {
config = {
allowUnfree = true;
packageOverrides = pkgs: {
dmenu = pkgs.writers.writeDashBin "dmenu" ''exec ${pkgs.rofi}/bin/rofi -dmenu "$@"'';
};
permittedInsecurePackages = [
];
};
@@ -37,7 +31,7 @@ in
file = ../secrets/di-fm-key.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
mode = "440";
};
restic = {
file = ../secrets/restic.age;
@@ -72,6 +66,8 @@ in
extraGroups = [
"pipewire"
"audio"
"lp"
"scanner"
];
};
@@ -90,14 +86,9 @@ in
swallow = command: "${pkgs.swallow}/bin/swallow ${command}";
in
{
o = "${pkgs.xdg-utils}/bin/xdg-open";
ns = "nix-shell --run zsh";
pbcopy = "${pkgs.xclip}/bin/xclip -selection clipboard -in";
pbpaste = "${pkgs.xclip}/bin/xclip -selection clipboard -out";
tmux = "${pkgs.tmux}/bin/tmux -2";
sxiv = swallow "${pkgs.nsxiv}/bin/nsxiv";
zathura = swallow "${pkgs.zathura}/bin/zathura";
im = "${pkgs.openssh}/bin/ssh weechat@makanek -t tmux attach-session -t IM";
im = "${pkgs.openssh}/bin/ssh weechat@makanek -t screen -x weechat";
yt = "${pkgs.yt-dlp}/bin/yt-dlp --add-metadata -ic"; # Download video link
yta = "${pkgs.yt-dlp}/bin/yt-dlp --add-metadata --audio-format mp3 --audio-quality 0 -xic"; # Download with audio
};
@@ -109,38 +100,21 @@ in
};
}
{
services.displayManager = {
autoLogin = {
enable = true;
user = config.users.users.me.name;
};
};
services.xserver = {
enable = true;
displayManager.lightdm = {
enable = true;
greeters.gtk = {
enable = true;
indicators = [
"~spacer"
"~host"
"~spacer"
"~session"
"~power"
];
};
};
};
services.power-profiles-daemon.enable = true;
}
{
programs.gnupg = {
agent = {
enable = true;
pinentryPackage = pkgs.pinentry-qt;
settings = let defaultCacheTtl = 2 * 60 * 60; in {
default-cache-ttl = defaultCacheTtl;
max-cache-ttl = 4 * defaultCacheTtl;
};
settings =
let
defaultCacheTtl = 2 * 60 * 60;
in
{
default-cache-ttl = defaultCacheTtl;
max-cache-ttl = 4 * defaultCacheTtl;
};
};
};
@@ -173,58 +147,39 @@ in
home-manager.backupFileExtension = "bak";
}
{
systemd.user.services.udiskie = {
after = [ "udisks2.service" ];
wants = [ "udisks2.service" ];
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${pkgs.udiskie}/bin/udiskie --verbose --no-config --notify";
};
};
services.udisks2.enable = true;
programs.dconf.enable = true;
home-manager.users.me = {
dconf.enable = true;
dconf.settings = {
# Change the default terminal for Nemo
"org/cinnamon/desktop/applications/terminal".exec = pkgs.lib.niveum.defaultApplications.terminal;
"org/cinnamon/desktop/applications/terminal".exec = lib.getExe pkgs.niphas-terminal;
};
};
}
./android.nix
./admin-essentials.nix
./stylix.nix
./alacritty.nix
./backup.nix
./bash.nix
./bluetooth.nix
./aerc.nix
./ccc.nix
./khal.nix
./browser.nix
./clipboard.nix
./cloud.nix
./direnv.nix
./docker.nix
./dunst.nix
./fonts.nix
./fzf.nix
./git.nix
./hledger.nix
./htop.nix
./lix.nix
./uni.nix
./i3.nix
./i3status-rust.nix
# ./i3.nix
./graphical
./keyboard
./mycelium.nix
./kdeconnect.nix
{ services.upower.enable = true; }
./lb.nix
./mpv.nix
./mime.nix
./neovim.nix
./nix.nix
./newsboat.nix
./editor.nix
./flameshot.nix
./packages.nix
./virtualization.nix
@@ -232,38 +187,38 @@ in
./polkit.nix
./printing.nix
./redshift.nix
./retiolum.nix
./rofi.nix
./spacetime.nix
./ssh.nix
./sshd.nix
./sound.nix
./sudo.nix
./tmux.nix
./unclutter.nix
./vscode.nix
./watson.nix
./wallpaper.nix
./zsh.nix
{
home-manager.users.me.home.file.".zshrc".text = ''
# nothing to see here
'';
}
./tor.nix
./mastodon-bot.nix
{
programs.zsh.interactiveShellInit = ''
hash -d nixos=/etc/nixos niveum=${config.users.users.me.home}/sync/src/niveum
'';
home-manager.users.me = {
xdg.userDirs = let pictures = "${config.users.users.me.home}/cloud/nextcloud/Bilder"; in {
enable = true;
documents = "${config.users.users.me.home}/cloud/nextcloud/Documents";
desktop = "/tmp";
download = "${config.users.users.me.home}/sync/Downloads";
music = "${config.users.users.me.home}/mobile/audio";
publicShare = "${config.users.users.me.home}/cloud/nextcloud/tmp";
videos = pictures;
pictures = pictures;
};
xdg.userDirs =
let
pictures = "${config.users.users.me.home}/cloud/nextcloud/Bilder";
in
{
enable = true;
documents = "${config.users.users.me.home}/cloud/nextcloud/Documents";
desktop = "/tmp";
download = "${config.users.users.me.home}/sync/Downloads";
music = "${config.users.users.me.home}/mobile/audio";
publicShare = "${config.users.users.me.home}/cloud/nextcloud/tmp";
videos = pictures;
pictures = pictures;
};
};
}
];

View File

@@ -1,37 +0,0 @@
{pkgs, ...}: let
nixify = pkgs.writers.writeDashBin "nixify" ''
set -efuC
if [ ! -e ./.envrc ]; then
echo use_nix > .envrc
direnv allow
fi
if [ ! -e shell.nix ]; then
cat > shell.nix <<'EOF'
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = [];
}
EOF
''${EDITOR:-vim} shell.nix
fi
'';
in {
environment.systemPackages = [pkgs.direnv nixify];
home-manager.users.me.programs.direnv = {
enable = true;
stdlib = builtins.readFile "${
pkgs.fetchFromGitHub {
owner = "Mic92";
repo = "dotfiles";
rev = "a0a9b7e358fa70a85cd468f8ca1fbb02ae0a91df";
sha256 = "1y9h5s1lf59sczsm0ksq2x1yhl98ba9lwk5yil3q53rg7n4574pg";
}
}/home/.direnvrc";
};
programs.zsh.interactiveShellInit = ''
eval "$(${pkgs.direnv}/bin/direnv hook zsh)"
'';
}

View File

@@ -1,16 +0,0 @@
{
lib,
pkgs,
...
}: {
virtualisation.docker = {
enable = true;
# for ICE wifi, ref https://gist.github.com/sunsided/7840e89ff4e11b64a2d7503fafa0290c
extraOptions = lib.concatStringsSep " " [
"--bip=172.39.1.5/24"
"--fixed-cidr=172.39.1.0/25"
];
};
users.users.me.extraGroups = ["docker"];
environment.systemPackages = [pkgs.docker pkgs.docker-compose];
}

View File

@@ -1,64 +0,0 @@
{
lib,
pkgs,
...
}: let
sgr = code: string: ''\u001b[${code}m${string}\u001b[0m'';
in {
environment.systemPackages = [
(pkgs.writers.writeDashBin "notifications" ''
${pkgs.dunst}/bin/dunstctl history \
| ${pkgs.jq}/bin/jq -r '
.data[]
| map("${sgr "90" ''\(.appname.data)''} ${sgr "1" ''\(.summary.data)''} ${sgr "31" ''\(.body.data | gsub("\n"; " | "))''}")
| join("\n")'
'')
];
home-manager.users.me.services.dunst = {
enable = true;
iconTheme = pkgs.lib.niveum.theme.icon;
settings = {
global = {
transparency = 10;
geometry = "200x5-30+20";
follow = "mouse";
indicate_hidden = true;
notification_height = 0;
separator_height = 2;
padding = 8;
horizontal_padding = 8;
sort = true;
markup = "full";
format = "%a\\n<b>%s</b>\\n%b";
alignment = "left";
show_age_threshold = 60;
bounce_freq = 0;
word_wrap = true;
ellipsize = "middle";
ignore_newline = false;
stack_duplicates = true;
hide_duplicate_count = false;
max_icon_size = 32;
sticky_history = true;
history_length = 20;
dmenu = "${pkgs.rofi}/bin/rofi -display-run dunst -show run";
browser = pkgs.lib.niveum.defaultApplications.browser;
verbosity = "mesg";
corner_radius = 0;
mouse_left_click = "do_action";
mouse_right_click = "close_current";
mouse_middle_click = "close_all";
};
urgency_low = {
timeout = 5;
};
urgency_normal = {
timeout = 10;
};
urgency_critical = {
timeout = 0;
};
};
};
}

View File

@@ -1,13 +1,10 @@
{
pkgs,
lib,
config,
...
}: {
environment.variables.EDITOR = pkgs.lib.mkForce "nvim";
environment.shellAliases.vi = "nvim";
environment.shellAliases.vim = "nvim";
environment.shellAliases.view = "nvim -R";
}:
{
home-manager.users.me = {
editorconfig = {
enable = true;
@@ -34,17 +31,13 @@
};
environment.systemPackages = [
(pkgs.writers.writeDashBin "vim" ''neovim "$@"'')
(pkgs.vim-kmein.override {
# stylixColors = config.lib.stylix.colors;
colorscheme = "base16-gruvbox-dark-medium";
})
pkgs.vim-typewriter
pkgs.dawn-editor
# language servers
pkgs.pyright
pkgs.haskellPackages.haskell-language-server
pkgs.texlab
pkgs.nil
pkgs.gopls
pkgs.nixfmt-rfc-style
pkgs.rust-analyzer

View File

@@ -2,7 +2,8 @@
lib,
pkgs,
...
}: {
}:
{
home-manager.users.me = {
services.flameshot = {
enable = true;

View File

@@ -1,20 +1,25 @@
{
pkgs,
...
}: let
zip-font = name: arguments: let
directory = pkgs.fetchzip arguments;
in
pkgs.runCommand name {} ''
}:
let
zip-font =
name: arguments:
let
directory = pkgs.fetchzip arguments;
in
pkgs.runCommand name { } ''
mkdir -p $out/share/fonts/{truetype,opentype,woff}
${pkgs.findutils}/bin/find ${directory} -name '*.ttf' -exec install '{}' $out/share/fonts/truetype \;
${pkgs.findutils}/bin/find ${directory} -name '*.otf' -exec install '{}' $out/share/fonts/opentype \;
${pkgs.findutils}/bin/find ${directory} -name '*.woff' -exec install '{}' $out/share/fonts/woff \;
'';
simple-ttf = name: arguments: let
file = pkgs.fetchurl arguments;
in
pkgs.runCommand name {} ''
simple-ttf =
name: arguments:
let
file = pkgs.fetchurl arguments;
in
pkgs.runCommand name { } ''
mkdir -p $out/share/fonts/truetype
install ${file} $out/share/fonts/truetype
'';
@@ -57,7 +62,8 @@
url = "https://github.com/microsoft/font-tools/raw/1092cb23520967830001a0807eb21d6a44dda522/EgyptianOpenType/font/eot.ttf";
sha256 = "1n294vhcx90270pnsw1dbk6izd61fjvbnjrh4hcf98ff3s540x0c";
};
in {
in
{
fonts = {
enableDefaultPackages = true;
fontDir.enable = true;
@@ -117,12 +123,28 @@ in {
vollkorn
zilla-slab
]; # google-fonts league-of-moveable-type
fontconfig.defaultFonts = let emoji = ["Noto Color Emoji"]; in {
monospace = ["Noto Sans Mono"] ++ emoji;
serif = ["Noto Serif" "Noto Naskh Arabic" "Noto Serif Devanagari"];
sansSerif = ["Noto Sans Display" "Noto Naskh Arabic" "Noto Sans Hebrew" "Noto Sans Devanagari" "Noto Sans CJK JP" "Noto Sans Coptic" "Noto Sans Syriac Western"];
inherit emoji;
};
fontconfig.defaultFonts =
let
emoji = [ "Noto Color Emoji" ];
in
{
monospace = [ "Noto Sans Mono" ] ++ emoji;
serif = [
"Noto Serif"
"Noto Naskh Arabic"
"Noto Serif Devanagari"
];
sansSerif = [
"Noto Sans Display"
"Noto Naskh Arabic"
"Noto Sans Hebrew"
"Noto Sans Devanagari"
"Noto Sans CJK JP"
"Noto Sans Coptic"
"Noto Sans Syriac Western"
];
inherit emoji;
};
# xelatex fails with woff files
# ref https://tex.stackexchange.com/questions/392144/xelatex-and-fontspec-crash-trying-to-find-woff-file-for-some-fonts-but-not-other
fontconfig.localConf = ''

View File

@@ -1,24 +0,0 @@
{pkgs, ...}: {
programs.fzf = {
fuzzyCompletion = true;
keybindings = true;
};
home-manager.users.me = {
programs.fzf = let
defaultCommand = "${pkgs.fd}/bin/fd --type f --strip-cwd-prefix --follow --no-ignore-vcs --exclude .git";
in {
enable = true;
defaultCommand = defaultCommand;
defaultOptions = ["--height=40%"];
changeDirWidgetCommand = "${pkgs.fd}/bin/fd --type d";
changeDirWidgetOptions = [
"--preview='${pkgs.tree}/bin/tree -L 1 {}'"
"--bind=space:toggle-preview"
"--preview-window=hidden"
];
fileWidgetCommand = defaultCommand;
fileWidgetOptions = ["--preview='head -$LINES {}'"];
};
};
}

View File

@@ -10,6 +10,10 @@
# pkgs.freeciv
# pkgs.lincity-ng
# pkgs.superTuxKart
pkgs.morris
pkgs.gnome-chess
pkgs.gnuchess
];
networking.firewall = {
# for 0ad multiplayer

View File

@@ -1,52 +0,0 @@
{
pkgs,
lib,
...
}:
{
environment.systemPackages = [
pkgs.mr
pkgs.gitFull
pkgs.git-crypt
pkgs.gitflow
pkgs.gh
pkgs.git-extras
# pkgs.git-trim
pkgs.git-absorb
pkgs.gitstats
pkgs.patch
pkgs.patchutils
];
environment.shellAliases = {
gf = "git-flow";
g = "git";
};
home-manager.users.me = {
programs.git = {
enable = true;
package = pkgs.gitFull;
settings.alias = {
br = "branch";
co = "checkout";
ci = "commit";
cm = "commit -m";
amend = "commit --amend";
st = "status -s";
unstage = "reset HEAD --";
diffs = "diff --staged";
last = "log -1 HEAD";
logs = "log --pretty=oneline";
graph = "log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all";
};
ignores = pkgs.lib.niveum.ignorePaths;
settings.user.name = pkgs.lib.niveum.kieran.name;
settings.user.email = pkgs.lib.niveum.kieran.email;
settings.pull.ff = "only";
settings.rebase.autoStash = true;
settings.merge.autoStash = true;
settings.push.autoSetupRemove = true;
};
};
}

View File

@@ -0,0 +1,44 @@
{
pkgs,
lib,
config,
...
}:
{
programs.hyprland = {
enable = true;
withUWSM = true;
xwayland.enable = true;
package = pkgs.hyprland;
portalPackage = pkgs.xdg-desktop-portal-hyprland;
};
programs.ydotool.enable = true;
xdg.portal = {
enable = true;
extraPortals = [
pkgs.xdg-desktop-portal-hyprland
pkgs.xdg-desktop-portal-gtk
];
config.common.default = "*";
};
services.dbus = {
implementation = "broker";
# needed for GNOME services outside of GNOME (?)
packages = [ pkgs.gcr ];
};
environment.systemPackages = [
pkgs.xdg-desktop-portal
pkgs.xdg-desktop-portal-hyprland
];
services.getty.autologinOnce = true;
services.getty.autologinUser = config.users.users.me.name;
home-manager.users.me = import ./home-manager.nix {
inherit lib pkgs config;
};
}

View File

@@ -0,0 +1,415 @@
{
lib,
pkgs,
config,
...
}:
let
klem = pkgs.klem.override {
options.dmenu = "${pkgs.dmenu}/bin/dmenu -i -p klem";
options.scripts = {
"p.r paste" = pkgs.writers.writeDash "p.r" ''
${pkgs.curl}/bin/curl -fSs http://p.r --data-binary @- \
| ${pkgs.coreutils}/bin/tail --lines=1 \
| ${pkgs.gnused}/bin/sed 's/\\<r\\>/krebsco.de/'
'';
"envs.sh paste" = pkgs.writers.writeDash "envs-host" ''
${pkgs.curl}/bin/curl -F "file=@-" https://envs.sh
'';
# this segfaults
# "envs.sh mirror" = pkgs.writers.writeDash "envs-mirror" ''
# ${pkgs.curl}/bin/curl -F "url=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
# '';
"envs.sh shorten" = pkgs.writers.writeDash "envs-shorten" ''
${pkgs.curl}/bin/curl -F "shorten=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
'';
"go.r shorten" = pkgs.writers.writeDash "go.r" ''
${pkgs.curl}/bin/curl -fSs http://go.r -F "uri=$(${pkgs.coreutils}/bin/cat)"
'';
"4d2.org paste" = pkgs.writers.writeDash "4d2-paste" ''
${pkgs.curl}/bin/curl -F "file=@-" https://depot.4d2.org/
'';
"0x0.st shorten" = pkgs.writers.writeDash "0x0.st" ''
${pkgs.curl}/bin/curl -fSs https://0x0.st -F "shorten=$(${pkgs.coreutils}/bin/cat)"
'';
"rot13" = pkgs.writers.writeDash "rot13" ''
${pkgs.coreutils}/bin/tr '[A-Za-z]' '[N-ZA-Mn-za-m]'
'';
"ipa" = pkgs.writers.writeDash "ipa" ''
${pkgs.ipa}/bin/ipa
'';
"betacode" = pkgs.writers.writeDash "betacode" ''
${pkgs.betacode}/bin/betacode
'';
"curl" = pkgs.writers.writeDash "curl" ''
${pkgs.curl}/bin/curl -fSs "$(${pkgs.coreutils}/bin/cat)"
'';
ocr = pkgs.writers.writeDash "ocr" ''
${pkgs.tesseract4}/bin/tesseract -l eng+deu - stdout
'';
emojai = pkgs.writers.writeDash "emojai" ''
${pkgs.curl}/bin/curl https://www.emojai.app/api/generate -X POST -H 'Content-Type: application/json' --data-raw "$(${pkgs.jq}/bin/jq -sR '{emoji:.}')" | ${pkgs.jq}/bin/jq -r .result
'';
};
};
arabic.workspaces = [
"١"
"٢"
"٣"
"٤"
"٥"
"٦"
"٧"
"٨"
"٩"
"١٠"
];
arabic.music = "الموسيقى";
arabic.obsidian = "السبج";
hindi.workspaces = [
""
""
""
""
""
""
""
""
""
""
];
hindi.music = "";
hindi.obsidian = "ि";
hebrew.workspaces = [
"א"
"ב"
"ג"
"ד"
"ה"
"ו"
"ז"
"ח"
"ט"
"י"
];
hebrew.music = "מוסיקה";
hebrew.obsidian = "אובסידיאן";
latin.workspaces = [
""
""
""
""
""
""
""
""
""
""
];
latin.music = "MVSICA";
latin.obsidian = "NOSCENDA";
greek.workspaces = [
"Α"
"Β"
"Γ"
"Δ"
"Ε"
"Ϛ"
"Ζ"
"Η"
"Θ"
"Ι"
];
greek.music = "ΜΟΥΣΙΚΗ";
greek.obsidian = "ΥΠΟΜΝΗΜΑΤΑ";
language = greek;
in
{
services.mako = {
enable = true;
settings.default-timeout = 10 * 1000;
};
programs.ashell = {
enable = true;
settings = {
# position = "bottom";
modules = {
left = [
"Workspaces"
[
"WindowTitle"
]
];
center = [ "Clock" ];
right = [
"KeyboardLayout"
[
"Tray"
"SystemInfo"
"Settings"
]
];
};
workspaces = {
enable_workspace_filling = false;
disable_special_workspaces = true;
visibility_mode = "MonitorSpecific";
workspace_names = language.workspaces;
};
keyboard_layout.labels = {
"de" = "🇩🇪";
};
window_title = {
mode = "Title";
truncate_title_after_length = 75;
};
media_player = {
max_title_length = 40;
};
system_info.indicators = [
"Cpu"
"Memory"
{ Disk = "/"; }
];
clock.format = "%Y-%m-%d (%j %a %W) %H:%M";
settings.indicators = [
"IdleInhibitor"
"PowerProfile"
"Audio"
"Bluetooth"
"Network"
"Vpn"
"Battery"
];
appearance = {
font_name = config.stylix.fonts.sansSerif.name;
backdrop = 0.3;
scale_factor = 0.85;
# style = "Solid";
};
};
};
services.hypridle = {
enable = true;
settings = {
general = {
after_sleep_cmd = "hyprctl dispatch dpms on";
ignore_dbus_inhibit = false;
lock_cmd = "hyprlock";
};
listener = [
{
timeout = 900;
on-timeout = "hyprlock";
}
{
timeout = 1200;
on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on";
}
];
};
};
programs.hyprlock = {
enable = true;
settings = {
animations.enabled = false;
general = {
hide_cursor = true;
ignore_empty_input = true;
};
};
};
gtk = {
enable = true;
iconTheme = {
name = "Adwaita";
package = pkgs.adwaita-icon-theme;
};
};
wayland.windowManager.hyprland =
let
mod = "SUPER";
in
{
enable = true;
systemd.enable = false;
systemd.variables = [ "--all" ];
settings = {
env = [
"XCURSOR_SIZE,${toString config.stylix.cursor.size}" # TODO
"HYPRCURSOR_SIZE,${toString config.stylix.cursor.size}" # TODO
"HYPRCURSOR_THEME,${config.stylix.cursor.name}"
"QT_QPA_PLATFORM=wayland"
"GDK_BACKEND=wayland"
"NIXOS_OZONE_WL=1"
];
permission = [
"${pkgs.xdg-desktop-portal-hyprland}/libexec/.xdg-desktop-portal-hyprland-wrapped, screencopy, allow"
];
monitor = [
"eDP-1, 1920x1080, 0x0, 1" # fatteh's display
"desc:Samsung Electric Company C27F390 HTQH602129, 1920x1080, 0x-1080, 1" # home
"desc:Dell Inc. DELL P2419HC 8L0FL03, 1920x1080, 0x-1080, 1" # amo
", preferred, auto, 1"
];
exec-once = [
(lib.getExe pkgs.ashell)
"hyprctl dispatch exec \"[workspace special:${language.obsidian} silent] obsidian\""
(lib.getExe pkgs.niphas-clipboard-watcher)
(lib.getExe pkgs.niphas-redshift)
(lib.getExe pkgs.niphas-set-wallpaper)
];
device = [
{
name = "elan-touchscreen";
enabled = false;
}
];
general = {
gaps_in = 2;
gaps_out = 2;
border_size = 2;
resize_on_border = true;
allow_tearing = false;
layout = "dwindle";
};
decoration = {
rounding = 0;
rounding_power = 0;
active_opacity = 1.0;
inactive_opacity = 1.0;
shadow = {
enabled = false;
range = 4;
render_power = 3;
};
blur = {
enabled = false;
size = 3;
passes = 1;
vibrancy = 0.17;
};
};
animations = {
enabled = true;
animation = [
"global, 1, 2, default"
];
};
dwindle = {
preserve_split = true;
};
master.new_status = "master";
gesture = [
"3, horizontal, workspace"
];
input = {
kb_layout = "de";
kb_variant = "T3";
kb_options = "compose:caps,grp:ctrls_toggle";
follow_mouse = 1;
sensitivity = 0;
touchpad.natural_scroll = false;
};
bindm = [
"${mod}, mouse:272, movewindow"
"${mod}, mouse:273, resizewindow"
];
bindel = [
",XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"
",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
",XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+"
",XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%-"
", Print, exec, ${lib.getExe pkgs.niphas-screenshot}"
];
bindl = [
", XF86AudioNext, exec, playerctl next"
", XF86AudioPause, exec, playerctl play-pause"
", XF86AudioPlay, exec, playerctl play-pause"
", XF86AudioPrev, exec, playerctl previous"
];
bind = [
"${mod}, Return, exec, ${lib.getExe pkgs.niphas-terminal}"
"${mod} SHIFT, Q, killactive,"
"${mod} SHIFT, R, exit,"
"${mod}, t, exec, ${lib.getExe pkgs.niphas-file-browser}"
"${mod}, Y, exec, ${lib.getExe pkgs.niphas-web-browser}"
"${mod}, Q, exec, ${lib.getExe pkgs.niphas-clipman}"
"${mod}, u, exec, ${lib.getExe pkgs.unicodmenu}"
"${mod}, p, exec, ${lib.getExe pkgs.rofi-pass-wayland}"
"${mod} SHIFT, Z, togglefloating,"
"${mod}, D, exec, ${lib.getExe pkgs.rofi} -show run"
"${mod}, E, togglesplit," # dwindle
"${mod}, F, fullscreen"
"${mod}, G, moveoutofgroup"
"${mod} SHIFT, G, togglegroup"
"${mod}, h, movefocus, l"
"${mod}, l, movefocus, r"
"${mod}, k, movefocus, u"
"${mod}, j, movefocus, d"
"${mod}, F12, exec, ${klem}/bin/klem"
"${mod} SHIFT, W, exec, hyprlock"
"${mod} SHIFT, H, movewindow, l"
"${mod} SHIFT, L, movewindow, r"
"${mod} SHIFT, K, movewindow, u"
"${mod} SHIFT, J, movewindow, d"
"${mod}, S, togglespecialworkspace, ${language.music}"
"${mod} SHIFT, S, movetoworkspace, special:${language.music}"
"${mod}, O, togglespecialworkspace, ${language.obsidian}"
"${mod} SHIFT, O, movetoworkspace, special:${language.obsidian}"
]
++ lib.concatMap (
i:
let
key = lib.mod i 10;
in
[
"${mod}, ${toString key}, workspace, ${toString i}"
"${mod} SHIFT, ${toString key}, movetoworkspace, ${toString i}"
]
) (lib.range 1 10);
windowrule = [
"suppressevent maximize, class:.*" # ignore maximize requests from apps
"nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0" # fix some dragging issues with wayyland
"float,title:^(Picture-in-Picture)$"
"pin,title:^(Picture-in-Picture)$"
"size 640 360,title:^(Picture-in-Picture)$"
"move 100%-640 100%-360,title:^(Picture-in-Picture)$"
];
};
extraConfig = ''
bind = ${mod}, R, submap, resize
submap = resize
binde = , l, resizeactive, 50 0
binde = , h, resizeactive, -50 0
binde = , k, resizeactive, 0 -50
binde = , j, resizeactive, 0 50
bind = , escape, submap, reset
submap = reset
'';
};
}

View File

@@ -1,26 +1,28 @@
{
pkgs,
...
}: let
}:
let
ledgerDirectory = "/home/kfm/sync/src/ledger";
hora = pkgs.callPackage ../packages/hora.nix { timeLedger = "${ledgerDirectory}/time.timeclock"; };
in {
environment.systemPackages = let
git = "${pkgs.git}/bin/git -C ${ledgerDirectory}";
in [
hora
pkgs.hledger
(pkgs.writers.writeDashBin "hledger-git" ''
if [ "$1" = entry ]; then
${pkgs.hledger}/bin/hledger balance -V > "${ledgerDirectory}/balance.txt"
${git} add balance.txt
${git} commit --all --message="$(date -Im)"
else
${git} $*
fi
'')
(pkgs.writers.writeDashBin "hledger-edit" ''
$EDITOR ${ledgerDirectory}/current.journal
'')
];
in
{
environment.systemPackages =
let
git = "${pkgs.git}/bin/git -C ${ledgerDirectory}";
in
[
pkgs.hledger
(pkgs.writers.writeDashBin "hledger-git" ''
if [ "$1" = entry ]; then
${pkgs.hledger}/bin/hledger balance -V > "${ledgerDirectory}/balance.txt"
${git} add balance.txt
${git} commit --all --message="$(date -Im)"
else
${git} $*
fi
'')
(pkgs.writers.writeDashBin "hledger-edit" ''
$EDITOR ${ledgerDirectory}/current.journal
'')
];
}

View File

@@ -22,8 +22,18 @@
sort_key = "PERCENT_CPU";
tree_view = false;
update_process_names = false;
right_meters = ["Uptime" "Tasks" "LoadAverage" "Battery"];
left_meters = ["LeftCPUs2" "RightCPUs2" "Memory" "Swap"];
right_meters = [
"Uptime"
"Tasks"
"LoadAverage"
"Battery"
];
left_meters = [
"LeftCPUs2"
"RightCPUs2"
"Memory"
"Swap"
];
};
};
};

View File

@@ -3,7 +3,8 @@
pkgs,
lib,
...
}: let
}:
let
klem = pkgs.klem.override {
options.dmenu = "${pkgs.dmenu}/bin/dmenu -i -p klem";
options.scripts = {
@@ -51,7 +52,8 @@
'';
};
};
in {
in
{
age.secrets = {
github-token-i3status-rust = {
file = ../secrets/github-token-i3status-rust.age;
@@ -105,190 +107,224 @@ in {
'';
};
home-manager.users.me = let
modifier = "Mod4";
infoWorkspace = "";
messageWorkspace = "";
modes.resize = {
"Escape" = ''mode "default"'';
"Return" = ''mode "default"'';
"h" = "resize shrink width 10 px or 5 ppt";
"j" = "resize grow height 10 px or 5 ppt";
"k" = "resize shrink height 10 px or 5 ppt";
"l" = "resize grow width 10 px or 5 ppt";
};
gaps.inner = 4;
floating = {
titlebar = false;
border = 1;
};
bars = let position = "bottom"; in [
(lib.recursiveUpdate config.home-manager.users.me.stylix.targets.i3.exportedBarConfig
home-manager.users.me =
let
modifier = "Mod4";
infoWorkspace = "";
messageWorkspace = "";
modes.resize = {
"Escape" = ''mode "default"'';
"Return" = ''mode "default"'';
"h" = "resize shrink width 10 px or 5 ppt";
"j" = "resize grow height 10 px or 5 ppt";
"k" = "resize shrink height 10 px or 5 ppt";
"l" = "resize grow width 10 px or 5 ppt";
};
gaps.inner = 4;
floating = {
titlebar = false;
border = 1;
};
bars =
let
position = "bottom";
in
[
(lib.recursiveUpdate config.home-manager.users.me.stylix.targets.i3.exportedBarConfig {
workspaceButtons = true;
mode = "hide"; # "dock";
inherit position;
statusCommand = toString (
pkgs.writers.writeDash "i3status-rust" ''
export I3RS_GITHUB_TOKEN="$(cat ${config.age.secrets.github-token-i3status-rust.path})"
export OPENWEATHERMAP_API_KEY="$(cat ${config.age.secrets.openweathermap-api-key.path})"
exec ${config.home-manager.users.me.programs.i3status-rust.package}/bin/i3status-rs ${config.home-manager.users.me.home.homeDirectory}/.config/i3status-rust/config-${position}.toml
''
);
fonts = {
names = [
"${config.stylix.fonts.sansSerif.name}"
"FontAwesome 6 Free"
];
size = config.stylix.fonts.sizes.desktop * 0.8;
};
})
];
window = {
titlebar = false;
border = 2;
hideEdgeBorders = "smart";
commands = [
{
criteria = {
class = "floating";
};
command = "floating enable";
}
{
criteria = {
class = "fzfmenu";
};
command = "floating enable";
}
{
criteria = {
class = ".*";
};
command = "border pixel 2";
}
{
criteria = {
class = "mpv";
};
command = lib.strings.concatStringsSep ", " [
"floating enable"
"sticky enable"
"fullscreen disable"
"resize set 640 480"
"move position mouse"
];
}
];
};
colors =
let
background = config.lib.stylix.colors.withHashtag.base00;
in
{
workspaceButtons = true;
mode = "hide"; # "dock";
inherit position;
statusCommand = toString (pkgs.writers.writeDash "i3status-rust" ''
export I3RS_GITHUB_TOKEN="$(cat ${config.age.secrets.github-token-i3status-rust.path})"
export OPENWEATHERMAP_API_KEY="$(cat ${config.age.secrets.openweathermap-api-key.path})"
exec ${config.home-manager.users.me.programs.i3status-rust.package}/bin/i3status-rs ${config.home-manager.users.me.home.homeDirectory}/.config/i3status-rust/config-${position}.toml
'');
fonts = {
names = ["${config.stylix.fonts.sansSerif.name}" "FontAwesome 6 Free"];
size = config.stylix.fonts.sizes.desktop * 0.8;
unfocused = {
border = lib.mkForce background;
childBorder = lib.mkForce background;
};
})
];
window = {
titlebar = false;
border = 2;
hideEdgeBorders = "smart";
commands = [
{
criteria = {class = "floating";};
command = "floating enable";
}
{
criteria = {class = "fzfmenu";};
command = "floating enable";
}
{
criteria = {class = ".*";};
command = "border pixel 2";
}
{
criteria = {class = "mpv";};
command = lib.strings.concatStringsSep ", " [
"floating enable"
"sticky enable"
"fullscreen disable"
"resize set 640 480"
"move position mouse"
];
}
];
};
colors = let
background = config.lib.stylix.colors.withHashtag.base00;
in {
unfocused = {
border = lib.mkForce background;
childBorder = lib.mkForce background;
};
};
keybindings =
lib.listToAttrs (map (x: lib.nameValuePair "${modifier}+Shift+${toString x}" "move container to workspace ${toString x}") (lib.range 1 9))
// lib.listToAttrs (map (x: lib.nameValuePair "${modifier}+${toString x}" "workspace ${toString x}") (lib.range 1 9))
// {
"${modifier}+i" = "workspace ${infoWorkspace}";
"${modifier}+m" = "workspace ${messageWorkspace}";
};
keybindings =
lib.listToAttrs (
map (
x: lib.nameValuePair "${modifier}+Shift+${toString x}" "move container to workspace ${toString x}"
) (lib.range 1 9)
)
// lib.listToAttrs (
map (x: lib.nameValuePair "${modifier}+${toString x}" "workspace ${toString x}") (lib.range 1 9)
)
// {
"${modifier}+i" = "workspace ${infoWorkspace}";
"${modifier}+m" = "workspace ${messageWorkspace}";
"${modifier}+Shift+h" = "move left 25 px";
"${modifier}+Shift+j" = "move down 25 px";
"${modifier}+Shift+k" = "move up 25 px";
"${modifier}+Shift+l" = "move right 25 px";
"${modifier}+h" = "focus left";
"${modifier}+j" = "focus down";
"${modifier}+k" = "focus up";
"${modifier}+l" = "focus right";
"${modifier}+Shift+h" = "move left 25 px";
"${modifier}+Shift+j" = "move down 25 px";
"${modifier}+Shift+k" = "move up 25 px";
"${modifier}+Shift+l" = "move right 25 px";
"${modifier}+h" = "focus left";
"${modifier}+j" = "focus down";
"${modifier}+k" = "focus up";
"${modifier}+l" = "focus right";
# "${modifier}+Shift+b" = "move container to workspace prev";
# "${modifier}+Shift+n" = "move container to workspace next";
# "${modifier}+b" = "workspace prev";
# "${modifier}+n" = "workspace next";
# "${modifier}+Shift+b" = "move container to workspace prev";
# "${modifier}+Shift+n" = "move container to workspace next";
# "${modifier}+b" = "workspace prev";
# "${modifier}+n" = "workspace next";
"${modifier}+Shift+c" = "reload";
"${modifier}+Shift+q" = "kill";
"${modifier}+Shift+r" = "restart";
"${modifier}+Shift+c" = "reload";
"${modifier}+Shift+q" = "kill";
"${modifier}+Shift+r" = "restart";
"${modifier}+z" = "sticky toggle";
"${modifier}+Shift+z" = "floating toggle";
"${modifier}+z" = "sticky toggle";
"${modifier}+Shift+z" = "floating toggle";
"${modifier}+Shift+s" = "move scratchpad";
"${modifier}+s" = ''[class="^(?i)(?!obsidian).*"] scratchpad show'';
"${modifier}+o" = ''[class="obsidian"] scratchpad show'';
"${modifier}+Shift+s" = "move scratchpad";
"${modifier}+s" = ''[class="^(?i)(?!obsidian).*"] scratchpad show'';
"${modifier}+o" = ''[class="obsidian"] scratchpad show'';
"${modifier}+c" = "split h";
"${modifier}+e" = "layout toggle split";
"${modifier}+f" = "fullscreen toggle";
"${modifier}+r" = "mode resize";
"${modifier}+v" = "split v";
"${modifier}+w" = "layout tabbed";
"${modifier}+q" = "exec ${config.services.clipmenu.package}/bin/clipmenu";
"${modifier}+c" = "split h";
"${modifier}+e" = "layout toggle split";
"${modifier}+f" = "fullscreen toggle";
"${modifier}+r" = "mode resize";
"${modifier}+v" = "split v";
"${modifier}+w" = "layout tabbed";
"${modifier}+q" = "exec ${config.services.clipmenu.package}/bin/clipmenu";
"${modifier}+Return" = "exec ${pkgs.lib.niveum.defaultApplications.terminal}";
"${modifier}+t" = "exec ${pkgs.lib.niveum.defaultApplications.fileManager}";
"${modifier}+y" = "exec ${pkgs.lib.niveum.defaultApplications.browser}";
"${modifier}+Return" = "exec ${lib.getExe pkgs.niphas-terminal}";
"${modifier}+t" = "exec ${lib.getExe pkgs.niphas-file-browser}";
"${modifier}+y" = "exec ${lib.getExe pkgs.niphas-web-browser}";
"${modifier}+d" = "exec ${pkgs.writers.writeDash "run" ''exec rofi -modi run,ssh,window -show run''}";
"${modifier}+Shift+d" = "exec ${pkgs.notemenu}/bin/notemenu";
"${modifier}+p" = "exec rofi-pass";
"${modifier}+Shift+p" = "exec rofi-pass --insert";
"${modifier}+u" = "exec ${pkgs.unicodmenu}/bin/unicodmenu";
"${modifier}+Shift+u" = "exec ${pkgs.writers.writeDash "last-unicode" ''${pkgs.xdotool}/bin/xdotool type --delay 1000 "$(${pkgs.gawk}/bin/awk 'END{print $1}' ~/.cache/unicodmenu)"''}";
"${modifier}+d" =
"exec ${pkgs.writers.writeDash "run" ''exec rofi -modi run,ssh,window -show run''}";
"${modifier}+Shift+d" = "exec ${lib.getExe pkgs.notemenu}";
"${modifier}+p" = "exec rofi-pass";
"${modifier}+Shift+p" = "exec rofi-pass --insert";
"${modifier}+u" = "exec ${lib.getExe pkgs.unicodmenu}";
"${modifier}+Shift+u" =
"exec ${pkgs.writers.writeDash "last-unicode" ''${pkgs.xdotool}/bin/xdotool type --delay 1000 "$(${pkgs.gawk}/bin/awk 'END{print $1}' ~/.cache/unicodmenu)"''}";
"${modifier}+F7" = "exec ${pkgs.writers.writeDash "showkeys-toggle" ''
if ${pkgs.procps}/bin/pgrep screenkey; then
exec ${pkgs.procps}/bin/pkill screenkey
else
exec ${pkgs.screenkey}/bin/screenkey
fi
''}";
"${modifier}+F12" = "exec ${klem}/bin/klem";
"XF86AudioLowerVolume" = "exec ${pkgs.pamixer}/bin/pamixer -d 5";
"XF86AudioMute" = "exec ${pkgs.pamixer}/bin/pamixer -t";
"XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5";
"XF86Calculator" = "exec ${pkgs.st}/bin/st -c floating -e ${pkgs.bc}/bin/bc";
"XF86AudioPause" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next";
"XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl previous";
"XF86AudioStop" = "exec ${pkgs.playerctl}/bin/playerctl stop";
"${modifier}+F7" = "exec ${pkgs.writers.writeDash "showkeys-toggle" ''
if ${pkgs.procps}/bin/pgrep screenkey; then
exec ${pkgs.procps}/bin/pkill screenkey
else
exec ${pkgs.screenkey}/bin/screenkey
fi
''}";
"${modifier}+F12" = "exec ${klem}/bin/klem";
"XF86AudioLowerVolume" = "exec ${lib.getExe pkgs.pamixer} -d 5";
"XF86AudioMute" = "exec ${lib.getExe pkgs.pamixer} -t";
"XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5";
"XF86Calculator" = "exec ${lib.getExe pkgs.st} -c floating -e ${pkgs.bc}/bin/bc";
"XF86AudioPause" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"XF86AudioPlay" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"XF86AudioNext" = "exec ${lib.getExe pkgs.playerctl} next";
"XF86AudioPrev" = "exec ${lib.getExe pkgs.playerctl} previous";
"XF86AudioStop" = "exec ${lib.getExe pkgs.playerctl} stop";
# key names detected with xorg.xev:
# XF86WakeUp (fn twice)
# XF86Battery (fn f3)
# XF86Sleep (fn f4) - actually suspends
# XF86WLAN
# XF86WebCam (fn f6)
# XF86TouchpadToggle (fn f8)
# XF86Suspend (fn f12) - actually suspends to disk
# Num_Lock (fn Roll) - numlocks
# XF86Audio{Prev,Next,Mute,Play,Stop}
# XF86Forward
# XF86Back
# XF86Launch1 (thinkvantage)
};
in {
stylix.targets.i3.enable = true;
# key names detected with xorg.xev:
# XF86WakeUp (fn twice)
# XF86Battery (fn f3)
# XF86Sleep (fn f4) - actually suspends
# XF86WLAN
# XF86WebCam (fn f6)
# XF86TouchpadToggle (fn f8)
# XF86Suspend (fn f12) - actually suspends to disk
# Num_Lock (fn Roll) - numlocks
# XF86Audio{Prev,Next,Mute,Play,Stop}
# XF86Forward
# XF86Back
# XF86Launch1 (thinkvantage)
};
in
{
stylix.targets.i3.enable = true;
xsession.windowManager.i3 = {
enable = true;
extraConfig = ''
bindsym --release ${modifier}+Shift+w exec xsecurelock
xsession.windowManager.i3 = {
enable = true;
extraConfig = ''
bindsym --release ${modifier}+Shift+w exec xsecurelock
exec "${pkgs.obsidian}/bin/obsidian"
for_window [class="obsidian"] , move scratchpad
exec "${lib.getExe pkgs.obsidian}"
for_window [class="obsidian"] , move scratchpad
assign [class="message"] ${messageWorkspace}
exec "${pkgs.writers.writeDash "irc" "exec ${pkgs.alacritty}/bin/alacritty --class message -e ssh weechat@makanek -t tmux attach-session -t IM"}"
exec "${pkgs.writers.writeDash "email" "exec ${pkgs.alacritty}/bin/alacritty --class message -e aerc"}"
assign [class="message"] ${messageWorkspace}
exec "${pkgs.writers.writeDash "irc" "exec ${lib.getExe pkgs.alacritty} --class message -e ssh weechat@makanek -t tmux attach-session -t IM"}"
exec "${pkgs.writers.writeDash "email" "exec ${lib.getExe pkgs.alacritty} --class message -e aerc"}"
exec --no-startup-id ${pkgs.xss-lock}/bin/xss-lock -- xsecurelock
'';
config = {
inherit modifier gaps modes bars floating window colors;
exec --no-startup-id ${pkgs.xss-lock}/bin/xss-lock -- xsecurelock
'';
config = {
inherit
modifier
gaps
modes
bars
floating
window
colors
;
keybindings = keybindings // {
"${modifier}+F6" = "exec ${pkgs.xorg.xkill}/bin/xkill";
"${modifier}+F9" = "exec ${pkgs.redshift}/bin/redshift -O 4000 -b 0.85";
"${modifier}+F10" = "exec ${pkgs.redshift}/bin/redshift -x";
"${modifier}+F11" = "exec ${pkgs.xcalib}/bin/xcalib -invert -alter";
"Print" = "exec flameshot gui";
# "${modifier}+Shift+x" = "exec ${move-to-new-workspace}";
# "${modifier}+x" = "exec ${new-workspace}";
"XF86Display" = "exec ${pkgs.dmenu-randr}/bin/dmenu-randr";
"XF86Display" = "exec ${lib.getExe pkgs.dmenu-randr}";
};
};
};
};
};
}

View File

@@ -1,82 +0,0 @@
{
pkgs,
config,
...
}: {
age.secrets = {
miniflux-api-token = {
file = ../secrets/miniflux-api-token.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
};
home-manager.users.me = {
programs.i3status-rust = {
enable = true;
bars.bottom = {
icons = "awesome6";
settings = {
theme.overrides = let
colours = config.lib.stylix.colors.withHashtag;
in {
idle_bg = colours.base00;
idle_fg = colours.base05;
good_bg = colours.base00;
good_fg = colours.base0B;
warning_bg = colours.base00;
warning_fg = colours.base0A;
critical_bg = colours.base00;
critical_fg = colours.base09;
info_bg = colours.base00;
info_fg = colours.base04;
separator_bg = colours.base00;
separator = " ";
};
};
blocks = [
{
block = "music";
format = "{$icon $combo $play |}";
separator = " ";
}
{
block = "net";
format = " $icon HU";
missing_format = "";
device = "ppp0";
}
{
block = "net";
format = " $icon FU";
missing_format = "";
device = "tun0";
}
{
block = "battery";
format = "$icon $percentage $time";
device = "DisplayDevice";
driver = "upower";
}
{
block = "sound";
}
{
block = "disk_space";
format = "$icon $available";
}
{
block = "memory";
format = "$icon $mem_used.eng(prefix:G)";
}
{block = "load";}
{
block = "time";
format = "$icon $timestamp.datetime(f:'%Y-%m-%d (%W %a) %H:%M', l:de_DE)";
}
];
};
};
};
}

View File

@@ -111,14 +111,18 @@ in
variant = if settings ? "variant" then settings.variant else "";
in
pkgs.writers.writeDashBin "kb-${language}" ''
if [ -z $SWAYSOCK ]; then
${pkgs.xorg.setxkbmap}/bin/setxkbmap ${defaultLanguage.code},${code} ${defaultLanguage.variant},${variant} ${
toString (map (option: "-option ${option}") xkbOptions)
}
else
if [ -n "$SWAYSOCK" ]; then
swaymsg -s $SWAYSOCK 'input * xkb_layout "${defaultLanguage.code},${code}"'
swaymsg -s $SWAYSOCK 'input * xkb_variant "${defaultLanguage.variant},${variant}"'
swaymsg -s $SWAYSOCK 'input * xkb_options "${lib.concatStringsSep "," xkbOptions}"'
elif [ -n "$HYPRLAND_INSTANCE_SIGNATURE" ]; then
hyprctl keyword input:kb_variant "" # otherwise we end up with an invalid combination for a short while
hyprctl keyword input:kb_layout "${defaultLanguage.code},${code}"
hyprctl keyword input:kb_variant "${defaultLanguage.variant},${variant}"
elif [ -n "$DISPLAY" ]; then
${pkgs.xorg.setxkbmap}/bin/setxkbmap ${defaultLanguage.code},${code} ${defaultLanguage.variant},${variant} ${
toString (map (option: "-option ${option}") xkbOptions)
}
fi
''
) (languages // config.services.xserver.xkb.extraLayouts);

View File

@@ -3,14 +3,16 @@
pkgs,
lib,
...
}: let
}:
let
davHome = "~/.local/share/dav";
kmeinCloud = {
davEndpoint = "https://cloud.kmein.de/remote.php/dav";
username = "kieran";
passwordFile = config.age.secrets.nextcloud-password-kieran.path;
};
in {
in
{
age.secrets = {
nextcloud-password-kieran = {
file = ../secrets/nextcloud-password-kieran.age;
@@ -18,12 +20,6 @@ in {
group = config.users.users.me.group;
mode = "400";
};
nextcloud-password-fysi = {
file = ../secrets/nextcloud-password-fysi.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
};
environment.systemPackages = [
@@ -45,8 +41,8 @@ in {
systemd.user.services.vdirsyncer = {
enable = true;
wants = ["network-online.target"];
wantedBy = ["default.target"];
wants = [ "network-online.target" ];
wantedBy = [ "default.target" ];
startAt = "*:00/10";
script = ''
${pkgs.vdirsyncer}/bin/vdirsyncer sync && ${pkgs.khal}/bin/khal printcalendars # https://lostpackets.de/khal/configure.html#syncing

View File

@@ -2,10 +2,11 @@
lib,
pkgs,
...
}: {
}:
{
systemd.services.lb-subscription = {
enable = true;
wants = ["network-online.target"];
wants = [ "network-online.target" ];
startAt = "weekly";
serviceConfig = {
user = "kfm";

11
configs/lix.nix Normal file
View File

@@ -0,0 +1,11 @@
{
pkgs,
lib,
...
}:
{
nix = {
package = lib.mkForce pkgs.lix;
settings.experimental-features = [ "nix-command" "flakes" ];
};
}

View File

@@ -1,19 +0,0 @@
{pkgs, ...}: {
systemd.services.imaginary-illuminations = {
enable = false;
wants = ["network-online.target"];
serviceConfig = {
User = "kfm";
Group = "users";
WorkingDirectory = "/home/kfm/cloud/Seafile/Documents/Media/imaginary-illuminations";
Restart = "on-failure";
RestartSec = "15s";
};
startAt = "7:00";
script = ''
${pkgs.deno}/bin/deno run -A post.ts
'';
};
systemd.timers.imaginary-illuminations.timerConfig.RandomizedDelaySec = "14h";
}

View File

@@ -2,7 +2,8 @@
config,
pkgs,
...
}: {
}:
{
services.nginx.virtualHosts.default = {
locations."= /stub_status".extraConfig = "stub_status;";
};
@@ -41,12 +42,12 @@
systemd.services.promtail = {
description = "Promtail service for Loki";
wantedBy = ["multi-user.target"];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = ''
${pkgs.grafana-loki}/bin/promtail --config.file ${
(pkgs.formats.yaml {}).generate "promtail.yaml" {
(pkgs.formats.yaml { }).generate "promtail.yaml" {
server = {
http_listen_port = 28183;
grpc_listen_port = 0;
@@ -55,9 +56,7 @@
clients = [
{
url = "http://${
if config.networking.hostName == "makanek"
then "127.0.0.1"
else "makanek.r"
if config.networking.hostName == "makanek" then "127.0.0.1" else "makanek.r"
}:3100/loki/api/v1/push";
}
];
@@ -71,7 +70,7 @@
};
relabel_configs = [
{
source_labels = ["__journal__systemd_unit"];
source_labels = [ "__journal__systemd_unit" ];
target_label = "unit";
}
];

View File

@@ -1,43 +1,42 @@
{
pkgs,
lib,
self,
config,
...
}: let
}:
let
swallow = command: "${pkgs.swallow}/bin/swallow ${command}";
in {
myMpv =
pkgs:
self.inputs.wrappers.wrapperModules.mpv.apply {
inherit pkgs;
scripts = [
pkgs.mpvScripts.visualizer
];
"mpv.conf".content = "";
"mpv.input".content = ''
Alt+- add video-zoom -0.25
Alt+= add video-zoom 0.25
Alt+LEFT add video-rotate -90
Alt+RIGHT add video-rotate 90
Alt+h add video-pan-x 0.05
Alt+j add video-pan-y -0.05
Alt+k add video-pan-y 0.05
Alt+l add video-pan-x -0.05
'';
};
in
{
environment.shellAliases.smpv = swallow "mpv";
nixpkgs.overlays = [
(self: super: {
mpv = config.home-manager.users.me.programs.mpv.finalPackage;
(final: prev: {
mpv = (myMpv prev).wrapper;
})
];
home-manager.users.me = {
programs.mpv = {
enable = true;
config = {
ytdl-format = "bestvideo[height<=?720][fps<=?30][vcodec!=?vp9]+bestaudio/best";
ytdl-raw-options = lib.concatStringsSep "," [''sub-lang="de,en"'' "write-sub=" "write-auto-sub="];
screenshot-template = "%F-%wH%wM%wS-%#04n";
script-opts = "ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp";
ao = "pulse"; # no pipewire for me :(
};
bindings = {
"Alt+RIGHT" = "add video-rotate 90";
"Alt+LEFT" = "add video-rotate -90";
"Alt+-" = "add video-zoom -0.25";
"Alt+=" = "add video-zoom 0.25";
"Alt+l" = "add video-pan-x -0.05";
"Alt+h" = "add video-pan-x 0.05";
"Alt+k" = "add video-pan-y 0.05";
"Alt+j" = "add video-pan-y -0.05";
};
scripts = [
pkgs.mpvScripts.quality-menu
pkgs.mpvScripts.visualizer
];
};
};
environment.systemPackages = [
((myMpv pkgs).wrapper)
];
}

View File

@@ -1,7 +1,8 @@
{
pkgs,
...
}: {
}:
{
programs.nm-applet.enable = true;
networking.networkmanager = {
@@ -12,10 +13,10 @@
];
wifi.macAddress = "random";
ethernet.macAddress = "random";
unmanaged = ["docker*"];
unmanaged = [ "docker*" ];
};
users.users.me.extraGroups = ["networkmanager"];
users.users.me.extraGroups = [ "networkmanager" ];
environment.systemPackages = [
pkgs.speedtest-cli

View File

@@ -1,17 +0,0 @@
{
pkgs,
config,
...
}: {
environment.systemPackages = [
(pkgs.writers.writeDashBin "miniflux-watch-later" ''
miniflux_api_token=$(cat ${config.age.secrets.miniflux-api-token.path})
random_feed_item=$(
${pkgs.curl}/bin/curl -u "$miniflux_api_token" --basic -s 'https://feed.kmein.de/v1/entries?starred=true&limit=0' \
| ${pkgs.jq}/bin/jq -r '.entries[].id' \
| ${pkgs.coreutils}/bin/shuf -n1
)
${pkgs.xdg-utils}/bin/xdg-open "https://feed.kmein.de/starred/entry/$random_feed_item"
'')
];
}

View File

@@ -1,14 +0,0 @@
{
pkgs,
inputs,
...
}: {
nixpkgs = {
config.allowUnfree = true;
};
nix = {
package = pkgs.nixVersions.stable;
extraOptions = "experimental-features = nix-command flakes";
nixPath = ["nixpkgs=${inputs.nixpkgs}"];
};
}

View File

@@ -2,21 +2,23 @@
pkgs,
lib,
...
}: let
}:
let
openweathermap-repo = pkgs.fetchFromGitHub {
owner = "ip1981";
repo = "openweathermap";
rev = "9cfef7b14ac5af7109449b54b1cb352b4c76167a";
sha256 = "0sm43wicvw2fy7nq65s8vch6jjb5bszqr4ilnhibayamj4jcpw53";
};
openweathermap = pkgs.haskellPackages.callCabal2nix "openweathermap" openweathermap-repo {};
openweathermap = pkgs.haskellPackages.callCabal2nix "openweathermap" openweathermap-repo { };
openweathermap-key = lib.strings.fileContents <secrets/openweathermap.key>;
in {
in
{
nixpkgs.config.packageOverrides = pkgs: {
weather = pkgs.writers.writeDashBin "weather" ''
${openweathermap}/bin/openweathermap --api-key ${openweathermap-key} "$@"
'';
};
environment.systemPackages = [pkgs.weather];
environment.systemPackages = [ pkgs.weather ];
}

View File

@@ -1,22 +1,23 @@
{
config,
pkgs,
lib,
inputs,
...
}: let
worldradio = pkgs.callPackage ../packages/worldradio.nix {};
}:
let
worldradio = pkgs.callPackage ../packages/worldradio.nix { };
zoteroStyle = {
name,
sha256,
}: {
name = "${name}.csl";
path = pkgs.fetchurl {
url = "https://www.zotero.org/styles/${name}";
inherit sha256;
zoteroStyle =
{
name,
sha256,
}:
{
name = "${name}.csl";
path = pkgs.fetchurl {
url = "https://www.zotero.org/styles/${name}";
inherit sha256;
};
};
};
cslDirectory = pkgs.linkFarm "citation-styles" [
(zoteroStyle {
name = "chicago-author-date-de";
@@ -32,7 +33,8 @@
})
];
astrolog = pkgs.astrolog.overrideAttrs (old:
astrolog = pkgs.astrolog.overrideAttrs (
old:
old
// {
installPhase = ''
@@ -51,8 +53,10 @@
/^:I /s/80/120/ # wider text output
' $out/astrolog/astrolog.as
'';
});
in {
}
);
in
{
home-manager.users.me.home.file = {
".csl".source = cslDirectory;
".local/share/pandoc/csl".source = cslDirectory; # as of pandoc 2.11, it includes citeproc
@@ -66,41 +70,27 @@ in {
GPODDER_DOWNLOAD_DIR=${config.users.users.me.home}/mobile/audio/Text/podcasts exec ${pkgs.gpodder}/bin/gpodder "$@"
'')
# INTERNET
aria2
telegram-desktop
whois
dnsutils
# FILE MANAGERS
lf
pcmanfm
# MEDIA
ffmpeg
simplescreenrecorder
imagemagick
exiftool
nsxiv
graphviz
# SHELL
bat # better cat
dos2unix
genpass # generate passwords
(pkgs.writers.writeDashBin "genpassphrase" ''${pkgs.genpass}/bin/genpass --passphrase | ${pkgs.gnused}/bin/sed 's/ /-/g;s/\(^\|-\)\([a-z]\)/\1\U\2/g;s/$/-'$(${pkgs.coreutils}/bin/date +%Y)'/' '')
(pkgs.writers.writeDashBin "genpassphrase" ''${pkgs.genpass}/bin/genpass "$@" --passphrase | ${pkgs.gnused}/bin/sed 's/ /-/g;s/\(^\|-\)\([a-z]\)/\1\U\2/g;s/$/-'$(${pkgs.coreutils}/bin/date +%Y)'/' '')
gcc
python3Packages.jsonschema # json validation
pup # html toolkit
xan # csv toolkit
magic-wormhole-rs # file transfer
man-pages
man-pages-posix
exfat # to mount windows drives
# HARDWARE TOOLS
gnome-disk-utility
arandr # xrandr for noobs
wdisplays
libnotify # for notify-send
xclip # clipboard CLI
dragon-drop # drag and drop
xorg.xkill # kill by clicking
portfolio # personal finance overview
audacity
calibre
@@ -117,7 +107,7 @@ in {
zoom-us # video conferencing
(pkgs.writers.writeDashBin "im" ''
weechat_password=$(${pkgs.pass}/bin/pass weechat)
exec ${weechat}/bin/weechat -t -r '/mouse enable; /remote add makanek http://${pkgs.lib.niveum.systems.makanek.externalIp}:8002 -password='"$weechat_password"'; /remote connect makanek'
exec ${weechat}/bin/weechat -t -r '/mouse enable; /remote add makanek http://${pkgs.lib.niveum.machines.makanek.externalIp}:8002 -password='"$weechat_password"'; /remote connect makanek'
'')
alejandra # nix formatter
pdfgrep # search in pdf
@@ -129,6 +119,7 @@ in {
pdfpc # presenter console for pdf slides
hc # print files as qr codes
yt-dlp
yt-dlp-master
espeak
rink # unit converter
auc
@@ -138,6 +129,7 @@ in {
polyglot
qrpaste
ttspaste
pi # llm agent
new-mac # get a new mac address
scanned
default-gateway
@@ -173,37 +165,36 @@ in {
di-fm-key-file = config.age.secrets.di-fm-key.path;
})
# kmein.slide
termdown
termdown # countdown timer in terminal
image-convert-tolino
rfc
tag
timer
nix-prefetch-git
nix-git
nixfmt-rfc-style
comma
par
qrencode
# inputs.menstruation-backend.defaultPackage.x86_64-linux
inputs.agenix.packages.x86_64-linux.default
inputs.recht.defaultPackage.x86_64-linux
pkgs.agenix
pkgs.wetter
pkgs.alarm
(pkgs.writers.writeDashBin "worldradio" ''
shuf ${worldradio} | ${pkgs.findutils}/bin/xargs ${pkgs.mpv}/bin/mpv --no-video
'')
(pkgs.writers.writeDashBin "chats" ''
${pkgs.openssh}/bin/ssh makanek "cd /var/lib/weechat/logs && grep --ignore-case --color=always --recursive $@" | ${pkgs.less}/bin/less --raw-control-chars
${pkgs.openssh}/bin/ssh -p ${toString pkgs.lib.niveum.machines.makanek.sshPort} ${pkgs.lib.niveum.machines.makanek.externalIp} "cd /var/lib/weechat/logs && grep --ignore-case --color=always --recursive $@" | ${pkgs.less}/bin/less --raw-control-chars
'')
inputs.scripts.packages.x86_64-linux.alarm
niveum-ssh
spotify
ncspot
playerctl
#krebs
pkgs.nur.repos.mic92.ircsink
cyberlocker-tools
kpaste
(haskellPackages.ghcWithHoogle (hs: [
hs.text
@@ -213,6 +204,7 @@ in {
(python3.withPackages (py: [
py.black
py.ruff
# py.python-language-server
# py.pyls-mypy
# py.pyls-black
@@ -233,12 +225,16 @@ in {
go
texlive.combined.scheme-full
latexrun
(aspellWithDicts (dict: [dict.de dict.en dict.en-computers]))
(aspellWithDicts (dict: [
dict.de
dict.en
dict.en-computers
]))
# haskellPackages.pandoc-citeproc
text2pdf
lowdown
glow # markdown to term
libreoffice
libreoffice-qt6-fresh
# gnumeric
dia
pandoc
@@ -248,10 +244,6 @@ in {
# proselint
asciidoctor
wordnet
tokei # count lines of code
gnumake
binutils # for strip, ld, ...
# nightly.rust
shellcheck
# photography

View File

@@ -1,6 +1,8 @@
{config, ...}: let
{ config, ... }:
let
user = config.users.users.me.name;
in {
in
{
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.user == "${user}" && action.id == "org.freedesktop.systemd1.manage-units") {

View File

@@ -2,9 +2,11 @@
pkgs,
config,
...
}: let
}:
let
suspend = pkgs.writers.writeDash "suspend" "${pkgs.systemd}/bin/systemctl suspend";
in {
in
{
services.power-action = {
enable = true;
plans.suspend = {

View File

@@ -1,17 +1,32 @@
{pkgs, lib, ...}: let
hp-driver = pkgs.hplip;
in {
{ pkgs, lib, ... }:
let
hp-driver = pkgs.hplipWithPlugin;
in
{
services.printing = {
enable = true;
drivers = [hp-driver];
drivers = [ hp-driver ];
};
hardware.sane = {
enable = true;
extraBackends = [ hp-driver ];
};
environment.systemPackages = [
pkgs.system-config-printer
pkgs.simple-scan
hp-driver
];
# allow connecting to .local printers
services.avahi.nssmdns4 = true;
services.avahi = {
nssmdns4 = true;
enable = true;
openFirewall = true;
};
# users.users.me.extraGroups is set in configs/default.nix which defines the "me" user
hardware.printers.ensurePrinters = [
{
@@ -30,7 +45,6 @@ in {
];
}
/*
HP/hp-officejet_4650_series.ppd.gz
drv:///hp/hpcups.drv/hp-officejet_4650_series.ppd
HP/hp-officejet_4650_series.ppd.gz
drv:///hp/hpcups.drv/hp-officejet_4650_series.ppd
*/

View File

@@ -2,8 +2,11 @@
config,
pkgs,
...
}: {
networking.hosts = {"42:0:ca48:f98f:63d7:31ce:922b:245d" = ["go"];};
}:
{
networking.hosts = {
"42:0:ca48:f98f:63d7:31ce:922b:245d" = [ "go" ];
};
services.tinc.networks.retiolum = {
rsaPrivateKeyFile = config.age.secrets.retiolum-rsa.path;

View File

@@ -1,4 +1,5 @@
{pkgs, ...}: {
{ pkgs, ... }:
{
home-manager.users.me.programs.rofi = {
enable = true;
pass = {
@@ -13,6 +14,6 @@
help_color="#FF0000"
''; # help_color set by https://github.com/mrossinek/dotfiles/commit/13fc5f24caa78c8f20547bf473266879507f13bf
};
plugins = [pkgs.rofi-calc];
plugins = [ pkgs.rofi-calc ];
};
}

View File

@@ -1,4 +1,5 @@
{pkgs, ...}: {
{ pkgs, ... }:
{
services.pipewire = {
enable = true;
alsa = {
@@ -9,7 +10,7 @@
jack.enable = true;
};
systemd.user.services.pipewire-pulse.path = [pkgs.pulseaudio];
systemd.user.services.pipewire-pulse.path = [ pkgs.pulseaudio ];
services.avahi = {
enable = true;

Some files were not shown because too many files have changed in this diff Show More