From 786bb5cbdc41a648d92cce2af374fa2d5655bd35 Mon Sep 17 00:00:00 2001
From: polyfloyd <floyd@polyfloyd.net>
Date: Sun, 10 Sep 2023 17:48:21 +0200
Subject: [PATCH] Add the photos role

---
 fotos.yaml                                    |  5 ++
 .../templates/public-bridge.conf              |  1 +
 roles/photos/defaults/main.yaml               |  3 +
 roles/photos/handlers/main.yaml               | 12 ++++
 roles/photos/tasks/main.yaml                  |  6 ++
 roles/photos/tasks/photo-gallery.yaml         | 24 ++++++++
 roles/photos/tasks/photos2mqtt.yaml           | 34 ++++++++++++
 roles/photos/templates/photo-gallery.service  | 13 +++++
 roles/photos/templates/photos2mqtt.pl         | 55 +++++++++++++++++++
 roles/photos/templates/photos2mqtt.service    | 16 ++++++
 10 files changed, 169 insertions(+)
 create mode 100644 fotos.yaml
 create mode 100644 roles/photos/defaults/main.yaml
 create mode 100644 roles/photos/handlers/main.yaml
 create mode 100644 roles/photos/tasks/main.yaml
 create mode 100644 roles/photos/tasks/photo-gallery.yaml
 create mode 100644 roles/photos/tasks/photos2mqtt.yaml
 create mode 100644 roles/photos/templates/photo-gallery.service
 create mode 100644 roles/photos/templates/photos2mqtt.pl
 create mode 100644 roles/photos/templates/photos2mqtt.service

diff --git a/fotos.yaml b/fotos.yaml
new file mode 100644
index 0000000..e141485
--- /dev/null
+++ b/fotos.yaml
@@ -0,0 +1,5 @@
+---
+- hosts: fotos
+  roles:
+    - common
+    - photos
diff --git a/roles/mqtt-internal/templates/public-bridge.conf b/roles/mqtt-internal/templates/public-bridge.conf
index 7b0494a..77d2557 100644
--- a/roles/mqtt-internal/templates/public-bridge.conf
+++ b/roles/mqtt-internal/templates/public-bridge.conf
@@ -11,3 +11,4 @@ topic bitlair/wifi/+/online out
 topic bitlair/climate/# out
 topic bitlair/humidity/+ out
 topic bitlair/lasercutter/+ out
