diff options
-rw-r--r-- | lib/postrunner/FFS_Device.rb | 5 | ||||
-rw-r--r-- | lib/postrunner/FitFileStore.rb | 67 | ||||
-rw-r--r-- | lib/postrunner/Log.rb | 2 | ||||
-rw-r--r-- | lib/postrunner/Main.rb | 15 | ||||
-rw-r--r-- | lib/postrunner/version.rb | 4 | ||||
-rw-r--r-- | postrunner.gemspec | 2 | ||||
-rw-r--r-- | spec/FitFileStore_spec.rb | 14 |
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 |