diff --git a/.app_version b/.app_version index c25c8e5b..1a44cad7 100644 --- a/.app_version +++ b/.app_version @@ -1 +1 @@ -0.30.0 +0.30.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 89e12393..02ab8cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +# [0.30.1] - 2025-07-22 + +## Fixed + +- Points limit exceeded check is now cached. +- Reverse geocoding for places is now significantly faster. + +## Changed + +- Stats page should load faster now. +- Track creation is temporarily disabled. + # [0.30.0] - 2025-07-21 -⚠️ If you were using RC, please run the following commands in the console, otherwise read on. ⚠️ +⚠️ If you were using 0.29.2 RC, please run the following commands in the console, otherwise read on. ⚠️ ```ruby # This will delete all tracks 👇 diff --git a/Gemfile.lock b/Gemfile.lock index 640e815e..4b955b5a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -126,7 +126,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - chartkick (5.1.5) + chartkick (5.2.0) coderay (1.1.3) concurrent-ruby (1.3.5) connection_pool (2.5.3) @@ -144,7 +144,7 @@ GEM database_consistency (2.0.4) activerecord (>= 3.2) date (3.4.1) - debug (1.10.0) + debug (1.11.0) irb (~> 1.10) reline (>= 0.3.8) devise (4.9.4) @@ -160,7 +160,7 @@ GEM dotenv (= 3.1.8) railties (>= 6.1) drb (2.2.3) - erb (5.0.1) + erb (5.0.2) erubi (1.13.1) et-orbi (1.2.11) tzinfo @@ -194,7 +194,7 @@ GEM actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) - io-console (0.8.0) + io-console (0.8.1) irb (1.15.2) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -243,7 +243,7 @@ GEM multi_json (1.15.0) multi_xml (0.7.1) bigdecimal (~> 3.1) - net-imap (0.5.8) + net-imap (0.5.9) date net-protocol net-pop (0.1.2) @@ -253,23 +253,23 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) - nokogiri (1.18.8) + nokogiri (1.18.9) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.18.8-aarch64-linux-gnu) + nokogiri (1.18.9-aarch64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.8-arm-linux-gnu) + nokogiri (1.18.9-arm-linux-gnu) racc (~> 1.4) - nokogiri (1.18.8-arm64-darwin) + nokogiri (1.18.9-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-darwin) + nokogiri (1.18.9-x86_64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-linux-gnu) + nokogiri (1.18.9-x86_64-linux-gnu) racc (~> 1.4) oj (3.16.11) bigdecimal (>= 3.0) ostruct (>= 0.2) - optimist (3.2.0) + optimist (3.2.1) orm_adapter (0.5.0) ostruct (0.6.1) parallel (1.27.0) @@ -342,7 +342,7 @@ GEM zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.3.0) - rdoc (6.14.1) + rdoc (6.14.2) erb psych (>= 4.0.0) redis (5.4.0) @@ -350,7 +350,7 @@ GEM redis-client (0.24.0) connection_pool regexp_parser (2.10.0) - reline (0.6.1) + reline (0.6.2) io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) @@ -462,7 +462,7 @@ GEM stringio (3.1.7) strong_migrations (2.3.0) activerecord (>= 7) - super_diff (0.15.0) + super_diff (0.16.0) attr_extras (>= 6.2.4) diff-lcs patience_diff @@ -475,7 +475,7 @@ GEM tailwindcss-ruby (3.4.17-arm64-darwin) tailwindcss-ruby (3.4.17-x86_64-darwin) tailwindcss-ruby (3.4.17-x86_64-linux) - thor (1.3.2) + thor (1.4.0) timeout (0.4.3) turbo-rails (2.0.16) actionpack (>= 7.1.0) @@ -496,7 +496,7 @@ GEM hashdiff (>= 0.4.0, < 2.0.0) webrick (1.9.1) websocket (1.2.11) - websocket-driver (0.7.7) + websocket-driver (0.8.0) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index a456452f..0300deae 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -5,10 +5,9 @@ class StatsController < ApplicationController before_action :authenticate_active_user!, only: %i[update update_all] def index - @stats = current_user.stats.group_by(&:year).transform_values { |stats| stats.sort_by(&:updated_at).reverse }.sort.reverse - @points_total = current_user.tracked_points.count - @points_reverse_geocoded = current_user.total_reverse_geocoded_points - @points_reverse_geocoded_without_data = current_user.total_reverse_geocoded_points_without_data + @stats = build_stats + assign_points_statistics + @year_distances = precompute_year_distances end def show @@ -43,4 +42,30 @@ class StatsController < ApplicationController redirect_to stats_path, notice: 'Stats are being updated', status: :see_other end + + private + + def assign_points_statistics + points_stats = ::StatsQuery.new(current_user).points_stats + + @points_total = points_stats[:total] + @points_reverse_geocoded = points_stats[:geocoded] + @points_reverse_geocoded_without_data = points_stats[:without_data] + end + + def precompute_year_distances + year_distances = {} + + @stats.each do |year, _stats| + year_distances[year] = Stat.year_distance(year, current_user) + end + + year_distances + end + + def build_stats + current_user.stats.group_by(&:year).transform_values do |stats| + stats.sort_by(&:updated_at).reverse + end.sort.reverse + end end diff --git a/app/javascript/controllers/maps_controller.js b/app/javascript/controllers/maps_controller.js index a675c0e9..12092891 100644 --- a/app/javascript/controllers/maps_controller.js +++ b/app/javascript/controllers/maps_controller.js @@ -219,7 +219,7 @@ export default class extends BaseController { this.setupTracksSubscription(); // Handle routes/tracks mode selection - this.addRoutesTracksSelector(); + // this.addRoutesTracksSelector(); # Temporarily disabled this.switchRouteMode('routes', true); // Initialize layers based on settings diff --git a/app/jobs/tracks/create_job.rb b/app/jobs/tracks/create_job.rb index 919e5f82..a65805c4 100644 --- a/app/jobs/tracks/create_job.rb +++ b/app/jobs/tracks/create_job.rb @@ -27,6 +27,8 @@ class Tracks::CreateJob < ApplicationJob end def create_error_notification(user, error) + return unless DawarichSettings.self_hosted? + Notifications::Create.new( user: user, kind: :error, diff --git a/app/jobs/trips/calculate_all_job.rb b/app/jobs/trips/calculate_all_job.rb index 0500881c..3710df3e 100644 --- a/app/jobs/trips/calculate_all_job.rb +++ b/app/jobs/trips/calculate_all_job.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Trips::CalculateAllJob < ApplicationJob - queue_as :default + queue_as :trips def perform(trip_id, distance_unit = 'km') Trips::CalculatePathJob.perform_later(trip_id) diff --git a/app/jobs/trips/calculate_countries_job.rb b/app/jobs/trips/calculate_countries_job.rb index e63365d3..ed5ee884 100644 --- a/app/jobs/trips/calculate_countries_job.rb +++ b/app/jobs/trips/calculate_countries_job.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Trips::CalculateCountriesJob < ApplicationJob - queue_as :default + queue_as :trips def perform(trip_id, distance_unit) trip = Trip.find(trip_id) diff --git a/app/jobs/trips/calculate_distance_job.rb b/app/jobs/trips/calculate_distance_job.rb index 8a28e06f..15ff83c4 100644 --- a/app/jobs/trips/calculate_distance_job.rb +++ b/app/jobs/trips/calculate_distance_job.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Trips::CalculateDistanceJob < ApplicationJob - queue_as :default + queue_as :trips def perform(trip_id, distance_unit) trip = Trip.find(trip_id) diff --git a/app/jobs/trips/calculate_path_job.rb b/app/jobs/trips/calculate_path_job.rb index 711cfef8..f1323c5f 100644 --- a/app/jobs/trips/calculate_path_job.rb +++ b/app/jobs/trips/calculate_path_job.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Trips::CalculatePathJob < ApplicationJob - queue_as :default + queue_as :trips def perform(trip_id) trip = Trip.find(trip_id) diff --git a/app/models/country.rb b/app/models/country.rb index 9ef64687..e40a0c6d 100644 --- a/app/models/country.rb +++ b/app/models/country.rb @@ -12,6 +12,8 @@ class Country < ApplicationRecord end def self.names_to_iso_a2 - pluck(:name, :iso_a2).to_h + Rails.cache.fetch('countries_names_to_iso_a2', expires_in: 1.day) do + pluck(:name, :iso_a2).to_h + end end end diff --git a/app/models/point.rb b/app/models/point.rb index 75566be3..7be8524a 100644 --- a/app/models/point.rb +++ b/app/models/point.rb @@ -33,8 +33,8 @@ class Point < ApplicationRecord after_create :async_reverse_geocode, if: -> { DawarichSettings.store_geodata? && !reverse_geocoded? } after_create :set_country after_create_commit :broadcast_coordinates - after_create_commit :trigger_incremental_track_generation, if: -> { import_id.nil? } - after_commit :recalculate_track, on: :update, if: -> { track.present? } + # after_create_commit :trigger_incremental_track_generation, if: -> { import_id.nil? } + # after_commit :recalculate_track, on: :update, if: -> { track.present? } def self.without_raw_data select(column_names - ['raw_data']) diff --git a/app/queries/stats_query.rb b/app/queries/stats_query.rb new file mode 100644 index 00000000..0192a8c8 --- /dev/null +++ b/app/queries/stats_query.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +class StatsQuery + def initialize(user) + @user = user + end + + def points_stats + sql = ActiveRecord::Base.sanitize_sql_array([ + <<~SQL.squish, + SELECT + COUNT(id) as total, + COUNT(reverse_geocoded_at) as geocoded, + COUNT(CASE WHEN geodata = '{}'::jsonb THEN 1 END) as without_data + FROM points + WHERE user_id = ? + SQL + user.id + ]) + + result = Point.connection.select_one(sql) + + { + total: result['total'].to_i, + geocoded: result['geocoded'].to_i, + without_data: result['without_data'].to_i + } + end + + private + + attr_reader :user +end diff --git a/app/services/points_limit_exceeded.rb b/app/services/points_limit_exceeded.rb index f47543d1..2bf8de8a 100644 --- a/app/services/points_limit_exceeded.rb +++ b/app/services/points_limit_exceeded.rb @@ -7,13 +7,18 @@ class PointsLimitExceeded def call return false if DawarichSettings.self_hosted? - return true if @user.tracked_points.count >= points_limit - false + Rails.cache.fetch(cache_key, expires_in: 1.day) do + @user.tracked_points.count >= points_limit + end end private + def cache_key + "points_limit_exceeded/#{@user.id}" + end + def points_limit DawarichSettings::BASIC_PAID_PLAN_LIMIT end diff --git a/app/views/stats/_year.html.erb b/app/views/stats/_year.html.erb index 886e2c96..3d8989b8 100644 --- a/app/views/stats/_year.html.erb +++ b/app/views/stats/_year.html.erb @@ -4,7 +4,7 @@