diff --git a/flake.lock b/flake.lock index b32421f..c4e94fa 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { @@ -35,16 +35,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1690370995, - "narHash": "sha256-9z//23jGegLJrf3ITStLwVf715O39dq5u48Kr/XW14U=", + "lastModified": 1703467016, + "narHash": "sha256-/5A/dNPhbQx/Oa2d+Get174eNI3LERQ7u6WTWOlR1eQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f3fbbc36b4e179a5985b9ab12624e9dfe7989341", + "rev": "d02d818f22c777aa4e854efc3242ec451e5d462a", "type": "github" }, "original": { "id": "nixpkgs", - "ref": "nixos-23.05", + "ref": "nixos-23.11", "type": "indirect" } }, @@ -63,11 +63,11 @@ ] }, "locked": { - "lastModified": 1675083208, - "narHash": "sha256-+sSFhSpV2jckr1qYlX/SaxQ6IdpagD6o4rru/3HAl0I=", + "lastModified": 1698464090, + "narHash": "sha256-Pnej7WZIPomYWg8f/CZ65sfW85IfIUjYhphMMg7/LT0=", "owner": "zaninime", "repo": "sbt-derivation", - "rev": "92d6d6d825e3f6ae5642d1cce8ff571c3368aaf7", + "rev": "6762cf2c31de50efd9ff905cbcc87239995a4ef9", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index dcc14da..2840d83 100644 --- a/flake.nix +++ b/flake.nix @@ -1,140 +1,150 @@ { inputs = { - nixpkgs.url = "nixpkgs/nixos-23.05"; + nixpkgs.url = "nixpkgs/nixos-23.11"; flake-utils.url = "github:numtide/flake-utils"; sbt.url = "github:zaninime/sbt-derivation/master"; # recommended for first style of usage documented below, but not necessary sbt.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = { - self, - nixpkgs, - sbt, - flake-utils, - }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; - }; - in { - packages.default = import ./package.nix { pkgs = pkgs; sbt = sbt; self = self; }; - #checks.build = self.packages.default; - } - ) // { + outputs = + { self + , nixpkgs + , sbt + , flake-utils + , + }: + flake-utils.lib.eachDefaultSystem + (system: + let + pkgs = import nixpkgs { + inherit system; + }; + in + { + packages.default = import ./package.nix { pkgs = pkgs; sbt = sbt; self = self; }; + #checks.build = self.packages.default; + } + ) // { - nixosModules.photoprism-slideshow = { lib, pkgs, config, ... }: - let - cfg = config.services.photoprism-slideshow; - in - { - options = with lib; { - services.photoprism-slideshow = { - enable = mkOption { - type = types.bool; - default = false; - }; + nixosModules.photoprism-slideshow = { lib, pkgs, config, ... }: + let + cfg = config.services.photoprism-slideshow; + in + { + options = with lib; { + services.photoprism-slideshow = { + enable = mkOption { + type = types.bool; + default = false; + }; - preload = mkOption { - type = types.bool; - default = false; - }; + preload = mkOption { + type = types.bool; + default = false; + }; - port = mkOption { - type = types.int; - default = 23234; - }; + port = mkOption { + type = types.int; + default = 23234; + }; + + database = mkOption { + type = types.str; + default = "/var/lib/photoprism/index.db"; + }; + + basePath = mkOption { + type = types.str; + default = "/slideshow"; + }; - database = mkOption { - type = types.str; - default = "/var/lib/photoprism/index.db"; + package = mkOption { + type = types.package; + default = self.outputs.packages."${pkgs.system}".default; + }; + + interval = mkOption { + type = types.int; + default = 10; + }; + }; }; - basePath = mkOption { - type = types.str; - default = "/slideshow"; - }; + config = with lib; mkIf cfg.enable { - package = mkOption { - type = types.package; - default = self.outputs.packages."${pkgs.system}".default; - }; - }; - }; + systemd.services.photoprism-slideshow-reload = mkIf cfg.preload { + enable = true; + startAt = "*-*-* 01:34:00"; + script = '' + ${pkgs.systemd}/bin/systemctl restart photoprism-slideshow + ''; + }; - config = with lib; mkIf cfg.enable { - - systemd.services.photoprism-slideshow-reload = mkIf cfg.preload { - enable = true; - startAt = "*-*-* 01:34:00"; - script = '' - ${pkgs.systemd}/bin/systemctl restart photoprism-slideshow - ''; - }; - - systemd.services.photoprism-slideshow = { - enable = true; - path = [ ]; - preStart = if cfg.preload then '' - cd /var/cache/photoprism-slideshow - [ -e photoprism-slideshow.db ] && rm -- photoprism-slideshow.db - ${pkgs.sqlite}/bin/sqlite3 ${cfg.database} ".clone photoprism-slideshow.db" - '' else ""; - environment = { - SERVER_PORT = toString cfg.port; - DATABASE = if cfg.preload then "/var/cache/photoprism-slideshow/photoprism-slideshow.db" else cfg.database; - BASE_PATH = cfg.basePath; - }; + systemd.services.photoprism-slideshow = { + enable = true; + path = [ ]; + preStart = + if cfg.preload then '' + cd /var/cache/photoprism-slideshow + [ -e photoprism-slideshow.db ] && rm -- photoprism-slideshow.db + ${pkgs.sqlite}/bin/sqlite3 ${cfg.database} ".clone photoprism-slideshow.db" + '' else ""; + environment = { + SERVER_PORT = toString cfg.port; + DATABASE = if cfg.preload then "/var/cache/photoprism-slideshow/photoprism-slideshow.db" else cfg.database; + BASE_PATH = cfg.basePath; + INTERVAL = toString cfg.interval; + }; - script = '' - ${cfg.package}/bin/photoprism-slideshow - ''; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - serviceConfig = { - DynamicUser = true; - Restart = "on-failure"; - CacheDirectory = "photoprism-slideshow"; - # Hardening - CapabilityBoundingSet = ""; - DeviceAllow = ""; - DevicePolicy = "closed"; - LockPersonality = true; - MemoryDenyWriteExecute = false; - NoNewPrivileges = true; - PrivateDevices = true; - PrivateUsers = true; - PrivateTmp = true; - ProtectClock = true; - ProtectControlGroups = true; - ProtectHome = true; - ProtectHostname = true; - ProtectKernelLogs = true; - ProtectKernelModules = true; - ProtectKernelTunables = true; - ProtectProc = "invisible"; - ProcSubset = "pid"; - ProtectSystem = "strict"; - RemoveIPC = true; - RestrictAddressFamilies = [ - "AF_INET" - "AF_INET6" - ]; - RestrictNamespaces = true; - RestrictRealtime = true; - RestrictSUIDSGID = true; - SupplementaryGroups = []; - SystemCallArchitectures = "native"; - SystemCallFilter = [ - "@system-service @pkey" - "~@privileged @resources" - ]; - UMask = "0077"; + script = '' + ${cfg.package}/bin/photoprism-slideshow + ''; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + DynamicUser = true; + Restart = "on-failure"; + CacheDirectory = "photoprism-slideshow"; + # Hardening + CapabilityBoundingSet = ""; + DeviceAllow = ""; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = false; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateUsers = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SupplementaryGroups = [ ]; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service @pkey" + "~@privileged @resources" + ]; + UMask = "0077"; + }; + }; }; }; - }; }; - }; } diff --git a/package.nix b/package.nix index f20ee20..feb50ab 100644 --- a/package.nix +++ b/package.nix @@ -4,7 +4,7 @@ sbt.lib.mkSbtDerivation { inherit pkgs; pname = "photoprism-slideshow"; - version = "0.0.1"; + version = "0.1.0"; depsSha256 = "sha256-qwtUYKy51TFA/q/Yd2bwzrPSkA/Xjrsbb8ftQf/0PlM="; diff --git a/src/main/scala/photoprism/slideshow/main.scala b/src/main/scala/photoprism/slideshow/main.scala index 15f037f..b67c161 100644 --- a/src/main/scala/photoprism/slideshow/main.scala +++ b/src/main/scala/photoprism/slideshow/main.scala @@ -9,6 +9,7 @@ object PhotoprismSlideshowApp extends cask.MainRoutes{ val db = scala.util.Properties.envOrElse("DATABASE", "./index.db") val basePath = scala.util.Properties.envOrElse("BASE_PATH", "") + val interval = scala.util.Properties.envOrElse("INTERVAL", "10").toInt val ds: javax.sql.DataSource = { val ds = org.sqlite.SQLiteDataSource() @@ -57,7 +58,7 @@ object PhotoprismSlideshowApp extends cask.MainRoutes{ ) ), tag("script")(raw(s""" - var intervalID = window.setInterval(refreshImage, 10 * 1000); + var intervalID = window.setInterval(refreshImage, ${interval} * 1000); function refreshImage() { fetch('./photo/random/' + location.hash.substr(1)) @@ -69,6 +70,7 @@ object PhotoprismSlideshowApp extends cask.MainRoutes{ // Examine the text in the response response.json().then(function(data) { + (new Image()).src = data.photo; document.getElementById('title').innerText = data.title; document.getElementsByTagName('title')[0].innerText = data.title; document.getElementById('ts').innerText = data.taken_at;