From 1f9e1f2f97e8b64b86999ed8690c9ba8373a7546 Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Mon, 2 Dec 2024 16:52:05 +0100 Subject: [PATCH] Add basic Photoprism photos integration --- app/controllers/api/v1/settings_controller.rb | 16 ++-- app/controllers/settings_controller.rb | 2 +- app/models/user.rb | 6 ++ app/services/photoprism/request_photos.rb | 80 +++++++++++++++++++ app/views/settings/_navigation.html.erb | 2 +- app/views/settings/index.html.erb | 12 ++- 6 files changed, 105 insertions(+), 13 deletions(-) create mode 100644 app/services/photoprism/request_photos.rb diff --git a/app/controllers/api/v1/settings_controller.rb b/app/controllers/api/v1/settings_controller.rb index 660f88e0..f87d9df7 100644 --- a/app/controllers/api/v1/settings_controller.rb +++ b/app/controllers/api/v1/settings_controller.rb @@ -12,16 +12,11 @@ class Api::V1::SettingsController < ApiController settings_params.each { |key, value| current_api_user.settings[key] = value } if current_api_user.save - render json: { - message: 'Settings updated', - settings: current_api_user.settings, - status: 'success' - }, status: :ok + render json: { message: 'Settings updated', settings: current_api_user.settings, status: 'success' }, + status: :ok else - render json: { - message: 'Something went wrong', - errors: current_api_user.errors.full_messages - }, status: :unprocessable_entity + render json: { message: 'Something went wrong', errors: current_api_user.errors.full_messages }, + status: :unprocessable_entity end end @@ -31,7 +26,8 @@ class Api::V1::SettingsController < ApiController params.require(:settings).permit( :meters_between_routes, :minutes_between_routes, :fog_of_war_meters, :time_threshold_minutes, :merge_threshold_minutes, :route_opacity, - :preferred_map_layer, :points_rendering_mode, :live_map_enabled + :preferred_map_layer, :points_rendering_mode, :live_map_enabled, + :immich_url, :immich_api_key, :photoprism_url, :photoprism_api_key ) end end diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index 8442bb94..243189cf 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -31,7 +31,7 @@ class SettingsController < ApplicationController params.require(:settings).permit( :meters_between_routes, :minutes_between_routes, :fog_of_war_meters, :time_threshold_minutes, :merge_threshold_minutes, :route_opacity, - :immich_url, :immich_api_key + :immich_url, :immich_api_key, :photoprism_url, :photoprism_api_key ) end end diff --git a/app/models/user.rb b/app/models/user.rb index a102d0b5..e9da779f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,6 +18,7 @@ class User < ApplicationRecord has_many :trips, dependent: :destroy after_create :create_api_key + before_save :strip_trailing_slashes def countries_visited stats.pluck(:toponyms).flatten.map { _1['country'] }.uniq.compact @@ -60,4 +61,9 @@ class User < ApplicationRecord save end + + def strip_trailing_slashes + settings['immich_url'].gsub!(%r{/+\z}, '') + settings['photoprism_url'].gsub!(%r{/+\z}, '') + end end diff --git a/app/services/photoprism/request_photos.rb b/app/services/photoprism/request_photos.rb new file mode 100644 index 00000000..9873c1e7 --- /dev/null +++ b/app/services/photoprism/request_photos.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +class Photoprism::RequestPhotos + attr_reader :user, :photoprism_api_base_url, :photoprism_api_key, :start_date, :end_date + + def initialize(user, start_date: '1970-01-01', end_date: nil) + @user = user + @photoprism_api_base_url = "#{user.settings['photoprism_url']}/api/v1/photos" + @photoprism_api_key = user.settings['photoprism_api_key'] + @start_date = start_date + @end_date = end_date + end + + def call + raise ArgumentError, 'Photoprism API key is missing' if photoprism_api_key.blank? + raise ArgumentError, 'Photoprism URL is missing' if user.settings['photoprism_url'].blank? + + data = retrieve_photoprism_data + + time_framed_data(data) + end + + private + + def retrieve_photoprism_data + data = [] + offset = 0 + + while offset < 1_000_000 + response = HTTParty.get( + photoprism_api_base_url, + headers: headers, + query: request_params(offset) + ) + + break if response.code != 200 + + photoprism_data = JSON.parse(response.body) + + data << photoprism_data + + break if photoprism_data.empty? + + offset += 1000 + end + + data + end + + def headers + { + 'Authorization' => "Bearer #{photoprism_api_key}", + 'accept' => 'application/json' + } + end + + def request_params(offset = 0) + params = { + q: '', + public: true, + quality: 3, + after: start_date, + offset: offset, + count: 1000 + } + + params.delete(:offset) if offset.zero? + params[:before] = end_date if end_date.present? + + params + end + + def time_framed_data(data) + data.flatten.select do |photo| + taken_at = DateTime.parse(photo['TakenAtLocal']) + end_date ||= Time.current + taken_at.between?(start_date.to_datetime, end_date.to_datetime) + end + end +end diff --git a/app/views/settings/_navigation.html.erb b/app/views/settings/_navigation.html.erb index 7232cc1c..b0b20437 100644 --- a/app/views/settings/_navigation.html.erb +++ b/app/views/settings/_navigation.html.erb @@ -1,5 +1,5 @@
- <%= link_to 'Main', settings_path, role: 'tab', class: "tab #{active_tab?(settings_path)}" %> + <%= link_to 'Integrations', settings_path, role: 'tab', class: "tab #{active_tab?(settings_path)}" %> <% if current_user.admin? %> <%= link_to 'Users', settings_users_path, role: 'tab', class: "tab #{active_tab?(settings_users_path)}" %> <%= link_to 'Background Jobs', settings_background_jobs_path, role: 'tab', class: "tab #{active_tab?(settings_background_jobs_path)}" %> diff --git a/app/views/settings/index.html.erb b/app/views/settings/index.html.erb index eb8e605f..613cfe73 100644 --- a/app/views/settings/index.html.erb +++ b/app/views/settings/index.html.erb @@ -5,7 +5,7 @@
-

Edit your Dawarich settings!

+

Edit your Integrations settings!

<%= form_for :settings, url: settings_path, method: :patch, data: { turbo_method: :patch, turbo: false } do |f| %>
<%= f.label :immich_url %> @@ -15,6 +15,16 @@ <%= f.label :immich_api_key %> <%= f.text_field :immich_api_key, value: current_user.settings['immich_api_key'], class: "input input-bordered", placeholder: 'xxxxxxxxxxxxxx' %>
+
+
+ <%= f.label :photoprism_url %> + <%= f.text_field :photoprism_url, value: current_user.settings['photoprism_url'], class: "input input-bordered", placeholder: 'http://192.168.0.1:2342' %> +
+
+ <%= f.label :photoprism_api_key %> + <%= f.text_field :photoprism_api_key, value: current_user.settings['photoprism_api_key'], class: "input input-bordered", placeholder: 'xxxxxxxxxxxxxx' %> +
+
<%= f.submit "Update", class: "btn btn-primary" %>