Merge pull request #227 from Freika/chore/ruby-335

Update gems and ruby version
This commit is contained in:
Evgenii Burmakin 2024-09-05 22:41:25 +03:00 committed by GitHub
commit 40f2db3d24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 218 additions and 129 deletions

View file

@ -1 +1 @@
0.13.0
0.13.1

View file

@ -1,16 +1,16 @@
version: 2.1
orbs:
ruby: circleci/ruby@2.1.1
browser-tools: circleci/browser-tools@1.2.3
ruby: circleci/ruby@2.1.4
browser-tools: circleci/browser-tools@1.4.8
jobs:
test:
docker:
- image: cimg/ruby:3.2.3
- image: cimg/ruby:3.3
environment:
RAILS_ENV: test
- image: circleci/postgres:13.3
- image: cimg/postgres:13.3
environment:
POSTGRES_USER: postgres
POSTGRES_DB: test_database

View file

@ -35,7 +35,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2.3'
ruby-version: '3.3.4'
bundler-cache: true
- name: Set up Node.js

View file

@ -1 +1 @@
3.2.3
3.3.4

View file

@ -5,8 +5,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.13.1] — 2024-09-05
### Added
- `GET /api/v1/health` endpoint to check the health of the application with swagger docs
### Changed
- Ruby version updated to 3.3.4
- Visits suggestion process now will try to merge consecutive visits to the same place into one visit.
## [0.13.0] — 2024-09-03
The GPX and GeoJSON export release
⚠️ BREAKING CHANGES: ⚠️
Default exporting format is now GeoJSON instead of Owntracks-like JSON. This will allow you to use the exported data in other applications that support GeoJSON format. It's also important to highlight, that GeoJSON format does not describe a way to store any time-related data. Dawarich relies on the `timestamp` field in the GeoJSON format to determine the time of the point. The value of the `timestamp` field should be a Unix timestamp in seconds. If you import GeoJSON data that does not have a `timestamp` field, the point will not be imported.

View file

@ -1,4 +1,4 @@
FROM ruby:3.2.3-alpine
FROM ruby:3.3.5-alpine
ENV APP_PATH /var/app
ENV BUNDLE_VERSION 2.5.9

View file

@ -1,4 +1,4 @@
FROM ruby:3.2.3-alpine
FROM ruby:3.3.4-alpine
ENV APP_PATH /var/app
ENV BUNDLE_VERSION 2.5.9

View file

@ -3,7 +3,8 @@
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.2.3'
ruby File.read('.ruby-version').strip
gem 'bootsnap', require: false
gem 'chartkick'
gem 'data_migrate'

View file

