diff options
-rw-r--r-- | lib/postrunner/ActivitiesDB.rb | 4 | ||||
-rw-r--r-- | lib/postrunner/Activity.rb | 51 | ||||
-rw-r--r-- | lib/postrunner/ChartView.rb | 3 | ||||
-rw-r--r-- | lib/postrunner/Main.rb | 6 | ||||
-rw-r--r-- | lib/postrunner/RuntimeConfig.rb | 1 | ||||
-rw-r--r-- | spec/PostRunner_spec.rb | 16 |
6 files changed, 68 insertions, 13 deletions
diff --git a/lib/postrunner/ActivitiesDB.rb b/lib/postrunner/ActivitiesDB.rb index 81f039a..b0207db 100644 --- a/lib/postrunner/ActivitiesDB.rb +++ b/lib/postrunner/ActivitiesDB.rb @@ -49,11 +49,13 @@ module PostRunner # Not all instance variables of Activity are stored in the file. The # normal constructor is not run during YAML::load_file. We have to # initialize those instance variables in a secondary step. + sync_needed = false @activities.each do |a| - a.late_init(self) + sync_needed |= a.late_init(self) end @records = PersonalRecords.new(self) + sync if sync_needed end # Add a new FIT file to the database. diff --git a/lib/postrunner/Activity.rb b/lib/postrunner/Activity.rb index 87c1daa..c346afb 100644 --- a/lib/postrunner/Activity.rb +++ b/lib/postrunner/Activity.rb @@ -23,8 +23,10 @@ module PostRunner # This is a list of variables that provide data from the fit file. To # speed up access to it, we cache the data in the activity database. - @@CachedVariables = %w( sport timestamp total_distance total_timer_time - avg_speed ) + @@CachedVariables = %w( sport timestamp total_distance + total_timer_time avg_speed ) + # We also store some additional information in the archive index. + @@CachedAttributes = @@CachedVariables + %w( fit_file name ) def initialize(db, fit_file, fit_activity, name = nil) @fit_file = fit_file @@ -41,12 +43,29 @@ module PostRunner generate_html_view end + # YAML::load() does not call initialize(). We don't have all attributes + # stored in the YAML file, so we need to make sure these are properly set + # after a YAML::load(). def late_init(db) @db = db @html_dir = File.join(@db.db_dir, 'html') @html_file = File.join(@html_dir, "#{@fit_file[0..-5]}.html") - #@fit_activity = load_fit_file - #@sport = @fit_activity.sessions[0].sport + + # The following code is only needed during version upgrades. It checks + # for any newly added instance variables that have not been loaded from + # the cache. In this case, we need to load the FitActivity and retrieve + # the value from there. + sync_needed = false + @@CachedVariables.each do |var| + unless instance_variable_defined?(ivar = ('@' + var)) + Log.debug "Activity attribute #{var} was not yet cached." + @fit_activity = load_fit_file unless @fit_activity + instance_variable_set(ivar, @fit_activity.send(var)) + sync_needed = true + end + end + + sync_needed end def check @@ -58,26 +77,36 @@ module PostRunner @fit_activity = load_fit_file(filter) end + # This method is called during YAML::load() to initialize the class + # objects. The initialize() is NOT called during YAML::load(). Any + # additional initialization work is done in late_init(). def yaml_initialize(tag, value) # Create attr_readers for cached variables. - @@CachedVariables.each { |v| self.class.send(:attr_reader, v.to_sym) } + @@CachedAttributes.each { |v| self.class.send(:attr_reader, v.to_sym) } # Load all attributes and assign them to instance variables. value.each do |a, v| + # We ignore all variables we don't expect. + unless @@CachedAttributes.include?(a) + Log.debug "Ignoring unknown cached variable #{a}" + next + end + instance_variable_set("@" + a, v) end # Use the FIT file name as activity name if none has been set yet. @name = @fit_file unless @name end + # This method is called during Activity::to_yaml() calls. It's being used + # to prevent some instance variables from being saved in the YAML file. + # Only attributes that are listed in @@CachedAttributes are being saved. def encode_with(coder) - attr_ignore = %w( @db @fit_activity @html_dir @html_file ) - - instance_variables.each do |v| - v = v.to_s - next if attr_ignore.include?(v) + instance_variables.each do |a| + a = a.to_s + next unless @@CachedAttributes.include?(a[1..-1]) - coder[v[1..-1]] = instance_variable_get(v) + coder[a[1..-1]] = instance_variable_get(a) end end diff --git a/lib/postrunner/ChartView.rb b/lib/postrunner/ChartView.rb index 33bd32c..1aa6039 100644 --- a/lib/postrunner/ChartView.rb +++ b/lib/postrunner/ChartView.rb @@ -203,7 +203,8 @@ EOT " transform: function (v) { return -v; },\n" + " inverseTransform: function (v) { return -v; } }" else - s << ", yaxis: { min: #{0.8 * min_value} }" + # Set the minimum slightly below the lowest found value. + s << ", yaxis: { min: #{0.9 * min_value} }" end s << "});\n" s << hover_function(chart_id, y_label, select_unit(unit)) + "\n" diff --git a/lib/postrunner/Main.rb b/lib/postrunner/Main.rb index 25d9cd0..f352a14 100644 --- a/lib/postrunner/Main.rb +++ b/lib/postrunner/Main.rb @@ -163,6 +163,12 @@ EOT def execute_command(args) @activities = ActivitiesDB.new(@db_dir, @cfg) + if @cfg.get_option(:version) != VERSION + Log.warn "Version upgrade detected. Database conversion started..." + @activities.generate_all_html_reports + @cfg.set_option(:version, VERSION) + Log.info "Version upgrade completed." + end case (cmd = args.shift) when 'check' diff --git a/lib/postrunner/RuntimeConfig.rb b/lib/postrunner/RuntimeConfig.rb index 2bb9cb0..2f39d0b 100644 --- a/lib/postrunner/RuntimeConfig.rb +++ b/lib/postrunner/RuntimeConfig.rb @@ -23,6 +23,7 @@ module PostRunner # @param dir [String] the directory to hold the config.yml file. def initialize(dir) @options = { + :version => '0.0.0', :unit_system => :metric, :import_dir => nil } diff --git a/spec/PostRunner_spec.rb b/spec/PostRunner_spec.rb index 9755a7c..d111b81 100644 --- a/spec/PostRunner_spec.rb +++ b/spec/PostRunner_spec.rb @@ -122,5 +122,21 @@ describe PostRunner::Main do postrunner(%w( units metric )) end + it 'should properly upgrade to a new version' do + # Change version in config file to 0.0.0. + rc = PostRunner::RuntimeConfig.new(@db_dir) + rc.set_option(:version, '0.0.0') + # Check that the config file really was changed. + rc = PostRunner::RuntimeConfig.new(@db_dir) + rc.get_option(:version).should == '0.0.0' + + # Run some command. + postrunner(%w( list )) + + # Check that version matches the current version again. + rc = PostRunner::RuntimeConfig.new(@db_dir) + rc.get_option(:version).should == PostRunner::VERSION + end + end |