# frozen_string_literal: true class Immich::ImportGeodata attr_reader :user, :start_date, :end_date def initialize(user, start_date: '1970-01-01', end_date: nil) @user = user @start_date = start_date @end_date = end_date end def call immich_data = retrieve_immich_data log_no_data and return if immich_data.empty? immich_data_json = parse_immich_data(immich_data) file_name = file_name(immich_data_json) import = user.imports.find_or_initialize_by(name: file_name, source: :immich_api) create_import_failed_notification(import.name) and return unless import.new_record? import.file.attach( io: StringIO.new(immich_data_json.to_json), filename: file_name, content_type: 'application/json' ) import.save! end private def retrieve_immich_data Immich::RequestPhotos.new(user, start_date:, end_date:).call end def parse_immich_data(immich_data) geodata = immich_data.map do |asset| next unless valid?(asset) extract_geodata(asset) end geodata.compact.sort_by { |data| data[:timestamp] } end def valid?(asset) asset.dig('exifInfo', 'latitude') && asset.dig('exifInfo', 'longitude') && asset.dig('exifInfo', 'dateTimeOriginal') end def extract_geodata(asset) { latitude: asset['exifInfo']['latitude'], longitude: asset['exifInfo']['longitude'], lonlat: "SRID=4326;POINT(#{asset['exifInfo']['longitude']} #{asset['exifInfo']['latitude']})", timestamp: Point.normalize_timestamp(asset['exifInfo']['dateTimeOriginal']) } end def log_no_data Rails.logger.info 'No geodata found for Immich' end def create_import_failed_notification(import_name) Notifications::Create.new( user:, kind: :info, title: 'Import was not created', content: "Import with the same name (#{import_name}) already exists. If you want to proceed, delete the existing import and try again." ).call end def file_name(immich_data_json) from = Time.zone.at(immich_data_json.first[:timestamp]).to_date to = Time.zone.at(immich_data_json.last[:timestamp]).to_date "immich-geodata-#{user.email}-from-#{from}-to-#{to}.json" end end