mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-09 08:47:11 -05:00
116 lines
4 KiB
Ruby
116 lines
4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Track cleaning strategy for daily track processing.
|
|
#
|
|
# This cleaner handles tracks that overlap with the specified time window,
|
|
# ensuring proper handling of cross-day tracks and preventing orphaned points.
|
|
#
|
|
# How it works:
|
|
# 1. Finds tracks that overlap with the time window (not just those completely contained)
|
|
# 2. For overlapping tracks, removes only points within the time window
|
|
# 3. Deletes tracks that become empty after point removal
|
|
# 4. Preserves tracks that extend beyond the time window with their remaining points
|
|
#
|
|
# Key differences from ReplaceCleaner:
|
|
# - Handles tracks that span multiple days correctly
|
|
# - Uses overlap logic instead of containment logic
|
|
# - Preserves track portions outside the processing window
|
|
# - Prevents orphaned points from cross-day tracks
|
|
#
|
|
# Used primarily for:
|
|
# - Daily track processing that handles 24-hour windows
|
|
# - Incremental processing that respects existing cross-day tracks
|
|
# - Scenarios where tracks may span the processing boundary
|
|
#
|
|
# Example usage:
|
|
# cleaner = Tracks::Cleaners::DailyCleaner.new(user, start_at: 1.day.ago.beginning_of_day, end_at: 1.day.ago.end_of_day)
|
|
# cleaner.cleanup
|
|
#
|
|
module Tracks
|
|
module Cleaners
|
|
class DailyCleaner
|
|
attr_reader :user, :start_at, :end_at
|
|
|
|
def initialize(user, start_at: nil, end_at: nil)
|
|
@user = user
|
|
@start_at = start_at
|
|
@end_at = end_at
|
|
end
|
|
|
|
def cleanup
|
|
return unless start_at.present? && end_at.present?
|
|
|
|
overlapping_tracks = find_overlapping_tracks
|
|
|
|
return if overlapping_tracks.empty?
|
|
|
|
Rails.logger.info "Processing #{overlapping_tracks.count} overlapping tracks for user #{user.id} in time window #{start_at} to #{end_at}"
|
|
|
|
overlapping_tracks.each do |track|
|
|
process_overlapping_track(track)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def find_overlapping_tracks
|
|
# Find tracks that overlap with our time window
|
|
# A track overlaps if: track_start < window_end AND track_end > window_start
|
|
user.tracks.where(
|
|
'(start_at < ? AND end_at > ?)',
|
|
Time.zone.at(end_at),
|
|
Time.zone.at(start_at)
|
|
)
|
|
end
|
|
|
|
def process_overlapping_track(track)
|
|
# Find points within our time window that belong to this track
|
|
points_in_window = track.points.where(
|
|
'timestamp >= ? AND timestamp <= ?',
|
|
start_at.to_i,
|
|
end_at.to_i
|
|
)
|
|
|
|
if points_in_window.empty?
|
|
Rails.logger.debug "Track #{track.id} has no points in time window, skipping"
|
|
return
|
|
end
|
|
|
|
# Remove these points from the track
|
|
points_in_window.update_all(track_id: nil)
|
|
|
|
Rails.logger.debug "Removed #{points_in_window.count} points from track #{track.id}"
|
|
|
|
# Check if the track has any remaining points
|
|
remaining_points_count = track.points.count
|
|
|
|
if remaining_points_count == 0
|
|
# Track is now empty, delete it
|
|
Rails.logger.debug "Track #{track.id} is now empty, deleting"
|
|
track.destroy!
|
|
elsif remaining_points_count < 2
|
|
# Track has too few points to be valid, delete it and orphan remaining points
|
|
Rails.logger.debug "Track #{track.id} has insufficient points (#{remaining_points_count}), deleting"
|
|
track.points.update_all(track_id: nil)
|
|
track.destroy!
|
|
else
|
|
# Track still has valid points outside our window, update its boundaries
|
|
Rails.logger.debug "Track #{track.id} still has #{remaining_points_count} points, updating boundaries"
|
|
update_track_boundaries(track)
|
|
end
|
|
end
|
|
|
|
def update_track_boundaries(track)
|
|
remaining_points = track.points.order(:timestamp)
|
|
|
|
return if remaining_points.empty?
|
|
|
|
# Update track start/end times based on remaining points
|
|
track.update!(
|
|
start_at: Time.zone.at(remaining_points.first.timestamp),
|
|
end_at: Time.zone.at(remaining_points.last.timestamp)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|