2024-11-27 14:14:17 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
class Trip < ApplicationRecord
|
2024-11-28 09:29:17 -05:00
|
|
|
has_rich_text :notes
|
2024-11-28 06:00:54 -05:00
|
|
|
|
2024-11-27 14:14:17 -05:00
|
|
|
belongs_to :user
|
|
|
|
|
|
|
|
|
|
validates :name, :started_at, :ended_at, presence: true
|
2024-11-27 15:37:21 -05:00
|
|
|
|
2025-05-15 15:33:01 -04:00
|
|
|
after_create :enqueue_calculation_jobs
|
|
|
|
|
after_update :enqueue_calculation_jobs, if: -> { saved_change_to_started_at? || saved_change_to_ended_at? }
|
2024-11-28 09:29:17 -05:00
|
|
|
|
2025-05-13 13:43:02 -04:00
|
|
|
def calculate_trip_data
|
2025-01-29 05:43:02 -05:00
|
|
|
calculate_path
|
|
|
|
|
calculate_distance
|
2025-05-13 13:43:02 -04:00
|
|
|
calculate_countries
|
2025-01-24 06:01:54 -05:00
|
|
|
end
|
|
|
|
|
|
2025-05-15 15:33:01 -04:00
|
|
|
def enqueue_calculation_jobs
|
|
|
|
|
Trips::CalculateAllJob.perform_later(id)
|
|
|
|
|
end
|
|
|
|
|
|
2024-11-27 15:37:21 -05:00
|
|
|
def points
|
2024-11-28 09:29:17 -05:00
|
|
|
user.tracked_points.where(timestamp: started_at.to_i..ended_at.to_i).order(:timestamp)
|
2024-11-27 15:37:21 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def countries
|
2025-05-13 13:43:02 -04:00
|
|
|
return points.pluck(:country).uniq.compact if DawarichSettings.store_geodata?
|
|
|
|
|
|
|
|
|
|
visited_countries
|
2024-11-27 15:37:21 -05:00
|
|
|
end
|
2024-11-28 04:40:08 -05:00
|
|
|
|
2024-12-10 13:31:52 -05:00
|
|
|
def photo_previews
|
|
|
|
|
@photo_previews ||= select_dominant_orientation(photos).sample(12)
|
2024-12-10 12:49:37 -05:00
|
|
|
end
|
2024-11-28 04:40:08 -05:00
|
|
|
|
2024-12-10 13:31:52 -05:00
|
|
|
def photo_sources
|
|
|
|
|
@photo_sources ||= photos.map { _1[:source] }.uniq
|
2024-11-28 04:40:08 -05:00
|
|
|
end
|
2024-11-28 09:29:17 -05:00
|
|
|
|
2025-05-15 15:33:01 -04:00
|
|
|
# These methods are now public since they're called from jobs
|
2025-01-29 05:43:02 -05:00
|
|
|
def calculate_path
|
2025-02-22 16:37:21 -05:00
|
|
|
trip_path = Tracks::BuildPath.new(points.pluck(:lonlat)).call
|
2025-01-29 05:43:02 -05:00
|
|
|
|
|
|
|
|
self.path = trip_path
|
|
|
|
|
end
|
|
|
|
|
|
2024-11-28 09:29:17 -05:00
|
|
|
def calculate_distance
|
2025-02-21 18:02:13 -05:00
|
|
|
distance = Point.total_distance(points, DISTANCE_UNIT)
|
2024-11-28 09:29:17 -05:00
|
|
|
|
|
|
|
|
self.distance = distance.round
|
|
|
|
|
end
|
2025-05-13 13:43:02 -04:00
|
|
|
|
|
|
|
|
def calculate_countries
|
|
|
|
|
countries = Trips::Countries.new(self).call
|
|
|
|
|
|
|
|
|
|
self.visited_countries = countries
|
|
|
|
|
end
|
2025-05-15 15:33:01 -04:00
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
|
|
def photos
|
|
|
|
|
@photos ||= Trips::Photos.new(self, user).call
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def select_dominant_orientation(photos)
|
|
|
|
|
vertical_photos = photos.select { |photo| photo[:orientation] == 'portrait' }
|
|
|
|
|
horizontal_photos = photos.select { |photo| photo[:orientation] == 'landscape' }
|
|
|
|
|
|
|
|
|
|
# this is ridiculous, but I couldn't find my way around frontend
|
|
|
|
|
# to show all photos in the same height
|
|
|
|
|
vertical_photos.count > horizontal_photos.count ? vertical_photos : horizontal_photos
|
|
|
|
|
end
|
2024-11-27 14:14:17 -05:00
|
|
|
end
|