2023-01-28 21:27:52 +00:00
|
|
|
{
|
2023-10-07 14:45:42 +00:00
|
|
|
flake,
|
2023-01-28 21:27:52 +00:00
|
|
|
lib,
|
|
|
|
config,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
with lib; let
|
2022-02-14 09:49:49 +00:00
|
|
|
psCfg = config.pub-solar;
|
|
|
|
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
|
2023-08-29 11:56:18 +00:00
|
|
|
|
2023-10-07 14:45:42 +00:00
|
|
|
dataDir = "${xdg.dataHome}/Paperless";
|
2023-10-09 20:52:28 +00:00
|
|
|
backupDir = "${xdg.dataHome}/PaperlessBackup";
|
2023-10-07 14:45:42 +00:00
|
|
|
consumptionDir = "/home/${psCfg.user.name}/.local/share/scandir";
|
2023-11-20 16:29:03 +00:00
|
|
|
|
|
|
|
scan2paperless = with pkgs; writeShellScriptBin "scan2paperless" ''
|
|
|
|
DEVICE=$1
|
|
|
|
NUM_PAGES=$2
|
|
|
|
NAME=$3
|
|
|
|
|
|
|
|
if [ -z "''${DEVICE}" ] || [ -z "''${NUM_PAGES}" ] || [ -z "''${NAME}" ]; then
|
|
|
|
echo "Usage: scan2paperless <device> <num_pages> <name>"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
tmpDir=$(${coreutils}/bin/mktemp -d)
|
|
|
|
files=()
|
|
|
|
|
|
|
|
for i in $(seq 1 $NUM_PAGES); do
|
|
|
|
fileName=$(${openssl}/bin/openssl rand -hex 12)
|
|
|
|
file="$tmpDir/$fileName.jpg"
|
|
|
|
echo "Start scanning page $i/$NUM_PAGES";
|
|
|
|
${sane-backends}/bin/scanimage -d $DEVICE --format=jpeg --resolution 300 --progress -o $file
|
|
|
|
echo "Finished scanning page $i";
|
|
|
|
files+=($file)
|
|
|
|
done
|
|
|
|
|
|
|
|
pdf="${consumptionDir}/$NAME.pdf"
|
2024-01-29 22:02:05 +00:00
|
|
|
${python3Packages.img2pdf}/bin/img2pdf --output $pdf ''${files[@]}
|
2023-11-20 16:29:03 +00:00
|
|
|
|
|
|
|
echo "PDF written to $pdf"
|
|
|
|
'';
|
2023-10-07 14:45:42 +00:00
|
|
|
in {
|
2024-03-12 11:17:01 +00:00
|
|
|
#################################
|
|
|
|
# Paperless service and proxy
|
|
|
|
#################################
|
|
|
|
|
|
|
|
security.acme.certs = {
|
|
|
|
"paperless.b12f.io" = {};
|
|
|
|
};
|
|
|
|
|
|
|
|
services.nginx.virtualHosts = {
|
|
|
|
"paperless.b12f.io" = {
|
|
|
|
forceSSL = true;
|
|
|
|
useACMEHost = "paperless.b12f.io";
|
|
|
|
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString config.services.paperless.port}";
|
2024-03-25 20:06:08 +00:00
|
|
|
listenAdresses = [
|
|
|
|
"127.0.0.1"
|
|
|
|
"::1"
|
|
|
|
"10.13.12.2"
|
|
|
|
"fd00:b12f:acab:1312:acab:2::"
|
|
|
|
];
|
2024-03-12 11:17:01 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-03-25 20:06:08 +00:00
|
|
|
services.authelia.instances.b12f.settings.clients = [{
|
|
|
|
client_id = "paperless";
|
|
|
|
client_name = "Paperless";
|
|
|
|
client_secret = "";
|
|
|
|
consent_mode = "implicit";
|
|
|
|
}];
|
|
|
|
|
2023-10-07 14:45:42 +00:00
|
|
|
services.paperless = {
|
|
|
|
enable = true;
|
|
|
|
user = psCfg.user.name;
|
|
|
|
consumptionDir = consumptionDir;
|
|
|
|
dataDir = dataDir;
|
2023-11-01 15:27:29 +00:00
|
|
|
address = "127.0.0.1";
|
2023-10-07 14:45:42 +00:00
|
|
|
extraConfig = {
|
|
|
|
PAPERLESS_OCR_LANGUAGE = "nld+deu";
|
2023-11-01 15:27:29 +00:00
|
|
|
PAPERLESS_URL = "https://paperless.b12f.io";
|
2024-03-25 20:06:08 +00:00
|
|
|
PAPERLESS_SOCIALACCOUNT_PROVIDERS = (builtins.toJSON {
|
|
|
|
openid_connect = {
|
|
|
|
APPS = [
|
|
|
|
{
|
|
|
|
provider_id = "keycloak";
|
|
|
|
name = "Keycloak";
|
|
|
|
client_id = "<insert-id>";
|
|
|
|
secret = "<insert-secret>";
|
|
|
|
settings.server_url = "http://keycloak:8080/realms/master/.well-known/openid-configuration";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
|
|
|
});
|
2023-02-07 14:56:19 +00:00
|
|
|
};
|
2022-02-14 09:49:49 +00:00
|
|
|
};
|
|
|
|
|
2024-03-12 11:17:01 +00:00
|
|
|
#################################
|
|
|
|
# Scanning
|
|
|
|
#################################
|
|
|
|
|
2023-10-10 11:37:17 +00:00
|
|
|
hardware.sane = {
|
|
|
|
enable = true;
|
|
|
|
extraBackends = [pkgs.hplipWithPlugin];
|
|
|
|
};
|
|
|
|
|
2023-10-07 14:45:42 +00:00
|
|
|
users.users."${psCfg.user.name}".packages = with pkgs; [
|
2023-11-20 16:29:03 +00:00
|
|
|
scan2paperless
|
2023-10-07 14:45:42 +00:00
|
|
|
sane-backends
|
|
|
|
];
|
2023-02-07 14:56:19 +00:00
|
|
|
|
2023-10-07 14:45:42 +00:00
|
|
|
home-manager.users."${psCfg.user.name}" = {
|
|
|
|
home.sessionVariables = {
|
|
|
|
SCANNER_OUTPUT_DIR = consumptionDir;
|
2022-02-14 09:49:49 +00:00
|
|
|
};
|
2023-10-07 14:45:42 +00:00
|
|
|
systemd.user.sessionVariables = {
|
|
|
|
SCANNER_OUTPUT_DIR = consumptionDir;
|
2023-08-29 11:56:18 +00:00
|
|
|
};
|
2022-02-14 09:49:49 +00:00
|
|
|
};
|
2023-10-07 14:45:42 +00:00
|
|
|
|
2024-03-12 11:17:01 +00:00
|
|
|
#################################
|
|
|
|
# hosting.de invoice fetch
|
|
|
|
#################################
|
|
|
|
|
|
|
|
age.secrets."hosting-de-invoice-sync-api-key" = {
|
|
|
|
file = "${flake.self}/secrets/hosting-de-invoice-sync-api-key.age";
|
|
|
|
mode = "400";
|
2024-03-19 17:33:13 +00:00
|
|
|
owner = psCfg.user.name;
|
2023-11-14 17:44:46 +00:00
|
|
|
};
|
2023-11-13 14:48:05 +00:00
|
|
|
|
2024-03-12 11:17:01 +00:00
|
|
|
services.cron = {
|
|
|
|
enable = true;
|
|
|
|
systemCronJobs = [
|
2024-03-19 17:33:13 +00:00
|
|
|
"30 1 * * * ${psCfg.user.name} ${pkgs.fetch-hostingde-invoices}/bin/fetch-hostingde-invoices '${config.age.secrets."hosting-de-invoice-sync-api-key".path}' '${consumptionDir}'"
|
2024-03-12 11:17:01 +00:00
|
|
|
];
|
2023-10-07 19:11:08 +00:00
|
|
|
};
|
2023-10-09 20:52:28 +00:00
|
|
|
|
2024-03-12 11:17:01 +00:00
|
|
|
#################################
|
|
|
|
# Backups
|
|
|
|
#################################
|
|
|
|
|
2023-10-09 20:52:28 +00:00
|
|
|
systemd.tmpfiles.rules = [
|
|
|
|
"d '${backupDir}' 0700 ${psCfg.user.name} users - -"
|
2024-03-19 17:33:13 +00:00
|
|
|
"d /tmp/paperless 0700 ${psCfg.user.name} users - -"
|
2023-10-09 20:52:28 +00:00
|
|
|
];
|
|
|
|
|
2024-03-25 20:06:08 +00:00
|
|
|
age.secrets."rclone-pie.conMoK~Ih_gjsd4Yo0U7eYcyZ5WHFy1n_a3BGwy_E5TVb8z2FaFzGnQS08TpTf~4ilPG5r5hytf" = {
|
2023-11-05 17:56:11 +00:00
|
|
|
file = "${flake.self}/secrets/rclone-pie.conf.age";
|
2023-10-09 20:52:28 +00:00
|
|
|
path = "/root/.config/rclone/rclone.conf";
|
2023-11-12 17:19:07 +00:00
|
|
|
mode = "400";
|
2023-10-09 20:52:28 +00:00
|
|
|
};
|
|
|
|
|
2023-11-05 17:56:11 +00:00
|
|
|
age.secrets."restic-password" = {
|
2023-10-09 20:52:28 +00:00
|
|
|
file = "${flake.self}/secrets/restic-password.age";
|
2023-11-12 17:19:07 +00:00
|
|
|
mode = "400";
|
2023-10-09 20:52:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
services.restic.backups = {
|
|
|
|
paperless = {
|
|
|
|
paths = [ backupDir ];
|
|
|
|
initialize = true;
|
2023-11-05 17:56:11 +00:00
|
|
|
passwordFile = config.age.secrets."restic-password".path;
|
2023-10-09 20:52:28 +00:00
|
|
|
# See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/
|
|
|
|
repository = "rclone:cloud.pub.solar:/backups/Paperless";
|
|
|
|
backupPrepareCommand = "${dataDir}/paperless-manage document_exporter ${backupDir} -c -p";
|
|
|
|
rcloneConfigFile = config.age.secrets."rclone-pie.conf".path;
|
|
|
|
};
|
|
|
|
};
|
2022-02-14 09:49:49 +00:00
|
|
|
}
|