summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/postrunner/ActivitiesDB.rb4
-rw-r--r--lib/postrunner/Activity.rb51
-rw-r--r--lib/postrunner/ChartView.rb3
-rw-r--r--lib/postrunner/Main.rb6
-rw-r--r--lib/postrunner/RuntimeConfig.rb1
-rw-r--r--spec/PostRunner_spec.rb16
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