# frozen_string_literal: true # This integration built based on # [September 15, 2024](https://github.com/photoprism/photoprism/releases/tag/240915-e1280b2fb) # release of Photoprism. 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 = URI.parse("#{user.safe_settings.photoprism_url}/api/v1/photos") @photoprism_api_key = user.safe_settings.photoprism_api_key @start_date = start_date @end_date = end_date end def call raise ArgumentError, 'Photoprism URL is missing' if user.safe_settings.photoprism_url.blank? raise ArgumentError, 'Photoprism API key is missing' if photoprism_api_key.blank? data = retrieve_photoprism_data return [] if data.blank? || data[0]['error'].present? time_framed_data(data, start_date, end_date) end private def retrieve_photoprism_data data = [] offset = 0 while offset < 1_000_000 response_data = fetch_page(offset) break if response_data.blank? || (response_data.is_a?(Hash) && response_data.try(:[], 'error').present?) data << response_data offset += 1000 end data.flatten rescue HTTParty::Error, Net::OpenTimeout, Net::ReadTimeout => e Rails.logger.error("Photoprism photo fetch failed: #{e.message}") [] end def fetch_page(offset) response = HTTParty.get( photoprism_api_base_url, headers: headers, query: request_params(offset), timeout: 10 ) if response.code != 200 Rails.logger.error "Photoprism API returned #{response.code}: #{response.body}" Rails.logger.debug "Photoprism API request params: #{request_params(offset).inspect}" end cache_preview_token(response.headers) JSON.parse(response.body) end def headers { 'Authorization' => "Bearer #{photoprism_api_key}", 'accept' => 'application/json' } end def request_params(offset = 0) params = offset.zero? ? default_params : default_params.merge(offset: offset) params[:before] = end_date if end_date.present? params end def default_params { q: '', public: true, quality: 3, after: start_date, count: 1000 } end def time_framed_data(data, start_date, end_date) 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 def cache_preview_token(headers) preview_token = headers['X-Preview-Token'] Photoprism::CachePreviewToken.new(user, preview_token).call end end