+topic bitlair/photos out
diff --git a/roles/photos/defaults/main.yaml b/roles/photos/defaults/main.yaml
new file mode 100644
index 0000000..b44f77d
--- /dev/null
+++ b/roles/photos/defaults/main.yaml
@@ -0,0 +1,3 @@
+photos_mqtt_host: mqtt.bitlair.nl
+photos_mqtt_topic: bitlair/photos
+photos_path: /opt/wip
diff --git a/roles/photos/handlers/main.yaml b/roles/photos/handlers/main.yaml
new file mode 100644
index 0000000..0d76217
--- /dev/null
+++ b/roles/photos/handlers/main.yaml
@@ -0,0 +1,12 @@
+---
+- name: restart photo-gallery
+  systemd:
+    name: photo-gallery
+    state: restarted
+    daemon_reload: true
+
+- name: restart photos2mqtt
+  systemd:
+    name: photos2mqtt
+    state: restarted
+    daemon_reload: true
diff --git a/roles/photos/tasks/main.yaml b/roles/photos/tasks/main.yaml
new file mode 100644
index 0000000..0450d03
--- /dev/null
+++ b/roles/photos/tasks/main.yaml
@@ -0,0 +1,6 @@
+---
+- tags: photos_gallery
+  import_tasks: photo-gallery.yaml
+
+- tags: photos_mqtt
+  import_tasks: photos2mqtt.yaml
diff --git a/roles/photos/tasks/photo-gallery.yaml b/roles/photos/tasks/photo-gallery.yaml
new file mode 100644
index 0000000..946b400
--- /dev/null
+++ b/roles/photos/tasks/photo-gallery.yaml
@@ -0,0 +1,24 @@
+---
+- name: Clone source
+  git:
+    repo: https://github.com/bitlair/photo-gallery.git
+    version: master
+    dest: /opt/photo-gallery
+    accept_hostkey: yes
+  notify: restart photo-gallery
+
+- name: Install photo-gallery service file
+  template:
+    src: photo-gallery.service
+    dest: /etc/systemd/system/photo-gallery.service
+    owner: root
+    group: root
+    mode: 0644
+  notify: restart photo-gallery
+
+- name: Start photo-gallery
+  systemd:
+    name: photo-gallery
+    state: started
+    enabled: yes
+    daemon_reload: true
diff --git a/roles/photos/tasks/photos2mqtt.yaml b/roles/photos/tasks/photos2mqtt.yaml
new file mode 100644
index 0000000..9b9b453
--- /dev/null
+++ b/roles/photos/tasks/photos2mqtt.yaml
@@ -0,0 +1,34 @@
+---
+- name: Install dependencies
+  apt:
+    name:
+      - make
+      - liblinux-inotify2-perl
+
+- name: Install mqtt-simple
+  command: cpan Net::MQTT::Simple
+
+- name: Install photos2mqtt
+  template:
+    src: photos2mqtt.pl
+    dest: /opt/photos2mqtt.pl
+    owner: root
+    group: root
+    mode: 0755
+  notify: restart photos2mqtt
+
+- name: Install photos2mqtt service file
+  template:
+    src: photos2mqtt.service
+    dest: /etc/systemd/system/photos2mqtt.service
+    owner: root
+    group: root
+    mode: 0644
+  notify: restart photos2mqtt
+
+- name: Start photos2mqtt
+  systemd:
+    name: photos2mqtt
+    state: started
+    enabled: yes
+    daemon_reload: true
diff --git a/roles/photos/templates/photo-gallery.service b/roles/photos/templates/photo-gallery.service
new file mode 100644
index 0000000..df38be5
--- /dev/null
+++ b/roles/photos/templates/photo-gallery.service
@@ -0,0 +1,13 @@
+# Managed by Ansible
+
+[Unit]
+Description=Gallery service
+After=network.target
+
+[Service]
+ExecStart=/usr/bin/node /opt/photo-gallery/server.js
+Restart=always
+RestartSec=3
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/photos/templates/photos2mqtt.pl b/roles/photos/templates/photos2mqtt.pl
new file mode 100644
index 0000000..87a42f5
--- /dev/null
+++ b/roles/photos/templates/photos2mqtt.pl
@@ -0,0 +1,55 @@
+#!/usr/bin/perl -w
+
+# Managed by Ansible
+
+use strict;
+use Net::MQTT::Simple;
+use Linux::Inotify2;
+use POSIX qw(strftime);
+use Time::HiRes qw(sleep time);
+
+my $path = "{{ photos_path }}";
+my $mqtt = Net::MQTT::Simple->new('{{ photos_mqtt_host }}');
+
+my $inotify = new Linux::Inotify2 or die $!;
+$inotify->blocking(0);
+
+sub today {
+    return strftime "%Y%m%d", localtime;
+}
+
+sub watch_daydir {
+    my ($dn) = @_;
+
+    print "Watching $dn\n";
+
+    $inotify->watch($dn, IN_CREATE, sub {
+        my $event = shift;
+        $inotify->watch($event->fullname, IN_CLOSE_WRITE, sub {
+            my $event = shift;
+            my $fn = $event->fullname;
+            unless ($fn =~ m[^\.|/\.]) {  # skip hidden files
+                print "New file written: $fn\n";
+                $mqtt->retain("{{ photos_mqtt_topic }}", $fn =~ s[^$path/][]r);
+            }
+            $event->w->cancel;
+        });
+    });
+}
+
+print "Watching $path\n";
+$inotify->watch($path, IN_CREATE, sub {
+    my $event = shift;
+    my $dn = $event->fullname;
+    -d $dn or next;
+
+    watch_daydir($dn);
+});
+
+watch_daydir("$path/" . today());
+
+while (1) {
+    $mqtt->tick(.05);
+    $inotify->poll;
+    sleep .1;
+}
diff --git a/roles/photos/templates/photos2mqtt.service b/roles/photos/templates/photos2mqtt.service
new file mode 100644
index 0000000..dbdb130
--- /dev/null
+++ b/roles/photos/templates/photos2mqtt.service
@@ -0,0 +1,16 @@
+# Managed by Ansible
+
+[Unit]
+Description=Photos to MQTT
+After=network.target
+
+[Service]
+Type=simple
+Restart=on-failure
+RestartSec=10s
+ExecStart=/usr/bin/perl /opt/photos2mqtt.pl
+User=wip
+
+[Install]
+WantedBy=multi-user.target
+