@ -1,80 +1,76 @@
GEM
remote: https://rubygems.org/
specs:
actioncable (7.1.3.4)
actionpack (= 7.1.3.4)
activesupport (= 7.1.3.4)
actioncable (7.2.1)
actionpack (= 7.2.1)
activesupport (= 7.2.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.1.3.4)
actionpack (= 7.1.3.4)
activejob (= 7.1.3.4)
activerecord (= 7.1.3.4)
activestorage (= 7.1.3.4)
activesupport (= 7.1.3.4)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.1.3.4)
actionpack (= 7.1.3.4)
actionview (= 7.1.3.4)
activejob (= 7.1.3.4)
activesupport (= 7.1.3.4)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
actionmailbox (7.2.1)
actionpack (= 7.2.1)
activejob (= 7.2.1)
activerecord (= 7.2.1)
activestorage (= 7.2.1)
activesupport (= 7.2.1)
mail (>= 2.8.0)
actionmailer (7.2.1)
actionpack (= 7.2.1)
actionview (= 7.2.1)
activejob (= 7.2.1)
activesupport (= 7.2.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.1.3.4)
actionview (= 7.1.3.4)
activesupport (= 7.1.3.4)
actionpack (7.2.1)
actionview (= 7.2.1)
activesupport (= 7.2.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
rack (>= 2.2.4, < 3.2)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.3.4)
actionpack (= 7.1.3.4)
activerecord (= 7.1.3.4)
activestorage (= 7.1.3.4)
activesupport (= 7.1.3.4)
useragent (~> 0.16)
actiontext (7.2.1)
actionpack (= 7.2.1)
activerecord (= 7.2.1)
activestorage (= 7.2.1)
activesupport (= 7.2.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.1.3.4)
activesupport (= 7.1.3.4)
actionview (7.2.1)
activesupport (= 7.2.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.1.3.4)
activesupport (= 7.1.3.4)
activejob (7.2.1)
activesupport (= 7.2.1)
globalid (>= 0.3.6)
activemodel (7.1.3.4)
activesupport (= 7.1.3.4)
activerecord (7.1.3.4)
activemodel (= 7.1.3.4)
activesupport (= 7.1.3.4)
activemodel (7.2.1)
activesupport (= 7.2.1)
activerecord (7.2.1)
activemodel (= 7.2.1)
activesupport (= 7.2.1)
timeout (>= 0.4.0)
activestorage (7.1.3.4)
actionpack (= 7.1.3.4)
activejob (= 7.1.3.4)
activerecord (= 7.1.3.4)
activesupport (= 7.1.3.4)
activestorage (7.2.1)
actionpack (= 7.2.1)
activejob (= 7.2.1)
activerecord (= 7.2.1)
activesupport (= 7.2.1)
marcel (~> 1.0)
activesupport (7.1.3.4)
activesupport (7.2.1)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
ast (2.4.2)
@ -96,7 +92,7 @@ GEM
rexml
crass (1.0.6)
csv (3.3.0)
data_migrate (9.4.2)
data_migrate (11.0.0)
activerecord (>= 6.1)
railties (>= 6.1)
date (3.3.4)
@ -110,7 +106,7 @@ GEM
responders
warden (~> 1.2.3)
diff-lcs (1.5.1)
docile (1.4.0)
docile (1.4.1)
dotenv (3.1.2)
dotenv-rails (3.1.2)
dotenv (= 3.1.2)
@ -129,18 +125,18 @@ GEM
fakeredis (0.1.4)
ffaker (2.23.0)
foreman (0.88.1)
fugit (1.10.1)
et-orbi (~> 1, >= 1.2.7)
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
geocoder (1.8.3)
base64 (>= 0.1.0)
csv (>= 3.0.0)
globalid (1.2.1)
activesupport (>= 6.1)
gpx (1.1.1)
gpx (1.2.0)
nokogiri (~> 1.7)
rake
hashdiff (1.1.0)
hashdiff (1.1.1)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
@ -171,7 +167,7 @@ GEM
kaminari-core (= 1.2.2)
kaminari-core (1.2.2)
language_server-protocol (3.17.0.3)
logger (1.6.0)
logger (1.6.1)
lograge (0.14.0)
actionpack (>= 4)
activesupport (>= 4)
@ -192,8 +188,7 @@ GEM
msgpack (1.7.2)
multi_xml (0.7.1)
bigdecimal (~> 3.1)
mutex_m (0.2.0)
net-imap (0.4.12)
net-imap (0.4.16)
date
net-protocol
net-pop (0.1.2)
@ -221,8 +216,8 @@ GEM
optimist (3.1.0)
orm_adapter (0.5.0)
ostruct (0.6.0)
parallel (1.25.1)
parser (3.3.3.0)
parallel (1.26.3)
parser (3.3.5.0)
ast (~> 2.4.1)
racc
patience_diff (1.2.0)
@ -253,20 +248,20 @@ GEM
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
rails (7.1.3.4)
actioncable (= 7.1.3.4)
actionmailbox (= 7.1.3.4)
actionmailer (= 7.1.3.4)
actionpack (= 7.1.3.4)
actiontext (= 7.1.3.4)
actionview (= 7.1.3.4)
activejob (= 7.1.3.4)
activemodel (= 7.1.3.4)
activerecord (= 7.1.3.4)
activestorage (= 7.1.3.4)
activesupport (= 7.1.3.4)
rails (7.2.1)
actioncable (= 7.2.1)
actionmailbox (= 7.2.1)
actionmailer (= 7.2.1)
actionpack (= 7.2.1)
actiontext (= 7.2.1)
actionview (= 7.2.1)
activejob (= 7.2.1)
activemodel (= 7.2.1)
activerecord (= 7.2.1)
activestorage (= 7.2.1)
activesupport (= 7.2.1)
bundler (>= 1.15.0)
railties (= 7.1.3.4)
railties (= 7.2.1)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
@ -274,10 +269,10 @@ GEM
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.1.3.4)
actionpack (= 7.1.3.4)
activesupport (= 7.1.3.4)
irb
railties (7.2.1)
actionpack (= 7.2.1)
activesupport (= 7.2.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
@ -286,32 +281,31 @@ GEM
rake (13.2.1)
rdoc (6.7.0)
psych (>= 4.0.0)
redis (5.2.0)
redis (5.3.0)
redis-client (>= 0.22.0)
redis-client (0.22.2)
connection_pool
regexp_parser (2.9.2)
reline (0.5.9)
reline (0.5.10)
io-console (~> 0.5)
request_store (1.7.0)
rack (>= 1.4)
responders (3.1.1)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.3.1)
strscan
rspec-core (3.13.0)
rexml (3.3.7)
rspec-core (3.13.1)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.1)
rspec-expectations (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (6.1.4)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-rails (7.0.1)
actionpack (>= 7.0)
activesupport (>= 7.0)
railties (>= 7.0)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
@ -328,31 +322,31 @@ GEM
rswag-ui (2.14.0)
actionpack (>= 5.2, < 8.0)
railties (>= 5.2, < 8.0)
rubocop (1.64.1)
rubocop (1.66.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
regexp_parser (>= 2.4, < 3.0)
rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
rubocop-ast (1.32.3)
parser (>= 3.3.1.0)
rubocop-rails (2.25.1)
rubocop-rails (2.26.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (1.13.0)
shoulda-matchers (6.3.0)
securerandom (0.3.1)
shoulda-matchers (6.4.0)
activesupport (>= 5.2.0)
shrine (3.6.0)
content_disposition (~> 1.0)
down (~> 5.1)
sidekiq (7.3.1)
sidekiq (7.3.2)
concurrent-ruby (< 2)
connection_pool (>= 2.3.0)
logger
@ -378,7 +372,6 @@ GEM
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.1)
strscan (3.1.0)
super_diff (0.12.1)
attr_extras (>= 6.2.4)
diff-lcs
@ -404,6 +397,7 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
useragent (0.16.10)
warden (1.2.9)
rack (>= 2.0.9)
webmock (3.23.1)
@ -468,7 +462,7 @@ DEPENDENCIES
webmock
RUBY VERSION
ruby 3.2.3p157
ruby 3.3.4p94
BUNDLED WITH
2.5.9

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Api::V1::HealthController < ApiController
skip_before_action :authenticate_api_key
def index
render json: { status: 'ok' }
end
end

View file

@ -2,12 +2,13 @@ import { Controller } from "@hotwired/stimulus"
import L, { latLng } from "leaflet";
import { osmMapLayer } from "../maps/layers";
// Connects to data-controller="visit-modal-map"
// This controller is used to display a map of all coordinates for a visit
// on the "Map" modal of a visit on the Visits page
export default class extends Controller {
static targets = ["container"];
connect() {
console.log("Visits maps controller connected");
this.coordinates = JSON.parse(this.element.dataset.coordinates);
this.center = JSON.parse(this.element.dataset.center);
this.radius = this.element.dataset.radius;

View file

@ -1,7 +1,6 @@
// app/javascript/controllers/visit_name_controller.js
import { Controller } from "@hotwired/stimulus";
// This controller is used to handle the updating of visit names on the Visits page
export default class extends Controller {
static targets = ["name", "input"];

View file

@ -3,7 +3,7 @@
class Export < ApplicationRecord
belongs_to :user
enum status: { created: 0, processing: 1, completed: 2, failed: 3 }
enum :status, { created: 0, processing: 1, completed: 2, failed: 3 }
validates :name, presence: true

View file

@ -8,7 +8,7 @@ class Import < ApplicationRecord
include ImportUploader::Attachment(:raw)
enum source: {
enum :source, {
google_semantic_history: 0, owntracks: 1, google_records: 2,
google_phone_takeout: 3, gpx: 4, immich_api: 5, geojson: 6
}

View file

@ -5,7 +5,7 @@ class Notification < ApplicationRecord
validates :title, :content, :kind, presence: true
enum kind: { info: 0, warning: 1, error: 2 }
enum :kind, { info: 0, warning: 1, error: 2 }
scope :unread, -> { where(read_at: nil) }
end

View file

@ -10,7 +10,7 @@ class Place < ApplicationRecord
has_many :place_visits, dependent: :destroy
has_many :suggested_visits, through: :place_visits, source: :visit
enum source: { manual: 0, photon: 1 }
enum :source, { manual: 0, photon: 1 }
def async_reverse_geocode
return unless REVERSE_GEOCODING_ENABLED

View file

@ -9,13 +9,13 @@ class Point < ApplicationRecord
validates :latitude, :longitude, :timestamp, presence: true
enum battery_status: { unknown: 0, unplugged: 1, charging: 2, full: 3 }, _suffix: true
enum trigger: {
enum :battery_status, { unknown: 0, unplugged: 1, charging: 2, full: 3 }, suffix: true
enum :trigger, {
unknown: 0, background_event: 1, circular_region_event: 2, beacon_event: 3,
report_location_message_event: 4, manual_event: 5, timer_based_event: 6,
settings_monitoring_event: 7
}, _suffix: true
enum connection: { mobile: 0, wifi: 1, offline: 2, unknown: 4 }, _suffix: true
}, suffix: true
enum :connection, { mobile: 0, wifi: 1, offline: 2, unknown: 4 }, suffix: true
scope :reverse_geocoded, -> { where.not(geodata: {}) }
scope :not_reverse_geocoded, -> { where(geodata: {}) }

View file

@ -10,7 +10,11 @@ class Visit < ApplicationRecord
validates :started_at, :ended_at, :duration, :name, :status, presence: true
enum status: { suggested: 0, confirmed: 1, declined: 2 }
enum :status, { suggested: 0, confirmed: 1, declined: 2 }
def reverse_geocoded?
place.geodata.present?
end
def coordinates
points.pluck(:latitude, :longitude).map { [_1[0].to_f, _1[1].to_f] }

View file

@ -16,6 +16,34 @@ class Visits::Prepare
grouped_points = Visits::GroupPoints.new(day_points).group_points_by_radius
day_result = prepare_day_result(grouped_points)
# Iterate through the day_result, check if there are any points outside of visits that are between two consecutive visits. If there are none, merge the visits.
day_result.each_cons(2) do |visit1, visit2|
next if visit1[:points].last == visit2[:points].first
points_between_visits = day_points.select do |point|
point.timestamp > visit1[:points].last.timestamp &&
point.timestamp < visit2[:points].first.timestamp
end
if points_between_visits.any?
# If there are points between the visits, we need to check if they are close enough to the visits to be considered part of them.
points_between_visits.each do |point|
next unless visit1[:points].last.distance_to(point) < visit1[:radius] ||
visit2[:points].first.distance_to(point) < visit2[:radius] ||
(point.timestamp - visit1[:points].last.timestamp).to_i < 600
visit1[:points] << point
end
end
visit1[:points] += visit2[:points]
visit1[:duration] = (visit1[:points].last.timestamp - visit1[:points].first.timestamp).to_i / 60
visit1[:ended_at] = Time.zone.at(visit1[:points].last.timestamp)
day_result.delete(visit2)
end
next if day_result.blank?
{ date: day, visits: day_result }
@ -41,7 +69,9 @@ class Visits::Prepare
longitude: center_point.longitude,
radius: calculate_radius(center_point, group),
points: group,
duration: (group.last.timestamp - group.first.timestamp).to_i / 60
duration: (group.last.timestamp - group.first.timestamp).to_i / 60,
started_at: Time.zone.at(group.first.timestamp).to_s,
ended_at: Time.zone.at(group.last.timestamp).to_s
}
end
end

View file

@ -56,6 +56,7 @@ Rails.application.routes.draw do
namespace :api do
namespace :v1 do
get 'health', to: 'health#index'
patch 'settings', to: 'settings#update'
get 'settings', to: 'settings#index'

3
db/schema.rb generated
View file

@ -53,9 +53,6 @@ ActiveRecord::Schema[7.1].define(version: 2024_08_22_092405) do
t.index ["user_id"], name: "index_areas_on_user_id"
end
create_table "data_migrations", primary_key: "version", id: :string, force: :cascade do |t|
end
create_table "exports", force: :cascade do |t|
t.string "name", null: false
t.string "url"

View file

@ -1,4 +1,3 @@
version: '3'
networks:
dawarich:
services:

View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Api::V1::Healths', type: :request do
describe 'GET /index' do
context 'when user is not authenticated' do
it 'returns http success' do
get '/api/v1/health'
expect(response).to have_http_status(:success)
end
end
end
end

View file

@ -36,7 +36,9 @@ RSpec.describe Visits::Prepare do
longitude: 0.0,
radius: 10,
points:,
duration: 105
duration: 105,
started_at: 1.day.ago.to_s,
ended_at: (1.day.ago + 105.minutes).to_s
}
]
}

View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'swagger_helper'
describe 'Health API', type: :request do
path '/api/v1/health' do
get 'Retrieves application status' do
tags 'Health'
produces 'application/json'
response '200', 'Healthy' do
run_test!
end
end
end
end

View file

@ -106,6 +106,14 @@ paths:
responses:
'200':
description: area deleted
"/api/v1/health":
get:
summary: Retrieves application status
tags:
- Health
responses:
'200':
description: areas found
"/api/v1/overland/batches":
post:
summary: Creates a batch of points