Commit 25fe4fe72ce5
Changed files (5)
home
common
services
home/common/services/readwise-reader.nix
@@ -0,0 +1,131 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+with lib;
+
+let
+ cfg = config.services.readwise-reader;
+
+ python = pkgs.python3.withPackages (ps: [
+ ps.requests
+ ps.click
+ ]);
+
+ readwise-reader-script = ../../../tools/readwise-reader/readwise-reader.py;
+
+ readwise-reader-wrapper = pkgs.writeShellScriptBin "readwise-reader-triage" ''
+ set -euo pipefail
+
+ export PATH="${
+ lib.makeBinPath [
+ pkgs.passage
+ pkgs.google-cloud-sdk
+ ]
+ }:$PATH"
+ export PASSAGE_DIR="${config.home.homeDirectory}/.local/share/passage"
+ export PASSAGE_IDENTITIES_FILE="${config.home.homeDirectory}/.local/share/passage/identities"
+ export XDG_DATA_HOME="${config.home.homeDirectory}/.local/share"
+ export GOOGLE_CLOUD_PROJECT="itpc-gcp-pnd-pe-eng-claude"
+ export GOOGLE_CLOUD_LOCATION="us-east5"
+
+ SCRIPT="${readwise-reader-script}"
+
+ echo "[$(date -Iseconds)] Starting readwise-reader triage..."
+
+ echo "โ Fetching documents..."
+ ${python}/bin/python "$SCRIPT" fetch
+
+ echo "โ Analyzing with ${cfg.model}..."
+ ${python}/bin/python "$SCRIPT" analyze -m ${cfg.model}
+
+ echo "โ Generating report..."
+ ${python}/bin/python "$SCRIPT" report --no-open
+
+ echo "[$(date -Iseconds)] Done. Report at ${cfg.outputDir}/triage-report.html"
+ '';
+in
+{
+ options.services.readwise-reader = {
+ enable = mkEnableOption "Readwise Reader triage report generation";
+
+ model = mkOption {
+ type = types.str;
+ default = "opus";
+ description = "LLM model for analysis (opus, sonnet, gemini, gemini25)";
+ };
+
+ interval = mkOption {
+ type = types.str;
+ default = "daily";
+ description = "How often to regenerate (systemd timer format)";
+ };
+
+ outputDir = mkOption {
+ type = types.str;
+ default = "${config.home.homeDirectory}/.local/share/readwise";
+ description = "Directory containing the report output";
+ };
+
+ serve = {
+ enable = mkEnableOption "serve the triage report via darkhttpd";
+
+ port = mkOption {
+ type = types.port;
+ default = 8880;
+ description = "Port for the HTTP server";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ home.packages = [
+ readwise-reader-wrapper
+ ];
+
+ systemd.user.services.readwise-reader-triage = {
+ Unit = {
+ Description = "Readwise Reader triage: fetch, analyze, generate report";
+ };
+ Service = {
+ Type = "oneshot";
+ ExecStart = "${readwise-reader-wrapper}/bin/readwise-reader-triage";
+ # Give enough time for LLM analysis
+ TimeoutStartSec = "30min";
+ };
+ };
+
+ systemd.user.timers.readwise-reader-triage = {
+ Unit = {
+ Description = "Timer for Readwise Reader triage report";
+ };
+ Timer = {
+ OnCalendar = cfg.interval;
+ Persistent = true;
+ # Randomize to avoid hitting API limits simultaneously with other services
+ RandomizedDelaySec = "15min";
+ };
+ Install = {
+ WantedBy = [ "timers.target" ];
+ };
+ };
+
+ systemd.user.services.readwise-reader-serve = mkIf cfg.serve.enable {
+ Unit = {
+ Description = "Serve Readwise Reader triage report";
+ After = [ "readwise-reader-triage.service" ];
+ };
+ Service = {
+ ExecStart = "${pkgs.darkhttpd}/bin/darkhttpd ${cfg.outputDir} --port ${toString cfg.serve.port} --no-listing";
+ Restart = "always";
+ RestartSec = 5;
+ };
+ Install = {
+ WantedBy = [ "default.target" ];
+ };
+ };
+ };
+}
systems/okinawa/extra.nix
@@ -261,6 +261,7 @@
5000 # Harmonia binary cache
5555 # OpenCode web
8090 # llama-server
+ 8880 # readwise-reader triage report
9000 # Prometheus node exporter
];
systems/okinawa/home.nix
@@ -26,6 +26,7 @@ in
../../home/common/services/gcal-to-org.nix
../../home/common/services/goimapnotify.nix
../../home/common/services/mail-monitor.nix
+ ../../home/common/services/readwise-reader.nix
../../home/common/services/readwise-sync.nix
../../home/common/services/redhat.nix
../../home/common/shell/gh.nix
@@ -116,6 +117,17 @@ in
interval = "daily";
};
+ # Readwise Reader triage report
+ services.readwise-reader = {
+ enable = true;
+ model = "opus";
+ interval = "daily";
+ serve = {
+ enable = true;
+ port = 8880;
+ };
+ };
+
# ntfy notification subscriber
# disabled: auth token expired, causes ~7k retry log lines per boot
# systemd.user.services.ntfy-subscriber = {
systems/rhea/extra.nix
@@ -349,6 +349,7 @@ in
opencode = mkRouter "opencode" [ "opencode.sbr.pm" ];
# llama-server on okinawa (VPN-only, OpenAI-compatible API)
llm = mkRouter "llm" [ "llm.sbr.pm" ];
+ reading = mkRouter "reading" [ "reading.sbr.pm" ];
# SearXNG metasearch engine on sakhalin
search = mkRouter "search" [
"search.sbr.pm"
@@ -378,6 +379,7 @@ in
lidarr = mkService "http://${builtins.head globals.machines.aion.net.ips}:8686";
opencode = mkService "http://${builtins.head globals.machines.okinawa.net.vpn.ips}:5555";
llm = mkService "http://${builtins.head globals.machines.okinawa.net.vpn.ips}:8090";
+ reading = mkService "http://${builtins.head globals.machines.okinawa.net.vpn.ips}:8880";
search = mkService "http://${builtins.head globals.machines.sakhalin.net.vpn.ips}:8090";
};
middlewares =
globals.nix
@@ -674,6 +674,8 @@ _: {
opencode.host = "rhea";
# llama-server on okinawa (routed through rhea/traefik)
llm.host = "rhea";
+ # Readwise Reader triage report on okinawa (routed through rhea/traefik)
+ reading.host = "rhea";
# SearXNG metasearch engine on aomi (routed through rhea/traefik)
search = {
host = "rhea";