diff --git a/.gitignore b/.gitignore
index b3803267..9583fb0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,9 @@
.DS_Store
.env
+.byebug_history
+
+
.devcontainer/.onCreateCommandMarker
.devcontainer/.postCreateCommandMarker
.devcontainer/.updateContentCommandMarker
diff --git a/app/jobs/import_job.rb b/app/jobs/import_job.rb
index a07cfa46..5cad02b6 100644
--- a/app/jobs/import_job.rb
+++ b/app/jobs/import_job.rb
@@ -4,9 +4,11 @@ class ImportJob < ApplicationJob
queue_as :imports
def perform(user_id, import_id)
+
user = User.find(user_id)
import = user.imports.find(import_id)
import.process!
+
end
end
diff --git a/app/services/imports/watcher.rb b/app/services/imports/watcher.rb
index 43f3653b..4ea6c07b 100644
--- a/app/services/imports/watcher.rb
+++ b/app/services/imports/watcher.rb
@@ -4,16 +4,19 @@ class Imports::Watcher
class UnsupportedSourceError < StandardError; end
WATCHED_DIR_PATH = Rails.root.join('tmp/imports/watched')
+ SUPPORTED_FORMATS = %w[.gpx .json .rec].freeze
def call
user_directories.each do |user_email|
user = User.find_by(email: user_email)
next unless user
+puts "Processing directory for user: #{user.email}"
user_directory_path = File.join(WATCHED_DIR_PATH, user_email)
file_names = file_names(user_directory_path)
file_names.each do |file_name|
+ puts "Processing file: #{file_name}"
process_file(user, user_directory_path, file_name)
end
end
@@ -36,7 +39,7 @@ class Imports::Watcher
def file_names(directory_path)
Dir.entries(directory_path).select do |file|
- ['.gpx', '.json'].include?(File.extname(file))
+ SUPPORTED_FORMATS.include?(File.extname(file))
end
end
@@ -50,8 +53,11 @@ class Imports::Watcher
import.raw_data = raw_data(file_path, import.source)
import.save!
+ puts "Import saved for file: #{file_name}"
+
ImportJob.perform_later(user.id, import.id)
+ puts "ImportJob enqueued for user_id: #{user.id}, import_id: #{import.id}"
end
def find_or_initialize_import(user, file_name)
@@ -72,9 +78,19 @@ class Imports::Watcher
end
def source(file_name)
- case file_name.split('.').last
- when 'json' then :geojson
- when 'gpx' then :gpx
+ case file_name.split('.').last.downcase
+ when 'json'
+ if file_name.match?(/location-history/i)
+ :google_phone_takeout
+ elsif file_name.match?(/Records/i)
+ :google_records
+ elsif file_name.match?(/\d{4}_\w+/i)
+ :google_semantic_history
+ else
+ :geojson
+ end
+ when 'rec' then :owntracks
+ when 'gpx' then :gpx
else raise UnsupportedSourceError, 'Unsupported source '
end
end
@@ -82,6 +98,15 @@ class Imports::Watcher
def raw_data(file_path, source)
file = File.read(file_path)
- source.to_sym == :gpx ? Hash.from_xml(file) : JSON.parse(file)
+ case source.to_sym
+ when :gpx
+ Hash.from_xml(file)
+ when :json, :geojson, :google_phone_takeout, :google_records, :google_semantic_history
+ JSON.parse(file)
+ when :owntracks
+ OwnTracks::RecParser.new(file).call
+ else
+ raise UnsupportedSourceError, "Unsupported source: #{source}"
+ end
end
-end
+end
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/invalid_user@domain.com/location-history.json b/spec/fixtures/files/watched/invalid_user@domain.com/location-history.json
new file mode 100644
index 00000000..88805bc2
--- /dev/null
+++ b/spec/fixtures/files/watched/invalid_user@domain.com/location-history.json
@@ -0,0 +1,89 @@
+[
+ {
+ "endTime": "2023-08-27T17:04:26.999-05:00",
+ "startTime": "2023-08-27T15:48:56.000-05:00",
+ "visit": {
+ "hierarchyLevel": "0",
+ "topCandidate": {
+ "probability": "0.785181",
+ "semanticType": "Unknown",
+ "placeID": "ChIJxxP_Qwb2aIYRTwDNDLkUmD0",
+ "placeLocation": "geo:27.720022,-97.347951"
+ },
+ "probability": "0.710000"
+ }
+ },
+ {
+ "endTime": "2023-08-27T22:00:00.000Z",
+ "startTime": "2023-08-27T20:00:00.000Z",
+ "timelinePath": [
+ {
+ "point": "geo:27.720007,-97.348044",
+ "durationMinutesOffsetFromStartTime": "49"
+ }
+ ]
+ },
+ {
+ "endTime": "2023-09-02T23:25:59.000-06:00",
+ "startTime": "2023-08-27T14:48:56.000-06:00",
+ "timelineMemory": {
+ "destinations": [
+ {
+ "identifier": "ChIJs9KSYYBfaIYRj5AOiZNQ0a4"
+ },
+ {
+ "identifier": "ChIJw6lCfj2sZ4YRl6q2LNNyojk"
+ },
+ {
+ "identifier": "ChIJA89FstRIAYcRr9I2aBzR89A"
+ },
+ {
+ "identifier": "ChIJtWVg4r5DFIcRr0zkOeDPEfY"
+ }
+ ],
+ "distanceFromOriginKms": "1594"
+ }
+ },
+ {
+ "endTime": "2023-08-28T00:00:00.000Z",
+ "startTime": "2023-08-27T22:00:00.000Z",
+ "timelinePath": [
+ {
+ "point": "geo:27.701123,-97.362988",
+ "durationMinutesOffsetFromStartTime": "4"
+ },
+ {
+ "point": "geo:27.701123,-97.362988",
+ "durationMinutesOffsetFromStartTime": "4"
+ },
+ {
+ "point": "geo:27.687173,-97.363743",
+ "durationMinutesOffsetFromStartTime": "7"
+ },
+ {
+ "point": "geo:27.686129,-97.381865",
+ "durationMinutesOffsetFromStartTime": "10"
+ },
+ {
+ "point": "geo:27.686129,-97.381865",
+ "durationMinutesOffsetFromStartTime": "10"
+ },
+ {
+ "point": "geo:27.686129,-97.381865",
+ "durationMinutesOffsetFromStartTime": "108"
+ },
+ {
+ "point": "geo:27.696576,-97.376949",
+ "durationMinutesOffsetFromStartTime": "109"
+ },
+ {
+ "point": "geo:27.709617,-97.375988",
+ "durationMinutesOffsetFromStartTime": "112"
+ },
+ {
+ "point": "geo:27.709617,-97.375988",
+ "durationMinutesOffsetFromStartTime": "112"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/user@domain.com/2023_January.json b/spec/fixtures/files/watched/user@domain.com/2023_January.json
new file mode 100644
index 00000000..1a25ab3c
--- /dev/null
+++ b/spec/fixtures/files/watched/user@domain.com/2023_January.json
@@ -0,0 +1,70 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.3439906,
+ 50.0506312
+ ]
+ },
+ "properties": {
+ "timestamp": "2023-01-01T08:00:00Z"
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.3439906,
+ 50.0506312
+ ]
+ },
+ "properties": {
+ "timestamp": "2023-01-01T10:00:00Z"
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.42076,
+ 50.08804
+ ]
+ },
+ "properties": {
+ "timestamp": "2023-01-02T12:00:00Z"
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.42076,
+ 50.08804
+ ]
+ },
+ "properties": {
+ "timestamp": "2023-01-02T14:00:00Z"
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 14.42076,
+ 50.08804
+ ]
+ },
+ "properties": {
+ "timestamp": "2023-01-02T16:00:00Z"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/user@domain.com/Records.json b/spec/fixtures/files/watched/user@domain.com/Records.json
new file mode 100644
index 00000000..930ca395
--- /dev/null
+++ b/spec/fixtures/files/watched/user@domain.com/Records.json
@@ -0,0 +1,40 @@
+{
+ "locations": [
+ {
+ "latitudeE7": 533690550,
+ "longitudeE7": 836950010,
+ "accuracy": 150,
+ "source": "UNKNOWN",
+ "timestamp": "2012-12-15T14:21:29.460Z"
+ },
+ {
+ "latitudeE7": 533563380,
+ "longitudeE7": 837616500,
+ "accuracy": 18000,
+ "source": "UNKNOWN",
+ "timestamp": "2013-01-04T10:22:43.225Z"
+ },
+ {
+ "latitudeE7": 533690589,
+ "longitudeE7": 836951347,
+ "accuracy": 22,
+ "source": "WIFI",
+ "deviceTag": 1184882232,
+ "timestamp": "2013-03-01T05:17:39.849Z"
+ },
+ {
+ "latitudeE7": 533700000,
+ "longitudeE7": 836960000,
+ "accuracy": 50,
+ "source": "GPS",
+ "timestamp": "2013-04-01T12:00:00.000Z"
+ },
+ {
+ "latitudeE7": 533710000,
+ "longitudeE7": 836970000,
+ "accuracy": 30,
+ "source": "GPS",
+ "timestamp": "2013-05-01T08:30:00.000Z"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/user@domain.com/export_same_points.json b/spec/fixtures/files/watched/user@domain.com/export_same_points.json
index 2ecfb883..7951ef5a 100644
--- a/spec/fixtures/files/watched/user@domain.com/export_same_points.json
+++ b/spec/fixtures/files/watched/user@domain.com/export_same_points.json
@@ -1 +1,175 @@
-{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}},{"type":"Feature","geometry":{"type":"Point","coordinates":["37.6173","55.755826"]},"properties":{"battery_status":"unplugged","ping":"MyString","battery":1,"tracker_id":"MyString","topic":"MyString","altitude":1,"longitude":"37.6173","velocity":"0","trigger":"background_event","bssid":"MyString","ssid":"MyString","connection":"wifi","vertical_accuracy":1,"accuracy":1,"timestamp":1609459200,"latitude":"55.755826","mode":1,"inrids":[],"in_regions":[],"city":null,"country":null,"geodata":{}}}]}
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ "37.6173",
+ "55.755826"
+ ]
+ },
+ "properties": {
+ "battery_status": "unplugged",
+ "ping": "MyString",
+ "battery": 1,
+ "tracker_id": "MyString",
+ "topic": "MyString",
+ "altitude": 1,
+ "longitude": "37.6173",
+ "velocity": "0",
+ "trigger": "background_event",
+ "bssid": "MyString",
+ "ssid": "MyString",
+ "connection": "wifi",
+ "vertical_accuracy": 1,
+ "accuracy": 1,
+ "timestamp": 1609459200,
+ "latitude": "55.755826",
+ "mode": 1,
+ "inrids": [],
+ "in_regions": [],
+ "city": null,
+ "country": null,
+ "geodata": {}
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ "37.6173",
+ "55.755826"
+ ]
+ },
+ "properties": {
+ "battery_status": "unplugged",
+ "ping": "MyString",
+ "battery": 1,
+ "tracker_id": "MyString",
+ "topic": "MyString",
+ "altitude": 1,
+ "longitude": "37.6173",
+ "velocity": "0",
+ "trigger": "background_event",
+ "bssid": "MyString",
+ "ssid": "MyString",
+ "connection": "wifi",
+ "vertical_accuracy": 1,
+ "accuracy": 1,
+ "timestamp": 1609459200,
+ "latitude": "55.755826",
+ "mode": 1,
+ "inrids": [],
+ "in_regions": [],
+ "city": null,
+ "country": null,
+ "geodata": {}
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ "37.6173",
+ "55.755826"
+ ]
+ },
+ "properties": {
+ "battery_status": "unplugged",
+ "ping": "MyString",
+ "battery": 1,
+ "tracker_id": "MyString",
+ "topic": "MyString",
+ "altitude": 1,
+ "longitude": "37.6173",
+ "velocity": "0",
+ "trigger": "background_event",
+ "bssid": "MyString",
+ "ssid": "MyString",
+ "connection": "wifi",
+ "vertical_accuracy": 1,
+ "accuracy": 1,
+ "timestamp": 1609459200,
+ "latitude": "55.755826",
+ "mode": 1,
+ "inrids": [],
+ "in_regions": [],
+ "city": null,
+ "country": null,
+ "geodata": {}
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ "37.6173",
+ "55.755826"
+ ]
+ },
+ "properties": {
+ "battery_status": "unplugged",
+ "ping": "MyString",
+ "battery": 1,
+ "tracker_id": "MyString",
+ "topic": "MyString",
+ "altitude": 1,
+ "longitude": "37.6173",
+ "velocity": "0",
+ "trigger": "background_event",
+ "bssid": "MyString",
+ "ssid": "MyString",
+ "connection": "wifi",
+ "vertical_accuracy": 1,
+ "accuracy": 1,
+ "timestamp": 1609459200,
+ "latitude": "55.755826",
+ "mode": 1,
+ "inrids": [],
+ "in_regions": [],
+ "city": null,
+ "country": null,
+ "geodata": {}
+ }
+ },
+ {
+ "type": "Feature",
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ "37.6173",
+ "55.755826"
+ ]
+ },
+ "properties": {
+ "battery_status": "unplugged",
+ "ping": "MyString",
+ "battery": 1,
+ "tracker_id": "MyString",
+ "topic": "MyString",
+ "altitude": 1,
+ "longitude": "37.6173",
+ "velocity": "0",
+ "trigger": "background_event",
+ "bssid": "MyString",
+ "ssid": "MyString",
+ "connection": "wifi",
+ "vertical_accuracy": 1,
+ "accuracy": 1,
+ "timestamp": 1609459200,
+ "latitude": "55.755826",
+ "mode": 1,
+ "inrids": [],
+ "in_regions": [],
+ "city": null,
+ "country": null,
+ "geodata": {}
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/user@domain.com/gpx_track_single_segment.gpx b/spec/fixtures/files/watched/user@domain.com/gpx_track_single_segment.gpx
index 3176fb4f..7c73a8ac 100644
--- a/spec/fixtures/files/watched/user@domain.com/gpx_track_single_segment.gpx
+++ b/spec/fixtures/files/watched/user@domain.com/gpx_track_single_segment.gpx
@@ -34,1206 +34,6 @@
811.41
-
- 808.11
-
-
-
- 805.33
-
-
-
- 802.85
-
-
-
- 800.8
-
-
-
- 798.9
-
-
-
- 797.19
-
-
-
- 795.8
-
-
-
- 794.31
-
-
-
- 793.25
-
-
-
- 792.19
-
-
-
- 791.44
-
-
-
- 791.24
-
-
-
- 791.47
-
-
-
- 792.04
-
-
-
- 792.18
-
-
-
- 793.94
-
-
-
- 795.29
-
-
-
- 796.89
-
-
-
- 798.7
-
-
-
- 801.44
-
-
-
- 803.97
-
-
-
- 806.6
-
-
-
- 809.27
-
-
-
- 811.96
-
-
-
- 814.62
-
-
-
- 817.54
-
-
-
- 820.18
-
-
-
- 822.76
-
-
-
- 825.25
-
-
-
- 827.89
-
-
-
- 830.82
-
-
-
- 833.17
-
-
-
- 835.42
-
-
-
- 837.9
-
-
-
- 839.89
-
-
-
- 841.98
-
-
-
- 844.17
-
-
-
- 846.01
-
-
-
- 847.32
-
-
-
- 848.51
-
-
-
- 849.54
-
-
-
- 850.3
-
-
-
- 850.74
-
-
-
- 851.11
-
-
-
- 851.31
-
-
-
- 851.37
-
-
-
- 851.36
-
-
-
- 851.21
-
-
-
- 851.04
-
-
-
- 850.86
-
-
-
- 850.41
-
-
-
- 849.94
-
-
-
- 849.54
-
-
-
- 849.08
-
-
-
- 848.67
-
-
-
- 848.36
-
-
-
- 848.08
-
-
-
- 847.87
-
-
-
- 847.77
-
-
-
- 847.74
-
-
-
- 847.75
-
-
-
- 847.81
-
-
-
- 847.96
-
-
-
- 848.17
-
-
-
- 848.37
-
-
-
- 848.68
-
-
-
- 849.01
-
-
-
- 849.24
-
-
-
- 849.47
-
-
-
- 849.7
-
-
-
- 849.88
-
-
-
- 850.1
-
-
-
- 850.25
-
-
-
- 850.38
-
-
-
- 850.47
-
-
-
- 850.46
-
-
-
- 850.35
-
-
-
- 850.35
-
-
-
- 850.02
-
-
-
- 849.6
-
-
-
- 849.05
-
-
-
- 848.37
-
-
-
- 847.54
-
-
-
- 846.57
-
-
-
- 845.55
-
-
-
- 844.29
-
-
-
- 842.85
-
-
-
- 841.43
-
-
-
- 839.98
-
-
-
- 838.63
-
-
-
- 837.18
-
-
-
- 835.48
-
-
-
- 833.92
-
-
-
- 832.43
-
-
-
- 831.06
-
-
-
- 829.84
-
-
-
- 829.04
-
-
-
- 828.42
-
-
-
- 828.15
-
-
-
- 828.11
-
-
-
- 828.51
-
-
-
- 829.55
-
-
-
- 830.31
-
-
-
- 831.12
-
-
-
- 831.93
-
-
-
- 832.91
-
-
-
- 833.85
-
-
-
- 834.91
-
-
-
- 836.07
-
-
-
- 837.2
-
-
-
- 838.38
-
-
-
- 839.56
-
-
-
- 840.58
-
-
-
- 841.58
-
-
-
- 842.46
-
-
-
- 843.23
-
-
-
- 843.46
-
-
-
- 843.41
-
-
-
- 842.64
-
-
-
- 841.84
-
-
-
- 840.81
-
-
-
- 839.56
-
-
-
- 837.86
-
-
-
- 836.03
-
-
-
- 833.91
-
-
-
- 831.55
-
-
-
- 828.71
-
-
-
- 825.47
-
-
-
- 820.96
-
-
-
- 817.85
-
-
-
- 814.71
-
-
-
- 811.52
-
-
-
- 808.25
-
-
-
- 805.03
-
-
-
- 801.68
-
-
-
- 798.27
-
-
-
- 794.91
-
-
-
- 791.73
-
-
-
- 788.61
-
-
-
- 785.48
-
-
-
- 782.4
-
-
-
- 779.42
-
-
-
- 776.47
-
-
-
- 773.67
-
-
-
- 770.99
-
-
-
- 768.4
-
-
-
- 765.66
-
-
-
- 763.1
-
-
-
- 760.26
-
-
-
- 757.88
-
-
-
- 755.75
-
-
-
- 753.7
-
-
-
- 751.75
-
-
-
- 749.94
-
-
-
- 748.17
-
-
-
- 746.34
-
-
-
- 744.47
-
-
-
- 743.18
-
-
-
- 742.0
-
-
-
- 741.01
-
-
-
- 740.17
-
-
-
- 739.53
-
-
-
- 738.88
-
-
-
- 738.42
-
-
-
- 738.16
-
-
-
- 738.01
-
-
-
- 738.01
-
-
-
- 738.11
-
-
-
- 738.36
-
-
-
- 738.8
-
-
-
- 739.13
-
-
-
- 739.78
-
-
-
- 740.12
-
-
-
- 740.55
-
-
-
- 740.93
-
-
-
- 741.31
-
-
-
- 741.6
-
-
-
- 741.82
-
-
-
- 741.89
-
-
-
- 741.94
-
-
-
- 741.89
-
-
-
- 742.0
-
-
-
- 742.05
-
-
-
- 742.17
-
-
-
- 742.28
-
-
-
- 742.49
-
-
-
- 742.74
-
-
-
- 742.86
-
-
-
- 743.34
-
-
-
- 744.01
-
-
-
- 744.96
-
-
-
- 746.14
-
-
-
- 747.41
-
-
-
- 748.68
-
-
-
- 750.03
-
-
-
- 751.57
-
-
-
- 753.47
-
-
-
- 755.4
-
-
-
- 757.49
-
-
-
- 759.68
-
-
-
- 762.09
-
-
-
- 764.56
-
-
-
- 767.4
-
-
-
- 770.3
-
-
-
- 773.45
-
-
-
- 776.83
-
-
-
- 780.51
-
-
-
- 783.74
-
-
-
- 786.94
-
-
-
- 790.76
-
-
-
- 794.06
-
-
-
- 797.36
-
-
-
- 800.75
-
-
-
- 804.12
-
-
-
- 807.53
-
-
-
- 811.02
-
-
-
- 814.61
-
-
-
- 818.13
-
-
-
- 821.6
-
-
-
- 825.29
-
-
-
- 828.89
-
-
-
- 832.37
-
-
-
- 836.28
-
-
-
- 839.49
-
-
-
- 842.19
-
-
-
- 844.74
-
-
-
- 847.21
-
-
-
- 849.34
-
-
-
- 851.3
-
-
-
- 852.93
-
-
-
- 854.35
-
-
-
- 855.69
-
-
-
- 856.86
-
-
-
- 857.72
-
-
-
- 858.43
-
-
-
- 858.78
-
-
-
- 859.01
-
-
-
- 859.0
-
-
-
- 858.97
-
-
-
- 859.21
-
-
-
- 859.45
-
-
-
- 859.73
-
-
-
- 860.06
-
-
-
- 860.45
-
-
-
- 861.08
-
-
-
- 861.61
-
-
-
- 862.29
-
-
-
- 863.0
-
-
-
- 863.9
-
-
-
- 864.96
-
-
-
- 866.07
-
-
-
- 867.3
-
-
-
- 869.0
-
-
-
- 870.45
-
-
-
- 871.97
-
-
-
- 873.37
-
-
-
- 874.8
-
-
-
- 876.17
-
-
-
- 877.6
-
-
-
- 879.15
-
-
-
- 880.87
-
-
-
- 882.54
-
-
-
- 884.28
-
-
-
- 886.01
-
-
-
- 887.84
-
-
-
- 889.62
-
-
-
- 891.29
-
-
-
- 892.83
-
-
-
- 893.87
-
-
-
- 894.78
-
-
-
- 895.66
-
-
-
- 896.51
-
-
-
- 896.83
-
-
-
- 896.95
-
-
-
- 896.98
-
-
-
- 896.67
-
-
-
- 896.92
-
-
-
- 897.13
-
-
-
- 897.08
-
-
-
- 897.65
-
-
-
- 898.62
-
-
-
- 899.59
-
-
-
- 900.3
-
-
-
- 901.06
-
-
-
- 901.98
-
-
-
- 902.94
-
-
-
- 904.14
-
-
-
- 905.06
-
-
-
- 905.5
-
-
-
- 905.8
-
-
-
- 905.47
-
-
-
- 905.91
-
-
-
- 906.01
-
-
-
- 905.66
-
-
-
- 904.85
-
-
-
- 904.4
-
-
-
- 903.49
-
-
-
- 903.02
-
-
-
- 901.8
-
-
-
- 901.42
-
-
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/user@domain.com/location-history.json b/spec/fixtures/files/watched/user@domain.com/location-history.json
new file mode 100644
index 00000000..88805bc2
--- /dev/null
+++ b/spec/fixtures/files/watched/user@domain.com/location-history.json
@@ -0,0 +1,89 @@
+[
+ {
+ "endTime": "2023-08-27T17:04:26.999-05:00",
+ "startTime": "2023-08-27T15:48:56.000-05:00",
+ "visit": {
+ "hierarchyLevel": "0",
+ "topCandidate": {
+ "probability": "0.785181",
+ "semanticType": "Unknown",
+ "placeID": "ChIJxxP_Qwb2aIYRTwDNDLkUmD0",
+ "placeLocation": "geo:27.720022,-97.347951"
+ },
+ "probability": "0.710000"
+ }
+ },
+ {
+ "endTime": "2023-08-27T22:00:00.000Z",
+ "startTime": "2023-08-27T20:00:00.000Z",
+ "timelinePath": [
+ {
+ "point": "geo:27.720007,-97.348044",
+ "durationMinutesOffsetFromStartTime": "49"
+ }
+ ]
+ },
+ {
+ "endTime": "2023-09-02T23:25:59.000-06:00",
+ "startTime": "2023-08-27T14:48:56.000-06:00",
+ "timelineMemory": {
+ "destinations": [
+ {
+ "identifier": "ChIJs9KSYYBfaIYRj5AOiZNQ0a4"
+ },
+ {
+ "identifier": "ChIJw6lCfj2sZ4YRl6q2LNNyojk"
+ },
+ {
+ "identifier": "ChIJA89FstRIAYcRr9I2aBzR89A"
+ },
+ {
+ "identifier": "ChIJtWVg4r5DFIcRr0zkOeDPEfY"
+ }
+ ],
+ "distanceFromOriginKms": "1594"
+ }
+ },
+ {
+ "endTime": "2023-08-28T00:00:00.000Z",
+ "startTime": "2023-08-27T22:00:00.000Z",
+ "timelinePath": [
+ {
+ "point": "geo:27.701123,-97.362988",
+ "durationMinutesOffsetFromStartTime": "4"
+ },
+ {
+ "point": "geo:27.701123,-97.362988",
+ "durationMinutesOffsetFromStartTime": "4"
+ },
+ {
+ "point": "geo:27.687173,-97.363743",
+ "durationMinutesOffsetFromStartTime": "7"
+ },
+ {
+ "point": "geo:27.686129,-97.381865",
+ "durationMinutesOffsetFromStartTime": "10"
+ },
+ {
+ "point": "geo:27.686129,-97.381865",
+ "durationMinutesOffsetFromStartTime": "10"
+ },
+ {
+ "point": "geo:27.686129,-97.381865",
+ "durationMinutesOffsetFromStartTime": "108"
+ },
+ {
+ "point": "geo:27.696576,-97.376949",
+ "durationMinutesOffsetFromStartTime": "109"
+ },
+ {
+ "point": "geo:27.709617,-97.375988",
+ "durationMinutesOffsetFromStartTime": "112"
+ },
+ {
+ "point": "geo:27.709617,-97.375988",
+ "durationMinutesOffsetFromStartTime": "112"
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/spec/fixtures/files/watched/user@domain.com/owntracks.rec b/spec/fixtures/files/watched/user@domain.com/owntracks.rec
new file mode 100644
index 00000000..473591f7
--- /dev/null
+++ b/spec/fixtures/files/watched/user@domain.com/owntracks.rec
@@ -0,0 +1,13 @@
+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:08Z lwt {"_type":"lwt","tst":1717459208}
+2024-03-01T18:40:09Z waypoints {"_type":"waypoint","desc":"Home","lat":52.232,"lon":13.339,"rad":50,"tst":1717459768}
+2024-03-01T18:40:10Z event {"_type":"transition","acc":5,"desc":"Home","event":"enter","lat":52.232,"lon":13.339,"t":"l","tid":"s8","tst":1717460098,"wtst":1717459768}
+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}
diff --git a/spec/services/imports/watcher_spec.rb b/spec/services/imports/watcher_spec.rb
index 83dacdf2..65bcd19a 100644
--- a/spec/services/imports/watcher_spec.rb
+++ b/spec/services/imports/watcher_spec.rb
@@ -11,8 +11,11 @@ RSpec.describe Imports::Watcher do
before do
stub_const('Imports::Watcher::WATCHED_DIR_PATH', watched_dir_path)
+ Sidekiq::Testing.inline!
end
+ after { Sidekiq::Testing.fake! }
+
context 'when there are no files in the watched directory' do
it 'does not call ImportJob' do
expect(ImportJob).not_to receive(:perform_later)
@@ -22,26 +25,34 @@ RSpec.describe Imports::Watcher do
end
context 'when there are files in the watched directory' do
- Sidekiq::Testing.inline! do
- context 'when the file has a valid user email' do
- it 'creates an import for the user' do
- expect { service }.to change(user.imports, :count).by(2)
- end
+ context 'when the file has a valid user email' do
+ it 'creates an import for the user' do
+ expect { service }.to change(user.imports, :count).by(6)
end
- context 'when the file has an invalid user email' do
- it 'does not create an import' do
- expect { service }.not_to change(Import, :count)
- end
+ it 'creates points for the user' do
+ initial_point_count = Point.count
+ service
+ expect(Point.count).to be > initial_point_count
end
+ end
- context 'when the import already exists' do
- it 'does not create a new import' do
- create(:import, user:, name: 'export_same_points.json')
- create(:import, user:, name: 'gpx_track_single_segment.gpx')
+ context 'when the file has an invalid user email' do
+ it 'does not create an import' do
+ expect { service }.not_to change(Import, :count)
+ end
+ end
- expect { service }.not_to change(Import, :count)
- end
+ context 'when the import already exists' do
+ it 'does not create a new import' do
+ create(:import, user:, name: '2023_January.json')
+ create(:import, user:, name: 'export_same_points.json')
+ create(:import, user:, name: 'gpx_track_single_segment.gpx')
+ create(:import, user:, name: 'location-history.json')
+ create(:import, user:, name: 'owntracks.rec')
+ create(:import, user:, name: 'Records.json')
+
+ expect { service }.not_to change(Import, :count)
end
end
end