mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
Implement photos serializer
This commit is contained in:
parent
202396a93d
commit
be45af95fb
7 changed files with 96 additions and 26 deletions
|
|
@ -10,7 +10,14 @@ class Api::V1::PhotosController < ApiController
|
|||
end
|
||||
|
||||
def thumbnail
|
||||
response = Rails.cache.fetch("photo_thumbnail_#{params[:id]}", expires_in: 1.day) do
|
||||
response = fetch_cached_thumbnail
|
||||
handle_thumbnail_response(response)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_cached_thumbnail
|
||||
Rails.cache.fetch("photo_thumbnail_#{params[:id]}", expires_in: 1.day) do
|
||||
HTTParty.get(
|
||||
"#{current_api_user.settings['immich_url']}/api/assets/#{params[:id]}/thumbnail?size=preview",
|
||||
headers: {
|
||||
|
|
@ -19,14 +26,11 @@ class Api::V1::PhotosController < ApiController
|
|||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def handle_thumbnail_response(response)
|
||||
if response.success?
|
||||
send_data(
|
||||
response.body,
|
||||
type: 'image/jpeg',
|
||||
disposition: 'inline',
|
||||
status: :ok
|
||||
)
|
||||
send_data(response.body, type: 'image/jpeg', disposition: 'inline', status: :ok)
|
||||
else
|
||||
render json: { error: 'Failed to fetch thumbnail' }, status: response.code
|
||||
end
|
||||
|
|
|
|||
|
|
@ -137,10 +137,13 @@ export default class extends Controller {
|
|||
this.map.addControl(this.drawControl);
|
||||
}
|
||||
if (e.name === 'Photos') {
|
||||
if (!this.userSettings.immich_url || !this.userSettings.immich_api_key) {
|
||||
if (
|
||||
(!this.userSettings.immich_url || !this.userSettings.immich_api_key) &&
|
||||
(!this.userSettings.photoprism_url || !this.userSettings.photoprism_api_key)
|
||||
) {
|
||||
showFlashMessage(
|
||||
'error',
|
||||
'Immich integration is not configured. Please check your settings.'
|
||||
'Photos integration is not configured. Please check your integrations settings.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -836,7 +839,7 @@ export default class extends Controller {
|
|||
<h3 class="font-bold">${photo.originalFileName}</h3>
|
||||
<p>Taken: ${new Date(photo.localDateTime).toLocaleString()}</p>
|
||||
<p>Location: ${photo.exifInfo.city}, ${photo.exifInfo.state}, ${photo.exifInfo.country}</p>
|
||||
${photo.type === 'VIDEO' ? '🎥 Video' : '📷 Photo'}
|
||||
${photo.type === 'video' ? '🎥 Video' : '📷 Photo'}
|
||||
</div>
|
||||
`;
|
||||
marker.bindPopup(popupContent);
|
||||
|
|
|
|||
61
app/serializers/api/photo_serializer.rb
Normal file
61
app/serializers/api/photo_serializer.rb
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::PhotoSerializer
|
||||
def initialize(photo)
|
||||
@photo = photo
|
||||
end
|
||||
|
||||
def call
|
||||
{
|
||||
id: id,
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
localDateTime: local_date_time,
|
||||
originalFileName: original_file_name,
|
||||
city: city,
|
||||
state: state,
|
||||
country: country,
|
||||
type: type
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :photo
|
||||
|
||||
def id
|
||||
photo['id'] || photo['ID']
|
||||
end
|
||||
|
||||
def latitude
|
||||
photo.dig('exifInfo', 'latitude') || photo['Lat']
|
||||
end
|
||||
|
||||
def longitude
|
||||
photo.dig('exifInfo', 'longitude') || photo['Lng']
|
||||
end
|
||||
|
||||
def local_date_time
|
||||
photo['localDateTime'] || photo['TakenAtLocal']
|
||||
end
|
||||
|
||||
def original_file_name
|
||||
photo['originalFileName'] || photo['OriginalName']
|
||||
end
|
||||
|
||||
def city
|
||||
photo.dig('exifInfo', 'city') || photo['PlaceCity']
|
||||
end
|
||||
|
||||
def state
|
||||
photo.dig('exifInfo', 'state') || photo['PlaceState']
|
||||
end
|
||||
|
||||
def country
|
||||
photo.dig('exifInfo', 'country') || photo['PlaceCountry']
|
||||
end
|
||||
|
||||
def type
|
||||
(photo['type'] || photo['Type']).downcase
|
||||
end
|
||||
end
|
||||
|
|
@ -5,7 +5,7 @@ class Immich::RequestPhotos
|
|||
|
||||
def initialize(user, start_date: '1970-01-01', end_date: nil)
|
||||
@user = user
|
||||
@immich_api_base_url = "#{user.settings['immich_url']}/api/search/metadata"
|
||||
@immich_api_base_url = URI.parse("#{user.settings['immich_url']}/api/search/metadata")
|
||||
@immich_api_key = user.settings['immich_api_key']
|
||||
@start_date = start_date
|
||||
@end_date = end_date
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Photoprism::RequestPhotos
|
||||
class Error < StandardError; end
|
||||
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_base_url = URI.parse("#{user.settings['photoprism_url']}/api/v1/photos")
|
||||
@photoprism_api_key = user.settings['photoprism_api_key']
|
||||
@start_date = start_date
|
||||
@end_date = end_date
|
||||
|
|
@ -18,7 +17,9 @@ class Photoprism::RequestPhotos
|
|||
|
||||
data = retrieve_photoprism_data
|
||||
|
||||
time_framed_data(data)
|
||||
return [] if data[0]['error'].present?
|
||||
|
||||
time_framed_data(data, start_date, end_date)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -29,15 +30,14 @@ class Photoprism::RequestPhotos
|
|||
|
||||
while offset < 1_000_000
|
||||
response_data = fetch_page(offset)
|
||||
break unless response_data
|
||||
break if response_data.blank? || response_data[0]['error'].present?
|
||||
|
||||
data << response_data
|
||||
break if response_data.empty?
|
||||
|
||||
offset += 1000
|
||||
end
|
||||
|
||||
data
|
||||
data.flatten
|
||||
end
|
||||
|
||||
def fetch_page(offset)
|
||||
|
|
@ -47,7 +47,10 @@ class Photoprism::RequestPhotos
|
|||
query: request_params(offset)
|
||||
)
|
||||
|
||||
raise Error, "Photoprism API returned #{response.code}: #{response.body}" if response.code != 200
|
||||
if response.code != 200
|
||||
Rails.logger.info "Photoprism API returned #{response.code}: #{response.body}"
|
||||
Rails.logger.debug "Photoprism API request params: #{request_params(offset).inspect}"
|
||||
end
|
||||
|
||||
JSON.parse(response.body)
|
||||
end
|
||||
|
|
@ -71,12 +74,11 @@ class Photoprism::RequestPhotos
|
|||
public: true,
|
||||
quality: 3,
|
||||
after: start_date,
|
||||
count: 1000,
|
||||
photo: 'yes'
|
||||
count: 1000
|
||||
}
|
||||
end
|
||||
|
||||
def time_framed_data(data)
|
||||
def time_framed_data(data, start_date, end_date)
|
||||
data.flatten.select do |photo|
|
||||
taken_at = DateTime.parse(photo['TakenAtLocal'])
|
||||
end_date ||= Time.current
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class Photos::Request
|
|||
photos << request_immich if user.immich_integration_configured?
|
||||
photos << request_photoprism if user.photoprism_integration_configured?
|
||||
|
||||
photos
|
||||
photos.flatten.map { |photo| Api::PhotoSerializer.new(photo).call }
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -201,10 +201,10 @@ RSpec.describe Photoprism::RequestPhotos do
|
|||
.to_return(status: 401, body: 'Unauthorized')
|
||||
end
|
||||
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
service.call
|
||||
end.to raise_error(Photoprism::RequestPhotos::Error, 'Photoprism API returned 401: Unauthorized')
|
||||
it 'logs the error' do
|
||||
expect(Rails.logger).to receive(:error).with('Photoprism API returned 401: Unauthorized')
|
||||
|
||||
service.call
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue