summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2020-07-26 14:17:00 +0200
committerChris Schlaeger <chris@linux.com>2020-07-26 14:17:00 +0200
commit6ab4a03f9249a8b903d2e8c42a3f94bd614ff5c7 (patch)
treec345cc8bc95fe45885f683fb189ab84ec38971e0
parente11e292e9c72e5295b6b9918aaeab62310ef5904 (diff)
downloadpostrunner-6ab4a03f9249a8b903d2e8c42a3f94bd614ff5c7.zip
New: Improved handling of unknown devices and unknown FIT elements
-rw-r--r--lib/postrunner/FFS_Device.rb5
-rw-r--r--lib/postrunner/FitFileStore.rb67
-rw-r--r--lib/postrunner/Log.rb2
-rw-r--r--lib/postrunner/Main.rb15
-rw-r--r--lib/postrunner/version.rb4
-rw-r--r--postrunner.gemspec2
-rw-r--r--spec/FitFileStore_spec.rb14
7 files changed, 87 insertions, 22 deletions
diff --git a/lib/postrunner/FFS_Device.rb b/lib/postrunner/FFS_Device.rb
index cd59711..d1d0e7f 100644
--- a/lib/postrunner/FFS_Device.rb
+++ b/lib/postrunner/FFS_Device.rb
@@ -3,7 +3,7 @@
#
# = FFS_Device.rb -- PostRunner - Manage the data from your Garmin sport devices.
#
-# Copyright (c) 2015, 2016, 2018 by Chris Schlaeger <cs@taskjuggler.org>
+# Copyright (c) 2015, 2016, 2018, 2020 by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -83,7 +83,8 @@ module PostRunner
return nil
end
else
- # Don't add the entity if has deleted before and overwrite isn't true.
+ # Don't add the entity if it has deleted before and overwrite isn't
+ # true.
path = @store['file_store'].fit_file_dir(File.basename(fit_file_name),
long_uid, type)
fq_fit_file_name = File.join(path, File.basename(fit_file_name))
diff --git a/lib/postrunner/FitFileStore.rb b/lib/postrunner/FitFileStore.rb
index d91cd28..f2e80b6 100644
--- a/lib/postrunner/FitFileStore.rb
+++ b/lib/postrunner/FitFileStore.rb
@@ -44,7 +44,7 @@ module PostRunner
# Setup non-persistent variables.
def restore
@data_dir = @store['config']['data_dir']
- # Ensure that we have an Array in the store to hold all known devices.
+ # Ensure that we have a Hash in the store to hold all known devices.
@store['devices'] = @store.new(PEROBS::Hash) unless @store['devices']
@devices_dir = File.join(@data_dir, 'devices')
@@ -69,8 +69,58 @@ module PostRunner
end
# Version upgrade logic.
- def handle_version_update
- # Nothing here so far.
+ def handle_version_update(from_version, to_version)
+ if from_version <= Gem::Version.new('0.12.0')
+ # PostRunner up until version 0.12.0 was using a long_uid with
+ # manufacturer name and product name. This was a bad idea since unknown
+ # devices were resolved to their numerical ID. In case the unknown ID
+ # was later added to the dictionary in fit4ruby version update, it
+ # resolved to its name and the device was recognized as a new device.
+ # Versions after 0.12.0 only use the numerical versions for the device
+ # long_uid and directory names.
+ uid_remap = {}
+ @store['devices'].each do |uid, device|
+ old_uid = uid
+
+ if (first_activity = device.activities.first)
+ first_activity.load_fit_file
+ if (fit_activity = first_activity.fit_activity)
+ if (device_info = fit_activity.device_infos.first)
+ new_uid = "#{device_info.numeric_manufacturer}-" +
+ "#{device_info.numeric_product}-#{device_info.serial_number}"
+
+ uid_remap[old_uid] = new_uid
+ puts first_activity.fit_file_name
+ end
+ end
+ end
+ end
+
+ @store.transaction do
+ pwd = Dir.pwd
+ base_dir_name = @store['config']['devices_dir']
+ Dir.chdir(base_dir_name)
+
+ uid_remap.each do |old_uid, new_uid|
+ if Dir.exist?(old_uid) && !Dir.exist?(new_uid) &&
+ !File.symlink?(old_uid)
+ # Rename the directory from the old (string) scheme to the
+ # new numeric scheme.
+ FileUtils.mv(old_uid, new_uid)
+ # Create a symbolic link with that points the old name to
+ # the new name.
+ File.symlink(new_uid, old_uid)
+ end
+
+ # Now update the long_uid in the FFS_Device object
+ @store['devices'][new_uid] = device = @store['devices'][old_uid]
+ device.long_uid = new_uid
+ @store['devices'].delete(old_uid)
+ end
+
+ Dir.chdir(pwd)
+ end
+ end
end
# Add a file to the store.
@@ -95,7 +145,8 @@ module PostRunner
# Generate a String that uniquely identifies the device that generated
# the FIT file.
id = extract_fit_file_id(fit_entity)
- long_uid = "#{id[:manufacturer]}-#{id[:product]}-#{id[:serial_number]}"
+ long_uid = "#{id[:numeric_manufacturer]}-" +
+ "#{id[:numeric_product]}-#{id[:serial_number]}"
# Make sure the device that created the FIT file is properly registered.
device = register_device(long_uid)
@@ -187,6 +238,7 @@ module PostRunner
@store['records'].generate_html_reports
generate_html_index_pages
end
+
# Determine the right directory for the given FIT file. The resulting path
# looks something like /home/user/.postrunner/devices/garmin-fenix3-1234/
# activity/5A.
@@ -462,6 +514,8 @@ module PostRunner
return {
:manufacturer => di.manufacturer,
:product => di.garmin_product || di.product,
+ :numeric_manufacturer => di.numeric_manufacturer,
+ :numeric_product => di.numeric_product,
:serial_number => di.serial_number
}
end
@@ -483,6 +537,8 @@ module PostRunner
return {
:manufacturer => fid.manufacturer,
:product => fid.garmin_product || fid.product,
+ :numeric_manufacturer => di.numeric_manufacturer,
+ :numeric_product => di.numeric_product,
:serial_number => fid.serial_number
}
end
@@ -502,7 +558,8 @@ module PostRunner
@store.new(FFS_Device, short_uid, long_uid)
# Create the directory to store the FIT files of this device.
- create_directory(File.join(@devices_dir, long_uid), long_uid)
+ create_directory(File.join(@devices_dir, long_uid),
+ long_uid)
end
@store['devices'][long_uid]
diff --git a/lib/postrunner/Log.rb b/lib/postrunner/Log.rb
index be63e77..d526f06 100644
--- a/lib/postrunner/Log.rb
+++ b/lib/postrunner/Log.rb
@@ -19,7 +19,7 @@ module PostRunner
Log.formatter = proc { |severity, datetime, progname, msg|
"#{severity == Logger::INFO ? '' : "#{severity}:"} #{msg}\n"
}
- Log.level = Logger::INFO
+ Log.level = Logger::WARN
end
diff --git a/lib/postrunner/Main.rb b/lib/postrunner/Main.rb
index 2a75e02..6ad96ee 100644
--- a/lib/postrunner/Main.rb
+++ b/lib/postrunner/Main.rb
@@ -107,7 +107,7 @@ module PostRunner
opts.separator <<"EOT"
-Copyright (c) 2014, 2015, 2016, 2017 by Chris Schlaeger
+Copyright (c) 2014, 2015, 2016, 2017, 2018, 2019, 2020 by Chris Schlaeger
This program is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published by the
@@ -597,10 +597,17 @@ EOT
def handle_version_update
if @db['config']['version'] != VERSION
- Log.warn "PostRunner version upgrade detected."
- @ffs.handle_version_update
+ puts "Work needed"
+ from_version = Gem::Version.new(@db['config']['version'])
+ to_version = Gem::Version.new(VERSION)
+
+ Log.warn "PostRunner version upgrade from #{from_version} to " +
+ "#{to_version} started."
+ @ffs.handle_version_update(from_version, to_version)
+
@db['config']['version'] = VERSION
- Log.info "Version upgrade completed."
+ Log.warn "PostRunner version upgrade from #{from_version} to " +
+ "#{to_version} completed."
end
end
diff --git a/lib/postrunner/version.rb b/lib/postrunner/version.rb
index b74e926..a4519d4 100644
--- a/lib/postrunner/version.rb
+++ b/lib/postrunner/version.rb
@@ -3,7 +3,7 @@
#
# = version.rb -- PostRunner - Manage the data from your Garmin sport devices.
#
-# Copyright (c) 2014, 2015, 2016, 2017 by Chris Schlaeger <cs@taskjuggler.org>
+# Copyright (c) 2014, 2015, 2016, 2017, 2020 by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -11,5 +11,5 @@
#
module PostRunner
- VERSION = '0.12.0'
+ VERSION = '1.0.0'
end
diff --git a/postrunner.gemspec b/postrunner.gemspec
index 3aab4de..7f4dab0 100644
--- a/postrunner.gemspec
+++ b/postrunner.gemspec
@@ -28,7 +28,7 @@ operating systems as well.}
spec.require_paths = ["lib"]
spec.required_ruby_version = '>=2.4'
- spec.add_dependency 'fit4ruby', '~> 3.5.0'
+ spec.add_dependency 'fit4ruby', '~> 3.6.0'
spec.add_dependency 'perobs', '~> 4.2.0'
spec.add_dependency 'nokogiri', '~> 1.6'
diff --git a/spec/FitFileStore_spec.rb b/spec/FitFileStore_spec.rb
index 91797aa..6206a4a 100644
--- a/spec/FitFileStore_spec.rb
+++ b/spec/FitFileStore_spec.rb
@@ -3,7 +3,7 @@
#
# = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices.
#
-# Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org>
+# Copyright (c) 2014, 2015, 2016, 2020 by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -51,7 +51,7 @@ describe PostRunner::FitFileStore do
expect(@activities[-1]).not_to be_nil
expect(@ffs.devices.length).to eq(1)
- expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
+ expect(@ffs.devices.include?('1-2050-123456790')).to be true
expect(@ffs.activities.length).to eq(1)
expect(@ffs.ref_by_activity(@activities[0])).to eq(1)
end
@@ -60,7 +60,7 @@ describe PostRunner::FitFileStore do
expect(@ffs.add_fit_file(@fit_file_names[0])).to be_nil
expect(@ffs.devices.length).to eq(1)
- expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
+ expect(@ffs.devices.include?('1-2050-123456790')).to be true
expect(@ffs.activities.length).to eq(1)
end
@@ -69,8 +69,8 @@ describe PostRunner::FitFileStore do
expect(@activities[-1]).not_to be_nil
expect(@ffs.devices.length).to eq(2)
- expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
- expect(@ffs.devices.include?('garmin-fenix3-123456791')).to be true
+ expect(@ffs.devices.include?('1-2050-123456790')).to be true
+ expect(@ffs.devices.include?('1-2050-123456791')).to be true
expect(@ffs.activities.length).to eq(2)
expect(@ffs.ref_by_activity(@activities[1])).to eq(1)
end
@@ -80,8 +80,8 @@ describe PostRunner::FitFileStore do
expect(@activities[-1]).not_to be_nil
expect(@ffs.devices.length).to eq(2)
- expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true
- expect(@ffs.devices.include?('garmin-fenix3-123456791')).to be true
+ expect(@ffs.devices.include?('1-2050-123456790')).to be true
+ expect(@ffs.devices.include?('1-2050-123456791')).to be true
expect(@ffs.activities.length).to eq(3)
expect(@ffs.ref_by_activity(@activities[2])).to eq(1)
end