From b336172b31fce5157bed8055c46ff837a87e5afc Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Tue, 10 Dec 2024 18:49:37 +0100 Subject: [PATCH] Show photoprism photos on a trip page --- app/helpers/application_helper.rb | 13 +++++++ app/models/import.rb | 5 ++- app/models/trip.rb | 52 +++++++++++++++++-------- app/serializers/api/photo_serializer.rb | 10 +++++ app/views/trips/show.html.erb | 10 +++-- 5 files changed, 68 insertions(+), 22 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5495369b..8cc09c1c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -120,4 +120,17 @@ module ApplicationHelper encoded_query = URI.encode_www_form_component(query.to_json) "#{base_url}/search?query=#{encoded_query}" end + + def photoprism_search_url(base_url, start_date, _end_date) + "#{base_url}/library/browse?view=cards&year=#{start_date.year}&month=#{start_date.month}&order=newest&public=true&quality=3" + end + + def photo_search_url(source, settings, start_date, end_date) + case source + when 'immich' + immich_search_url(settings['immich_url'], start_date, end_date) + when 'photoprism' + photoprism_search_url(settings['photoprism_url'], start_date, end_date) + end + end end diff --git a/app/models/import.rb b/app/models/import.rb index 2040d738..a0fbc870 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -18,8 +18,9 @@ class Import < ApplicationRecord end def years_and_months_tracked - points.order(:timestamp).map do |point| - [Time.zone.at(point.timestamp).year, Time.zone.at(point.timestamp).month] + points.order(:timestamp).pluck(:timestamp).map do |timestamp| + time = Time.zone.at(timestamp) + [time.year, time.month] end.uniq end end diff --git a/app/models/trip.rb b/app/models/trip.rb index 52948bf4..7a0fdaba 100644 --- a/app/models/trip.rb +++ b/app/models/trip.rb @@ -18,25 +18,15 @@ class Trip < ApplicationRecord end def photos - return [] if user.settings['immich_url'].blank? || user.settings['immich_api_key'].blank? + return [] unless can_fetch_photos? - immich_photos = Immich::RequestPhotos.new( - user, - start_date: started_at.to_date.to_s, - end_date: ended_at.to_date.to_s - ).call.reject { |asset| asset['type'].downcase == 'video' } + filtered_photos.sample(12) + .sort_by { |photo| photo['localDateTime'] } + .map { |asset| photo_thumbnail(asset) } + end - # let's count what photos are more: vertical or horizontal and select the ones that are more - vertical_photos = immich_photos.select { _1['exifInfo']['orientation'] == '6' } - horizontal_photos = immich_photos.select { _1['exifInfo']['orientation'] == '3' } - - # this is ridiculous, but I couldn't find my way around frontend - # to show all photos in the same height - photos = vertical_photos.count > horizontal_photos.count ? vertical_photos : horizontal_photos - - photos.sample(12).sort_by { _1['localDateTime'] }.map do |asset| - { url: "/api/v1/photos/#{asset['id']}/thumbnail.jpg?api_key=#{user.api_key}" } - end + def photos_sources + filtered_photos.map { _1[:source] }.uniq end private @@ -54,4 +44,32 @@ class Trip < ApplicationRecord self.distance = distance.round end + + def can_fetch_photos? + user.immich_integration_configured? || user.photoprism_integration_configured? + end + + def filtered_photos + return @filtered_photos if defined?(@filtered_photos) + + photos = Photos::Search.new( + user, + start_date: started_at.to_date.to_s, + end_date: ended_at.to_date.to_s + ).call + + @filtered_photos = select_dominant_orientation(photos) + end + + def select_dominant_orientation(photos) + vertical_photos = photos.select { |photo| photo[:orientation] == 'portrait' } + horizontal_photos = photos.select { |photo| photo[:orientation] == 'landscape' } + + vertical_photos.count > horizontal_photos.count ? vertical_photos : horizontal_photos + end + + def photo_thumbnail(asset) + { url: "/api/v1/photos/#{asset[:id]}/thumbnail.jpg?api_key=#{user.api_key}&source=#{asset[:source]}" } + end end + diff --git a/app/serializers/api/photo_serializer.rb b/app/serializers/api/photo_serializer.rb index 5e3ce9a5..c0a1119a 100644 --- a/app/serializers/api/photo_serializer.rb +++ b/app/serializers/api/photo_serializer.rb @@ -17,6 +17,7 @@ class Api::PhotoSerializer state: state, country: country, type: type, + orientation: orientation, source: source } end @@ -60,4 +61,13 @@ class Api::PhotoSerializer def type (photo['type'] || photo['Type']).downcase end + + def orientation + case source + when 'immich' + photo.dig('exifInfo', 'orientation') == '6' ? 'portrait' : 'landscape' + when 'photoprism' + photo['Portrait'] ? 'portrait' : 'landscape' + end + end end diff --git a/app/views/trips/show.html.erb b/app/views/trips/show.html.erb index 5cc00ce6..d0b265fc 100644 --- a/app/views/trips/show.html.erb +++ b/app/views/trips/show.html.erb @@ -52,9 +52,13 @@ <% end %> <% end %> -
- <%= link_to "More photos on Immich", immich_search_url(current_user.settings['immich_url'], @trip.started_at, @trip.ended_at), class: "btn btn-primary", target: '_blank' %> -
+ <% if @trip.photos_sources.any? %> +
+ <% @trip.photos_sources.each do |source| %> + <%= link_to "More photos on #{source}", photo_search_url(source, current_user.settings, @trip.started_at, @trip.ended_at), class: "btn btn-primary mt-2", target: '_blank' %> + <% end %> +
+ <% end %>