mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-09 22:28:04 -05:00
73 lines
2.3 KiB
Ruby
73 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Tracks
|
|
module PointLoaders
|
|
class IncrementalLoader
|
|
attr_reader :user, :day, :redis_buffer
|
|
|
|
def initialize(user, day = nil)
|
|
@user = user
|
|
@day = day || Date.current
|
|
@redis_buffer = Tracks::RedisBuffer.new(user.id, @day)
|
|
end
|
|
|
|
def load_points
|
|
# Get buffered points from Redis
|
|
buffered_points = redis_buffer.retrieve
|
|
|
|
# Find the last track for this day to determine where to start
|
|
last_track = Track.last_for_day(user, day)
|
|
|
|
# Load new points since last track
|
|
new_points = load_new_points_since_last_track(last_track)
|
|
|
|
# Combine buffered points with new points
|
|
combined_points = merge_points(buffered_points, new_points)
|
|
|
|
Rails.logger.debug "Loaded #{buffered_points.size} buffered points and #{new_points.size} new points for user #{user.id}"
|
|
|
|
combined_points
|
|
end
|
|
|
|
private
|
|
|
|
def load_new_points_since_last_track(last_track)
|
|
scope = user.points
|
|
.where.not(lonlat: nil)
|
|
.where.not(timestamp: nil)
|
|
.where(track_id: nil) # Only process points not already assigned to tracks
|
|
|
|
if last_track
|
|
scope = scope.where('timestamp > ?', last_track.end_at.to_i)
|
|
else
|
|
# If no last track, load all points for the day
|
|
day_start = day.beginning_of_day.to_i
|
|
day_end = day.end_of_day.to_i
|
|
scope = scope.where('timestamp >= ? AND timestamp <= ?', day_start, day_end)
|
|
end
|
|
|
|
scope.order(:timestamp)
|
|
end
|
|
|
|
def merge_points(buffered_points, new_points)
|
|
# Convert buffered point hashes back to Point objects if needed
|
|
buffered_point_objects = buffered_points.map do |point_data|
|
|
# If it's already a Point object, use it directly
|
|
if point_data.is_a?(Point)
|
|
point_data
|
|
else
|
|
# Create a Point-like object from the hash
|
|
Point.new(point_data.except('id').symbolize_keys)
|
|
end
|
|
end
|
|
|
|
# Combine and sort by timestamp
|
|
all_points = (buffered_point_objects + new_points.to_a).sort_by(&:timestamp)
|
|
|
|
# Remove duplicates based on timestamp and coordinates
|
|
all_points.uniq { |point| [point.timestamp, point.lat, point.lon] }
|
|
end
|
|
end
|
|
end
|
|
end
|