mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Add device support to geodata importers
This commit is contained in:
parent
a96517caf1
commit
a5e07def23
9 changed files with 44 additions and 53 deletions
|
|
@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
- Internal data structure for separate devices in a single user account.
|
||||
- [ ] Immich and Photoprism integrations should fill all possible fields in points table
|
||||
- Geodata from Immich and Photoprism now will also write `tracker_id` to the points table. This will allow to group points by device. It's a good idea to delete your existing imports from Photoprism and Immich and import them again. This will remove existing points and re-import them as long as photos are still available.
|
||||
- [ ] Add tracker_id index to points table
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ module PointValidation
|
|||
Point.where(
|
||||
lonlat: params[:lonlat],
|
||||
timestamp: params[:timestamp].to_i,
|
||||
tracker_id: params[:tracker_id],
|
||||
user_id:
|
||||
).exists?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ class Immich::ImportGeodata
|
|||
latitude: asset['exifInfo']['latitude'],
|
||||
longitude: asset['exifInfo']['longitude'],
|
||||
lonlat: "SRID=4326;POINT(#{asset['exifInfo']['longitude']} #{asset['exifInfo']['latitude']})",
|
||||
timestamp: Time.zone.parse(asset['exifInfo']['dateTimeOriginal']).to_i
|
||||
timestamp: Time.zone.parse(asset['exifInfo']['dateTimeOriginal']).to_i,
|
||||
tracker_id: asset['deviceId']
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ class Photoprism::ImportGeodata
|
|||
latitude: asset['Lat'],
|
||||
longitude: asset['Lng'],
|
||||
lonlat: "SRID=4326;POINT(#{asset['Lng']} #{asset['Lat']})",
|
||||
timestamp: Time.zone.parse(asset['TakenAt']).to_i
|
||||
timestamp: Time.zone.parse(asset['TakenAt']).to_i,
|
||||
tracker_id: "#{asset['CameraMake']} #{asset['CameraModel']}"
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class Photos::Importer
|
|||
|
||||
def create_point(point, index)
|
||||
return 0 unless valid?(point)
|
||||
return 0 if point_exists?(point, point['timestamp'])
|
||||
return 0 if point_exists?(point, user_id)
|
||||
|
||||
Point.create(
|
||||
lonlat: point['lonlat'],
|
||||
|
|
@ -28,6 +28,7 @@ class Photos::Importer
|
|||
timestamp: point['timestamp'].to_i,
|
||||
raw_data: point,
|
||||
import_id: import.id,
|
||||
tracker_id: point['tracker_id'],
|
||||
user_id:
|
||||
)
|
||||
|
||||
|
|
|
|||
2
spec/fixtures/files/immich/response.json
vendored
2
spec/fixtures/files/immich/response.json
vendored
|
|
@ -3,6 +3,7 @@
|
|||
{
|
||||
"assets": [
|
||||
{
|
||||
"deviceId": "MyString",
|
||||
"exifInfo": {
|
||||
"dateTimeOriginal": "2022-12-31T23:17:06.170Z",
|
||||
"latitude": 52.0000,
|
||||
|
|
@ -10,6 +11,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"deviceId": "MyString",
|
||||
"exifInfo": {
|
||||
"dateTimeOriginal": "2022-12-31T23:21:53.140Z",
|
||||
"latitude": 52.0000,
|
||||
|
|
|
|||
|
|
@ -104,56 +104,13 @@ RSpec.describe PointValidation do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with integration tests', :db do
|
||||
# These tests require a database with PostGIS support
|
||||
# Only run them if using real database integration
|
||||
|
||||
let(:existing_timestamp) { 1_650_000_000 }
|
||||
let(:existing_point_params) do
|
||||
{
|
||||
lonlat: 'POINT(10.5 50.5)',
|
||||
timestamp: existing_timestamp,
|
||||
user_id: user.id
|
||||
}
|
||||
context 'with point existing in device scope' do
|
||||
let(:existing_point) do
|
||||
create(:point, lonlat: 'POINT(10.5 50.5)', timestamp: Time.now.to_i, tracker_id: '123', user_id: user.id)
|
||||
end
|
||||
|
||||
before do
|
||||
# Skip this context if not in integration mode
|
||||
skip 'Skipping integration tests' unless ENV['RUN_INTEGRATION_TESTS']
|
||||
|
||||
# Create a point in the database
|
||||
existing_point = Point.create!(
|
||||
lonlat: "POINT(#{existing_point_params[:longitude]} #{existing_point_params[:latitude]})",
|
||||
timestamp: existing_timestamp,
|
||||
user_id: user.id
|
||||
)
|
||||
end
|
||||
|
||||
it 'returns true when a point with same coordinates and timestamp exists' do
|
||||
params = {
|
||||
lonlat: 'POINT(10.5 50.5)',
|
||||
timestamp: existing_timestamp
|
||||
}
|
||||
|
||||
expect(validator.point_exists?(params, user.id)).to be true
|
||||
end
|
||||
|
||||
it 'returns false when a point with different coordinates exists' do
|
||||
params = {
|
||||
lonlat: 'POINT(10.6 50.5)',
|
||||
timestamp: existing_timestamp
|
||||
}
|
||||
|
||||
expect(validator.point_exists?(params, user.id)).to be false
|
||||
end
|
||||
|
||||
it 'returns false when a point with different timestamp exists' do
|
||||
params = {
|
||||
lonlat: 'POINT(10.5 50.5)',
|
||||
timestamp: existing_timestamp + 1
|
||||
}
|
||||
|
||||
expect(validator.point_exists?(params, user.id)).to be false
|
||||
it 'returns true' do
|
||||
expect(validator.point_exists?(existing_point, user.id)).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,12 +4,22 @@ require 'rails_helper'
|
|||
|
||||
RSpec.describe 'Api::V1::Countries::Borders', type: :request do
|
||||
describe 'GET /index' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'returns a list of countries with borders' do
|
||||
get '/api/v1/countries/borders'
|
||||
get '/api/v1/countries/borders', headers: { 'Authorization' => "Bearer #{user.api_key}" }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.body).to include('AF')
|
||||
expect(response.body).to include('ZW')
|
||||
end
|
||||
|
||||
context 'when user is not authenticated' do
|
||||
it 'returns http unauthorized' do
|
||||
get '/api/v1/countries/borders'
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -45,12 +45,28 @@ RSpec.describe Photos::Importer do
|
|||
|
||||
context 'when there are points with the same coordinates' do
|
||||
let!(:existing_point) do
|
||||
create(:point, lonlat: 'POINT(30.0000 59.0000)', timestamp: 978_296_400, user:, device:)
|
||||
create(:point,
|
||||
lonlat: 'SRID=4326;POINT(30.0000 59.0000)',
|
||||
timestamp: 978_296_400,
|
||||
user: user,
|
||||
device: device,
|
||||
tracker_id: nil
|
||||
)
|
||||
end
|
||||
|
||||
it 'creates only new points' do
|
||||
expect { service }.to change { Point.count }.by(1)
|
||||
end
|
||||
|
||||
it 'does not create duplicate points' do
|
||||
service
|
||||
points = Point.where(
|
||||
lonlat: 'SRID=4326;POINT(30.0000 59.0000)',
|
||||
timestamp: 978_296_400,
|
||||
user_id: user.id
|
||||
)
|
||||
expect(points.count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue