mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Implement support for OwnTracks REC files
This commit is contained in:
parent
fb2468ab3d
commit
a2f3aef608
11 changed files with 64 additions and 330 deletions
File diff suppressed because one or more lines are too long
|
|
@ -30,7 +30,12 @@ class ImportsController < ApplicationController
|
|||
|
||||
file = File.read(file)
|
||||
|
||||
raw_data = params[:import][:source] == 'gpx' ? Hash.from_xml(file) : JSON.parse(file)
|
||||
raw_data =
|
||||
case params[:import][:source]
|
||||
when 'gpx' then Hash.from_xml(file)
|
||||
when 'owntracks' then file
|
||||
else JSON.parse(file)
|
||||
end
|
||||
|
||||
import.update(raw_data:)
|
||||
import.id
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class OwnTracks::ExportParser
|
||||
attr_reader :import, :json, :user_id
|
||||
attr_reader :import, :data, :user_id
|
||||
|
||||
def initialize(import, user_id)
|
||||
@import = import
|
||||
@json = import.raw_data
|
||||
@data = import.raw_data
|
||||
@user_id = user_id
|
||||
end
|
||||
|
||||
def call
|
||||
points_data = parse_json
|
||||
points_data = parse_data
|
||||
|
||||
points_data.each do |point_data|
|
||||
next if Point.exists?(
|
||||
|
|
@ -31,15 +31,11 @@ class OwnTracks::ExportParser
|
|||
|
||||
private
|
||||
|
||||
def parse_json
|
||||
points = []
|
||||
|
||||
json.each_key do |user|
|
||||
json[user].each_key do |devise|
|
||||
json[user][devise].each { |point| points << OwnTracks::Params.new(point).call }
|
||||
end
|
||||
def parse_data
|
||||
data.split("\n").map do |line|
|
||||
OwnTracks::Params.new(
|
||||
JSON.parse(line.split("\t* \t")[1])
|
||||
).call
|
||||
end
|
||||
|
||||
points
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<%= form.radio_button :source, :owntracks, class: "radio radio-primary" %>
|
||||
<span class="label-text">Owntracks</span>
|
||||
</label>
|
||||
<p class="text-sm mt-2">A JSON file you exported by pressing Download button in top right corner of OwnTracks web interface</p>
|
||||
<p class="text-sm mt-2">A .REC file you could find in your volumes/owntracks-recorder/store/rec/USER/TOPIC directory</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bordered shadow-lg p-3 hover:shadow-blue-500/50">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ FactoryBot.define do
|
|||
factory :import do
|
||||
user
|
||||
name { 'APRIL_2013.json' }
|
||||
source { 1 }
|
||||
raw_data { JSON.parse(File.read('spec/fixtures/files/owntracks/export.json')) }
|
||||
source { Import.sources[:owntracks] }
|
||||
raw_data { File.read('spec/fixtures/files/owntracks/2024-03.rec') }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
10
spec/fixtures/files/owntracks/2024-03.rec
vendored
Normal file
10
spec/fixtures/files/owntracks/2024-03.rec
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
2024-03-01T09:03:09Z * {"bs":2,"p":100.266,"batt":94,"_type":"location","tid":"RO","topic":"owntracks/test/iPhone 12 Pro","alt":36,"lon":13.332,"vel":0,"t":"p","BSSID":"b0:f2:8:45:94:33","SSID":"Home Wifi","conn":"w","vac":4,"acc":10,"tst":1709283789,"lat":52.225,"m":1,"inrids":["5f1d1b"],"inregions":["home"],"_http":true}
|
||||
2024-03-01T17:46:02Z * {"bs":1,"p":100.28,"batt":94,"_type":"location","tid":"RO","topic":"owntracks/test/iPhone 12 Pro","alt":36,"lon":13.333,"t":"p","vel":0,"BSSID":"b0:f2:8:45:94:33","conn":"w","SSID":"Home Wifi","vac":3,"cog":98,"acc":9,"tst":1709315162,"lat":52.226,"m":1,"inrids":["5f1d1b"],"inregions":["home"],"_http":true}
|
||||
2024-03-01T18:26:55Z * {"lon":13.334,"acc":5,"wtst":1696359532,"event":"leave","rid":"5f1d1b","desc":"home","topic":"owntracks/test/iPhone 12 Pro/event","lat":52.227,"t":"c","tst":1709317615,"tid":"RO","_type":"transition","_http":true}
|
||||
2024-03-01T18:26:55Z * {"cog":40,"batt":85,"lon":13.335,"acc":5,"bs":1,"p":100.279,"vel":3,"vac":3,"lat":52.228,"topic":"owntracks/test/iPhone 12 Pro","t":"c","conn":"m","m":1,"tst":1709317615,"alt":36,"_type":"location","tid":"RO","_http":true}
|
||||
2024-03-01T18:28:30Z * {"cog":38,"batt":85,"lon":13.336,"acc":5,"bs":1,"p":100.349,"vel":3,"vac":3,"lat":52.229,"topic":"owntracks/test/iPhone 12 Pro","t":"v","conn":"m","m":1,"tst":1709317710,"alt":35,"_type":"location","tid":"RO","_http":true}
|
||||
2024-03-01T18:33:03Z * {"cog":18,"batt":85,"lon":13.337,"acc":5,"bs":1,"p":100.347,"vel":4,"vac":3,"lat":52.230,"topic":"owntracks/test/iPhone 12 Pro","conn":"m","m":1,"tst":1709317983,"alt":36,"_type":"location","tid":"RO","_http":true}
|
||||
2024-03-01T18:40:11Z * {"cog":43,"batt":85,"lon":13.338,"acc":5,"bs":1,"p":100.348,"vel":6,"vac":3,"lat":52.231,"topic":"owntracks/test/iPhone 12 Pro","conn":"m","m":1,"tst":1709318411,"alt":37,"_type":"location","tid":"RO","_http":true}
|
||||
2024-03-01T18:42:57Z * {"cog":320,"batt":85,"lon":13.339,"acc":5,"bs":1,"p":100.353,"vel":3,"vac":3,"lat":52.232,"topic":"owntracks/test/iPhone 12 Pro","t":"v","conn":"m","m":1,"tst":1709318577,"alt":37,"_type":"location","tid":"RO","_http":true}
|
||||
2024-03-01T18:40:11Z * {"cog":43,"batt":85,"lon":13.338,"acc":5,"bs":1,"p":100.348,"vel":6,"vac":3,"lat":52.231,"topic":"owntracks/test/iPhone 12 Pro","conn":"m","m":1,"tst":1709318411,"alt":37,"_type":"location","tid":"RO","_http":true}
|
||||
2024-03-01T18:40:11Z * {"cog":43,"batt":85,"lon":13.341,"acc":5,"bs":1,"p":100.348,"created_at":1709318940,"vel":6,"vac":3,"lat":52.234,"topic":"owntracks/test/iPhone 12 Pro","conn":"m","m":1,"tst":1709318411,"alt":37,"_type":"location","tid":"RO","_http":true}
|
||||
275
spec/fixtures/files/owntracks/export.json
vendored
275
spec/fixtures/files/owntracks/export.json
vendored
|
|
@ -1,275 +0,0 @@
|
|||
{
|
||||
"test": {
|
||||
"iphone-12-pro": [
|
||||
{
|
||||
"batt": 85,
|
||||
"lon": -74.0060,
|
||||
"acc": 8,
|
||||
"bs": 2,
|
||||
"inrids": [
|
||||
"5f1d1b"
|
||||
],
|
||||
"BSSID": "b0:f2:8:45:94:33",
|
||||
"SSID": "Home Wifi",
|
||||
"vac": 3,
|
||||
"inregions": [
|
||||
"home"
|
||||
],
|
||||
"lat": 40.7128,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "p",
|
||||
"conn": "w",
|
||||
"m": 1,
|
||||
"tst": 1706965203,
|
||||
"alt": 41,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d773",
|
||||
"isorcv": "2024-02-03T13:00:03Z",
|
||||
"isotst": "2024-02-03T13:00:03Z",
|
||||
"disptst": "2024-02-03 13:00:03"
|
||||
},
|
||||
{
|
||||
"batt": 89,
|
||||
"lon": -0.1278,
|
||||
"acc": 8,
|
||||
"bs": 1,
|
||||
"inrids": [
|
||||
"5f1d1b"
|
||||
],
|
||||
"p": 101.233,
|
||||
"BSSID": "b0:f2:8:45:94:33",
|
||||
"SSID": "Home Wifi",
|
||||
"vac": 15,
|
||||
"inregions": [
|
||||
"home"
|
||||
],
|
||||
"lat": 51.5074,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "p",
|
||||
"conn": "w",
|
||||
"m": 1,
|
||||
"tst": 1706967037,
|
||||
"alt": 36,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d773",
|
||||
"isorcv": "2024-02-03T13:30:37Z",
|
||||
"isotst": "2024-02-03T13:30:37Z",
|
||||
"disptst": "2024-02-03 13:30:37"
|
||||
},
|
||||
{
|
||||
"cog": 11,
|
||||
"batt": 94,
|
||||
"lon": 139.6917,
|
||||
"acc": 5,
|
||||
"bs": 1,
|
||||
"p": 101.318,
|
||||
"vel": 3,
|
||||
"vac": 3,
|
||||
"lat": 35.6895,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "v",
|
||||
"conn": "m",
|
||||
"m": 1,
|
||||
"tst": 1706971835,
|
||||
"alt": 35,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d77d",
|
||||
"isorcv": "2024-02-03T14:50:35Z",
|
||||
"isotst": "2024-02-03T14:50:35Z",
|
||||
"disptst": "2024-02-03 14:50:35"
|
||||
},
|
||||
{
|
||||
"cog": 11,
|
||||
"batt": 94,
|
||||
"lon": 151.2093,
|
||||
"acc": 5,
|
||||
"bs": 1,
|
||||
"p": 101.318,
|
||||
"vel": 3,
|
||||
"vac": 3,
|
||||
"lat": -33.8688,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "c",
|
||||
"conn": "m",
|
||||
"m": 1,
|
||||
"tst": 1706971835,
|
||||
"alt": 35,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d77d",
|
||||
"isorcv": "2024-02-03T14:50:35Z",
|
||||
"isotst": "2024-02-03T14:50:35Z",
|
||||
"disptst": "2024-02-03 14:50:35"
|
||||
},
|
||||
{
|
||||
"cog": 47,
|
||||
"batt": 94,
|
||||
"lon": 2.3522,
|
||||
"acc": 4,
|
||||
"bs": 1,
|
||||
"inrids": [
|
||||
"5f1d1b"
|
||||
],
|
||||
"p": 101.326,
|
||||
"vel": 4,
|
||||
"vac": 4,
|
||||
"inregions": [
|
||||
"home"
|
||||
],
|
||||
"lat": 48.8566,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "v",
|
||||
"conn": "m",
|
||||
"m": 1,
|
||||
"tst": 1706974182,
|
||||
"alt": 42,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d773",
|
||||
"isorcv": "2024-02-03T15:29:42Z",
|
||||
"isotst": "2024-02-03T15:29:42Z",
|
||||
"disptst": "2024-02-03 15:29:42"
|
||||
},
|
||||
{
|
||||
"batt": 94,
|
||||
"lon": -43.1729,
|
||||
"acc": 8,
|
||||
"bs": 1,
|
||||
"inrids": [
|
||||
"5f1d1b"
|
||||
],
|
||||
"p": 101.253,
|
||||
"BSSID": "b0:f2:8:45:94:33",
|
||||
"SSID": "Home Wifi",
|
||||
"vac": 11,
|
||||
"inregions": [
|
||||
"home"
|
||||
],
|
||||
"lat": -22.9068,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "p",
|
||||
"conn": "w",
|
||||
"m": 1,
|
||||
"tst": 1706974302,
|
||||
"alt": 37,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d773",
|
||||
"isorcv": "2024-02-03T15:31:42Z",
|
||||
"isotst": "2024-02-03T15:31:42Z",
|
||||
"disptst": "2024-02-03 15:31:42"
|
||||
},
|
||||
{
|
||||
"batt": 94,
|
||||
"lon": -43.1729,
|
||||
"acc": 8,
|
||||
"bs": 1,
|
||||
"inrids": [
|
||||
"5f1d1b"
|
||||
],
|
||||
"p": 101.256,
|
||||
"BSSID": "b0:f2:8:45:94:33",
|
||||
"SSID": "Home Wifi",
|
||||
"vac": 17,
|
||||
"inregions": [
|
||||
"home"
|
||||
],
|
||||
"lat": -22.9068,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "p",
|
||||
"conn": "w",
|
||||
"m": 1,
|
||||
"tst": 1706977057,
|
||||
"alt": 36,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d773",
|
||||
"isorcv": "2024-02-03T16:17:37Z",
|
||||
"isotst": "2024-02-03T16:17:37Z",
|
||||
"disptst": "2024-02-03 16:17:37"
|
||||
},
|
||||
{
|
||||
"cog": 43,
|
||||
"batt": 89,
|
||||
"lon": 37.6176,
|
||||
"acc": 5,
|
||||
"bs": 1,
|
||||
"p": 101.349,
|
||||
"vel": 5,
|
||||
"vac": 3,
|
||||
"lat": 55.7558,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"t": "v",
|
||||
"conn": "m",
|
||||
"m": 1,
|
||||
"tst": 1706981399,
|
||||
"alt": 38,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d7ku",
|
||||
"isorcv": "2024-02-03T17:29:59Z",
|
||||
"isotst": "2024-02-03T17:29:59Z",
|
||||
"disptst": "2024-02-03 17:29:59"
|
||||
},
|
||||
{
|
||||
"cog": 53,
|
||||
"batt": 89,
|
||||
"lon": 37.6176,
|
||||
"acc": 5,
|
||||
"bs": 1,
|
||||
"p": 101.353,
|
||||
"vel": 5,
|
||||
"vac": 3,
|
||||
"lat": 55.7558,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"conn": "m",
|
||||
"m": 1,
|
||||
"tst": 1706981451,
|
||||
"alt": 37,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d7kv",
|
||||
"isorcv": "2024-02-03T17:30:51Z",
|
||||
"isotst": "2024-02-03T17:30:51Z",
|
||||
"disptst": "2024-02-03 17:30:51"
|
||||
},
|
||||
{
|
||||
"cog": 53,
|
||||
"batt": 89,
|
||||
"lon": 37.6176,
|
||||
"acc": 5,
|
||||
"bs": 1,
|
||||
"p": 101.359,
|
||||
"created_at": 1706981777,
|
||||
"vel": 5,
|
||||
"vac": 3,
|
||||
"lat": 55.7558,
|
||||
"topic": "owntracks/test/iPhone 12 Pro",
|
||||
"conn": "m",
|
||||
"m": 1,
|
||||
"tst": 1706981451,
|
||||
"alt": 37,
|
||||
"_type": "location",
|
||||
"tid": "RO",
|
||||
"_http": true,
|
||||
"ghash": "u33d7kv",
|
||||
"isorcv": "2024-02-03T17:30:51Z",
|
||||
"isotst": "2024-02-03T17:30:51Z",
|
||||
"disptst": "2024-02-03 17:30:51"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ RSpec.describe 'Imports', type: :request do
|
|||
before { sign_in user }
|
||||
|
||||
context 'when importing owntracks data' do
|
||||
let(:file) { fixture_file_upload('owntracks/export.json', 'application/json') }
|
||||
let(:file) { fixture_file_upload('owntracks/2024-03.rec', 'application/json') }
|
||||
|
||||
it 'queues import job' do
|
||||
expect do
|
||||
|
|
|
|||
|
|
@ -18,21 +18,21 @@ RSpec.describe OwnTracks::ExportParser do
|
|||
parser
|
||||
|
||||
expect(Point.first.attributes).to include(
|
||||
'latitude' => 40.7128,
|
||||
'longitude' => -74.006,
|
||||
'latitude' => 52.225,
|
||||
'longitude' => 13.332,
|
||||
'battery_status' => 'charging',
|
||||
'battery' => 85,
|
||||
'ping' => nil,
|
||||
'altitude' => 41,
|
||||
'accuracy' => 8,
|
||||
'vertical_accuracy' => 3,
|
||||
'velocity' => nil,
|
||||
'battery' => 94,
|
||||
'ping' => '100.266',
|
||||
'altitude' => 36,
|
||||
'accuracy' => 10,
|
||||
'vertical_accuracy' => 4,
|
||||
'velocity' => '0',
|
||||
'connection' => 'wifi',
|
||||
'ssid' => 'Home Wifi',
|
||||
'bssid' => 'b0:f2:8:45:94:33',
|
||||
'trigger' => 'background_event',
|
||||
'tracker_id' => 'RO',
|
||||
'timestamp' => 1_706_965_203,
|
||||
'timestamp' => 1709283789,
|
||||
'inrids' => ['5f1d1b'],
|
||||
'in_regions' => ['home'],
|
||||
'topic' => 'owntracks/test/iPhone 12 Pro',
|
||||
|
|
@ -40,29 +40,27 @@ RSpec.describe OwnTracks::ExportParser do
|
|||
'user_id' => user.id,
|
||||
'country' => nil,
|
||||
'raw_data' => {
|
||||
'batt' => 85,
|
||||
'lon' => -74.006,
|
||||
'acc' => 8,
|
||||
'bs' => 2,
|
||||
'inrids' => ['5f1d1b'],
|
||||
'BSSID' => 'b0:f2:8:45:94:33',
|
||||
'SSID' => 'Home Wifi',
|
||||
'vac' => 3,
|
||||
'inregions' => ['home'],
|
||||
'lat' => 40.7128,
|
||||
'topic' => 'owntracks/test/iPhone 12 Pro',
|
||||
't' => 'p',
|
||||
'conn' => 'w',
|
||||
'm' => 1,
|
||||
'tst' => 1_706_965_203,
|
||||
'alt' => 41,
|
||||
'_type' => 'location',
|
||||
'tid' => 'RO',
|
||||
'_http' => true,
|
||||
'ghash' => 'u33d773',
|
||||
'isorcv' => '2024-02-03T13:00:03Z',
|
||||
'isotst' => '2024-02-03T13:00:03Z',
|
||||
'disptst' => '2024-02-03 13:00:03'
|
||||
'm'=>1,
|
||||
'p'=>100.266,
|
||||
't'=>'p',
|
||||
'bs'=>2,
|
||||
'acc'=>10,
|
||||
'alt'=>36,
|
||||
'lat'=>52.225,
|
||||
'lon'=>13.332,
|
||||
'tid'=>'RO',
|
||||
'tst'=>1709283789,
|
||||
'vac'=>4,
|
||||
'vel'=>0,
|
||||
'SSID'=>'Home Wifi',
|
||||
'batt'=>94,
|
||||
'conn'=>'w',
|
||||
'BSSID'=>'b0:f2:8:45:94:33',
|
||||
'_http'=>true,
|
||||
'_type'=>'location',
|
||||
'topic'=>'owntracks/test/iPhone 12 Pro',
|
||||
'inrids'=>['5f1d1b'],
|
||||
'inregions'=>['home']
|
||||
}
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ RSpec.describe OwnTracks::Params do
|
|||
describe '#call' do
|
||||
subject(:params) { described_class.new(raw_point_params).call }
|
||||
|
||||
let(:file_path) { 'spec/fixtures/files/owntracks/export.json' }
|
||||
let(:file_path) { 'spec/fixtures/files/owntracks/2024-03.rec' }
|
||||
let(:file) { File.open(file_path) }
|
||||
let(:json) { JSON.parse(file.read) }
|
||||
let(:user) { json.keys.first }
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ describe 'OwnTracks Points API', type: :request do
|
|||
parameter name: :api_key, in: :query, type: :string, required: true, description: 'API Key'
|
||||
|
||||
response '200', 'Point created' do
|
||||
let(:file_path) { 'spec/fixtures/files/owntracks/export.json' }
|
||||
let(:file_path) { 'spec/fixtures/files/owntracks/2024-03.rec' }
|
||||
let(:file) { File.open(file_path) }
|
||||
let(:json) { JSON.parse(file.read) }
|
||||
let(:point) { json['test']['iphone-12-pro'].first }
|
||||
|
|
@ -79,7 +79,7 @@ describe 'OwnTracks Points API', type: :request do
|
|||
end
|
||||
|
||||
response '401', 'Unauthorized' do
|
||||
let(:file_path) { 'spec/fixtures/files/owntracks/export.json' }
|
||||
let(:file_path) { 'spec/fixtures/files/owntracks/2024-03.rec' }
|
||||
let(:file) { File.open(file_path) }
|
||||
let(:json) { JSON.parse(file.read) }
|
||||
let(:point) { json['test']['iphone-12-pro'].first }
|
||||
|
|
|
|||
Loading…
Reference in a new issue