diff --git a/flake.lock b/flake.lock
index 430c0c1..5848f43 100644
--- a/flake.lock
+++ b/flake.lock
@@ -496,11 +496,11 @@
"wrappers": "wrappers"
},
"locked": {
- "lastModified": 1770756688,
- "narHash": "sha256-raCwOTt5xT7J1ysxdGrmBva6OVrvjf47EgVLi5B5R5o=",
+ "lastModified": 1771601908,
+ "narHash": "sha256-lqscsSHms5xk8iOOEj0J6XtrIcZp7/TXN4iiQjNeXzM=",
"ref": "refs/heads/master",
- "rev": "86bf2150a7cabd225149f35c0ff57576af6ded44",
- "revCount": 38,
+ "rev": "13ee868d5d297fbcfa1370cfff67e5c7f5e3d0aa",
+ "revCount": 42,
"type": "git",
"url": "https://code.kmein.de/kfm/niphas"
},
@@ -722,11 +722,11 @@
]
},
"locked": {
- "lastModified": 1771337567,
- "narHash": "sha256-DiH3hGzC7z6qv39zuFCrMrKDTKdtsN+z/OorsbBdJaQ=",
+ "lastModified": 1771622489,
+ "narHash": "sha256-CGAS5ISs+h6GNQwaOLycfbcFRkN0legi/hdDov4Obfk=",
"owner": "pinpox",
"repo": "opencrow",
- "rev": "8da71c7d1d04e27ffb5aade99f67e591d52c30c4",
+ "rev": "9ec2d17e6c9d45b22b9cca3174b6b1a75758d8f6",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index d37f7e3..ddb14dc 100644
--- a/flake.nix
+++ b/flake.nix
@@ -12,6 +12,7 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
niphas.url = "git+https://code.kmein.de/kfm/niphas";
+ panoptikon.url = "git+https://code.kmein.de/kfm/panoptikon";
nixos-hardware.url = "github:NixOS/nixos-hardware";
nur.url = "github:nix-community/NUR";
retiolum.url = "github:krebs/retiolum";
@@ -90,6 +91,7 @@
autorenkalender,
telebots,
stockholm,
+ panoptikon,
nix-index-database,
stylix,
voidrice,
@@ -193,7 +195,6 @@
nixosModules = {
moodle-dl = import modules/moodle-dl.nix;
passport = import modules/passport.nix;
- panoptikon = import modules/panoptikon.nix;
power-action = import modules/power-action.nix;
system-dependent = import modules/system-dependent.nix;
telegram-bot = import modules/telegram-bot.nix;
@@ -369,10 +370,6 @@
inherit lib;
pkgs = final;
};
- panoptikon = import lib/panoptikon.nix {
- inherit lib;
- pkgs = final;
- };
};
};
@@ -384,6 +381,7 @@
nixpkgs.overlays = [
self.overlays.default
niphas.overlays.default
+ panoptikon.overlays.default
(final: prev: {
niphas-git =
(prev.niphas-git.passthru.configuration.apply {
@@ -448,7 +446,7 @@
++ profiles.server
++ [
systems/ful/configuration.nix
- self.nixosModules.panoptikon
+ panoptikon.nixosModules.default
self.nixosModules.go-webring
stockholm.nixosModules.reaktor2
opencrow.nixosModules.default
diff --git a/lib/panoptikon.nix b/lib/panoptikon.nix
deleted file mode 100644
index 2b08cec..0000000
--- a/lib/panoptikon.nix
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- pkgs,
- lib,
- ...
-}:
-{
- # watcher scripts
- url =
- address:
- pkgs.writers.writeDash "watch-url" ''
- ${pkgs.curl}/bin/curl -sSL ${lib.escapeShellArg address} \
- | ${pkgs.python3Packages.html2text}/bin/html2text --decode-errors=ignore
- '';
- urlSelector =
- selector: address:
- pkgs.writers.writeDash "watch-url-selector" ''
- ${pkgs.curl}/bin/curl -sSL ${lib.escapeShellArg address} \
- | ${pkgs.htmlq}/bin/htmlq ${lib.escapeShellArg selector} \
- | ${pkgs.python3Packages.html2text}/bin/html2text
- '';
- urlJSON =
- {
- jqScript ? ".",
- }:
- address:
- pkgs.writers.writeDash "watch-url-json" ''
- ${pkgs.curl}/bin/curl -sSL ${lib.escapeShellArg address} | ${pkgs.jq}/bin/jq -f ${pkgs.writeText "script.jq" jqScript}
- '';
-
- # reporter scripts
- kpaste-irc =
- {
- target,
- retiolumLink ? false,
- server ? "irc.r",
- messagePrefix ? "change detected: ",
- nick ? ''"$PANOPTIKON_WATCHER"-watcher'',
- }:
- pkgs.writers.writeDash "kpaste-irc-reporter" ''
- KPASTE_CONTENT_TYPE=text/plain ${pkgs.kpaste}/bin/kpaste \
- | ${pkgs.gnused}/bin/sed -n "${if retiolumLink then "2" else "3"}s/^/${messagePrefix}/p" \
- | ${pkgs.nur.repos.mic92.ircsink}/bin/ircsink \
- --nick ${nick} \
- --server ${server} \
- --target ${target}
- '';
-}
diff --git a/modules/panoptikon.nix b/modules/panoptikon.nix
deleted file mode 100644
index b5ce73f..0000000
--- a/modules/panoptikon.nix
+++ /dev/null
@@ -1,123 +0,0 @@
-{
- config,
- lib,
- pkgs,
- ...
-}:
-{
- options.services.panoptikon = {
- enable = lib.mkEnableOption "Generic command output / website watcher";
- watchers = lib.mkOption {
- type = lib.types.attrsOf (
- lib.types.submodule (watcher: {
- options = {
- script = lib.mkOption {
- type = lib.types.path;
- description = ''
- A script whose stdout is to be watched.
- '';
- example = ''
- pkgs.writers.writeDash "github-meta" '''
- ''${pkgs.curl}/bin/curl -sSL https://api.github.com/meta | ''${pkgs.jq}/bin/jq
- '''
- '';
- };
- frequency = lib.mkOption {
- type = lib.types.str;
- description = ''
- How often to run the script. See systemd.time(7) for more information about the format.
- '';
- example = "*:0/3";
- default = "daily";
- };
- loadCredential = lib.mkOption {
- type = lib.types.listOf lib.types.str;
- description = ''
- This can be used to pass secrets to the systemd service without adding them to the nix store.
- '';
- default = [ ];
- };
- reporters = lib.mkOption {
- type = lib.types.listOf lib.types.path;
- description = ''
- A list of scripts that take the diff (if any) via stdin and report it (e.g. to IRC, Telegram or Prometheus). The name of the watcher will be in the $PANOPTIKON_WATCHER environment variable.
- '';
- example = ''
- [
- (pkgs.writers.writeDash "telegram-reporter" '''
- ''${pkgs.curl}/bin/curl -X POST https://api.telegram.org/bot''${TOKEN}/sendMessage \
- -d chat_id=123456 \
- -d text="$(cat)"
- ''')
- (pkgs.writers.writeDash "notify" '''
- ''${pkgs.libnotify}/bin/notify-send "$PANOPTIKON_WATCHER has changed."
- ''')
- ]
- '';
- };
- };
- config = { };
- })
- );
- };
- };
-
- config =
- let
- cfg = config.services.panoptikon;
- in
- lib.mkIf cfg.enable {
- users.extraUsers.panoptikon = {
- isSystemUser = true;
- createHome = true;
- home = "/var/lib/panoptikon";
- group = "panoptikon";
- };
-
- users.extraGroups.panoptikon = { };
-
- systemd.timers = lib.attrsets.mapAttrs' (
- watcherName: _:
- lib.nameValuePair "panoptikon-${watcherName}" {
- timerConfig.RandomizedDelaySec = toString (60 * 60);
- }
- ) cfg.watchers;
-
- systemd.services = lib.attrsets.mapAttrs' (
- watcherName: watcherOptions:
- lib.nameValuePair "panoptikon-${watcherName}" {
- enable = true;
- startAt = watcherOptions.frequency;
- serviceConfig = {
- Type = "oneshot";
- User = "panoptikon";
- Group = "panoptikon";
- WorkingDirectory = "/var/lib/panoptikon";
- RestartSec = toString (60 * 60);
- Restart = "on-failure";
- LoadCredential = watcherOptions.loadCredential;
- };
- unitConfig = {
- StartLimitIntervalSec = "300";
- StartLimitBurst = "5";
- };
- environment.PANOPTIKON_WATCHER = watcherName;
- wants = [ "network-online.target" ];
- script = ''
- set -fux
- ${watcherOptions.script} > ${lib.escapeShellArg watcherName}
- diff_output=$(${pkgs.diffutils}/bin/diff --new-file ${
- lib.escapeShellArg (watcherName + ".old")
- } ${lib.escapeShellArg watcherName} || :)
- if [ -n "$diff_output" ]
- then
- ${lib.strings.concatMapStringsSep "\n" (
- reporter: ''echo "$diff_output" | ${reporter} || :''
- ) watcherOptions.reporters}
- fi
- mv ${lib.escapeShellArg watcherName} ${lib.escapeShellArg (watcherName + ".old")}
- '';
- }
- ) cfg.watchers;
- };
-}
diff --git a/systems/ful/panoptikon.nix b/systems/ful/panoptikon.nix
index 425d92e..65a892e 100644
--- a/systems/ful/panoptikon.nix
+++ b/systems/ful/panoptikon.nix
@@ -5,42 +5,23 @@
...
}:
let
- irc-xxx = pkgs.lib.panoptikon.kpaste-irc {
+ irc-xxx = pkgs.panoptikonReporters.kpaste-irc {
target = lib.escapeShellArg "#xxx";
retiolumLink = true;
};
- matrix =
- {
- server ? "matrix.4d2.org",
- target,
- }:
- pkgs.writers.writeDash "matrix-reporter" ''
- export RAW_MESSAGE="$(cat)"
- export MESSAGE=$(printf '%s
%s' "$PANOPTIKON_WATCHER" "$RAW_MESSAGE") - export MATRIX_TOKEN="$(cat ${config.age.secrets.matrix-token-lakai.path})" - export JSON_PAYLOAD=$(${pkgs.jq}/bin/jq -n --arg msgtype "m.text" --arg body "$RAW_MESSAGE" --arg formattedBody "$MESSAGE" '{msgtype: $msgtype, body: $body, format: "org.matrix.custom.html", formatted_body: $formattedBody}') - ${pkgs.curl}/bin/curl -X POST "https://${server}/_matrix/client/r0/rooms/${target}/send/m.room.message" \ - -d "$JSON_PAYLOAD" \ - -H "Authorization: Bearer $MATRIX_TOKEN" \ - -H "Content-Type: application/json" - ''; + matrix-kmein = pkgs.panoptikonReporters.matrix { + homeserver = "matrix.4d2.org"; + roomId = lib.escapeShellArg "!zlwCuPiCNMSxDviFzA:4d2.org"; + tokenPath = config.age.secrets.matrix-token-lakai.path; + }; - matrix-kmein = matrix { target = "!zlwCuPiCNMSxDviFzA:4d2.org"; }; + telegram-kmein = pkgs.panoptikonReporters.telegram { + tokenPath = config.age.secrets.telegram-token-kmein.path; + chatId = "-1001796440545"; + }; - telegram-kmein = - let - chatId = "-1001796440545"; - in - pkgs.writers.writeDash "telegram-fulltext" '' - export TOKEN="$(cat "$CREDENTIALS_DIRECTORY/token")" - ${pkgs.curl}/bin/curl -X POST "https://api.telegram.org/bot''${TOKEN}/sendMessage" \ - -d chat_id=${chatId} \ - -d text="$(cat)" \ - | ${pkgs.jq}/bin/jq -e .ok - ''; - - irc-kmein = pkgs.lib.panoptikon.kpaste-irc { + irc-kmein = pkgs.panoptikonReporters.kpaste-irc { messagePrefix = "$PANOPTIKON_WATCHER: "; target = "kmein"; nick = "panoptikon-kmein"; @@ -48,7 +29,12 @@ let }; in { - age.secrets.telegram-token-kmein.file = ../../secrets/telegram-token-kmein.age; + age.secrets.telegram-token-kmein = { + file = ../../secrets/telegram-token-kmein.age; + owner = "panoptikon"; + group = "panoptikon"; + mode = "400"; + }; age.secrets.matrix-token-lakai = { file = ../../secrets/matrix-token-lakai.age; owner = "panoptikon"; @@ -60,7 +46,7 @@ in enable = true; watchers = { "github-meta" = { - script = pkgs.lib.panoptikon.urlJSON { + script = pkgs.panoptikonWatchers.json { jqScript = '' { ssh_key_fingerprints: .ssh_key_fingerprints, @@ -70,83 +56,71 @@ in } "https://api.github.com/meta"; reporters = [ irc-xxx ]; }; - lammla = { - script = pkgs.lib.panoptikon.url "http://lammla.info/index.php?reihe=30"; - reporters = [ matrix-kmein ]; - }; - kratylos = { - script = pkgs.lib.panoptikon.url "https://kratylos.reichert-online.org/current_issue/KRATYLOS"; - reporters = [ matrix-kmein ]; - }; kobudo-tesshinkan = { - script = pkgs.lib.panoptikon.url "https://kobudo-tesshinkan.eu/index.php/de/termine-berichte/lehrgaenge/"; + script = pkgs.panoptikonWatchers.html "https://kobudo-tesshinkan.eu/index.php/de/termine-berichte/lehrgaenge/"; reporters = [ telegram-kmein matrix-kmein ]; }; - zeno-free = { - script = pkgs.lib.panoptikon.urlSelector ".zenoCOMain" "http://www.zeno.org/Lesesaal/M/E-Books"; - reporters = [ matrix-kmein ]; - }; carolinawelslau = { - script = pkgs.lib.panoptikon.urlSelector "#main" "https://carolinawelslau.de/"; + script = pkgs.panoptikonWatchers.htmlSelector "#main" "https://carolinawelslau.de/"; reporters = [ matrix-kmein ]; }; humboldt-preis = { - script = pkgs.lib.panoptikon.urlSelector "#content-core" "https://www.hu-berlin.de/de/ueberblick/menschen/ehrungen/humboldtpreis"; + script = pkgs.panoptikonWatchers.htmlSelector "#content-core" "https://www.hu-berlin.de/de/ueberblick/menschen/ehrungen/humboldtpreis"; reporters = [ matrix-kmein ]; }; lisalittmann = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://lisalittmann.de/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://lisalittmann.de/"; reporters = [ matrix-kmein ]; }; lisalittmann-archive = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://lisalittmann.de/archive/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://lisalittmann.de/archive/"; reporters = [ matrix-kmein ]; }; lisalittmann-projects = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://lisalittmann.de/projects/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://lisalittmann.de/projects/"; reporters = [ matrix-kmein ]; }; tatort = { - script = pkgs.lib.panoptikon.urlSelector ".linklist" "https://www.daserste.de/unterhaltung/krimi/tatort/sendung/index.html"; + script = pkgs.panoptikonWatchers.htmlSelector ".linklist" "https://www.daserste.de/unterhaltung/krimi/tatort/sendung/index.html"; reporters = [ matrix-kmein ]; }; warpgrid-idiomarium = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://warpgrid.de/idiomarium/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://warpgrid.de/idiomarium/"; reporters = [ matrix-kmein ]; }; warpgrid-futurism = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://warpgrid.de/futurism/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://warpgrid.de/futurism/"; reporters = [ matrix-kmein ]; }; warpgrid-imagiary = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://warpgrid.de/imagiary/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://warpgrid.de/imagiary/"; reporters = [ matrix-kmein ]; }; warpgrid-alchemy = { - script = pkgs.lib.panoptikon.urlSelector "#site-content" "https://warpgrid.de/alchemy/"; + script = pkgs.panoptikonWatchers.htmlSelector "#site-content" "https://warpgrid.de/alchemy/"; reporters = [ matrix-kmein ]; }; indogermanische-forschungen = { - script = pkgs.lib.panoptikon.urlSelector "#latestIssue" "https://www.degruyter.com/journal/key/INDO/html"; + script = pkgs.panoptikonWatchers.htmlSelector "#latestIssue" "https://www.degruyter.com/journal/key/INDO/html"; reporters = [ matrix-kmein ]; }; ig-neuigkeiten = { - script = pkgs.lib.panoptikon.urlSelector "[itemprop=articleBody]" "https://www.indogermanistik.org/aktuelles/neuigkeiten.html"; + script = pkgs.panoptikonWatchers.htmlSelector "[itemprop=articleBody]" "https://www.indogermanistik.org/aktuelles/neuigkeiten.html"; reporters = [ matrix-kmein ]; }; ig-tagungen = { - script = pkgs.lib.panoptikon.urlSelector "[itemprop=articleBody]" "https://www.indogermanistik.org/tagungen/tagungen-der-ig.html"; + script = pkgs.panoptikonWatchers.htmlSelector "[itemprop=articleBody]" "https://www.indogermanistik.org/tagungen/tagungen-der-ig.html"; reporters = [ matrix-kmein ]; }; fu-distant = { - script = pkgs.lib.panoptikon.urlSelector "#current_events" "https://www.geschkult.fu-berlin.de/en/e/ma-distant/Termine/index.html"; + script = pkgs.panoptikonWatchers.htmlSelector "#current_events" "https://www.geschkult.fu-berlin.de/en/e/ma-distant/Termine/index.html"; reporters = [ matrix-kmein ]; }; fu-aegyptologie = { - script = pkgs.lib.panoptikon.urlSelector "#current_events" "https://www.geschkult.fu-berlin.de/e/aegyptologie/termine/index.html"; + script = pkgs.panoptikonWatchers.htmlSelector "#current_events" "https://www.geschkult.fu-berlin.de/e/aegyptologie/termine/index.html"; reporters = [ matrix-kmein ]; }; };