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 @@