diff options
author | Chris Schlaeger <chris@linux.com> | 2014-07-20 21:47:39 +0200 |
---|---|---|
committer | Chris Schlaeger <chris@linux.com> | 2014-07-20 21:47:39 +0200 |
commit | 06fd275a92cee58de4fcb2ca5e8f255f655d4ba5 (patch) | |
tree | 8eff1d8252ff14e7367d8aa68781d01d9e267f57 /lib | |
parent | cc72a9807699b95363d0ae58aa5237d982946470 (diff) | |
download | postrunner-06fd275a92cee58de4fcb2ca5e8f255f655d4ba5.zip |
Lots of cleanup work
Diffstat (limited to 'lib')
-rw-r--r-- | lib/postrunner/ActivitiesDB.rb | 35 | ||||
-rw-r--r-- | lib/postrunner/Activity.rb | 53 | ||||
-rw-r--r-- | lib/postrunner/Main.rb | 43 | ||||
-rw-r--r-- | lib/postrunner/RuntimeConfig.rb | 20 |
4 files changed, 139 insertions, 12 deletions
diff --git a/lib/postrunner/ActivitiesDB.rb b/lib/postrunner/ActivitiesDB.rb index df0c105..c8785fb 100644 --- a/lib/postrunner/ActivitiesDB.rb +++ b/lib/postrunner/ActivitiesDB.rb @@ -8,6 +8,8 @@ module PostRunner class ActivitiesDB + include Fit4Ruby::Converters + def initialize(db_dir) @db_dir = db_dir @fit_dir = File.join(@db_dir, 'fit') @@ -21,24 +23,28 @@ module PostRunner @activities = [] end rescue - Log.fatal "Cannot load archive file #{@archive_file}: #{$!}" + Log.fatal "Cannot load archive file '#{@archive_file}': #{$!}" end else create_directories @activities = [] end + + unless @activities.is_a?(Array) + Log.fatal "The archive file '#{@archive_file}' is corrupted" + end end def add(fit_file) base_fit_file = File.basename(fit_file) if @activities.find { |a| a.fit_file == base_fit_file } - Log.warn "Activity #{fit_file} is already included in the archive" + Log.debug "Activity #{fit_file} is already included in the archive" return false end begin fit_activity = Fit4Ruby.read(fit_file) - rescue + rescue Fit4Ruby::Error Log.error "Cannot read #{fit_file}: #{$!}" return false end @@ -50,12 +56,27 @@ module PostRunner end @activities << Activity.new(base_fit_file, fit_activity) + @activities.sort! do |a1, a2| + a2.start_time <=> a1.start_time + end sync Log.info "#{fit_file} successfully added to archive" true end + + def rename(fit_file, name) + base_fit_file = File.basename(fit_file) + @activities.each do |a| + if a.fit_file == base_fit_file + a.name = name + sync + break + end + end + end + def map_to_files(query) case query when /\A-?\d+$\z/ @@ -74,7 +95,6 @@ module PostRunner # (N-1). sidx -= 1 if sidx > 0 eidx -= 1 if eidx > 0 - puts "iv: #{sidx} - #{eidx}" unless (as = @activities[sidx..eidx]).empty? files = [] as.each do |a| @@ -93,7 +113,12 @@ module PostRunner i = 0 @activities.each do |a| i += 1 - puts "#{"%4d" % i} #{"%12s" % a.fit_file} #{a.start_time}" + puts "#{'%4d' % i} " + + "#{'%-20s' % a.name[0..19]} " + + "#{'%22s' % a.start_time.strftime("%a, %Y %b %d %H:%M")} " + + "#{'%7.2f' % (a.distance / 1000)} " + + "#{'%8s' % secsToHMS(a.duration)} " + + "#{'%5s' % speedToPace(a.avg_speed)} " end end diff --git a/lib/postrunner/Activity.rb b/lib/postrunner/Activity.rb index 96c9887..964a702 100644 --- a/lib/postrunner/Activity.rb +++ b/lib/postrunner/Activity.rb @@ -1,14 +1,61 @@ require 'fit4ruby' +require 'postrunner/RuntimeConfig' module PostRunner class Activity - attr_reader :fit_file, :start_time + attr_reader :fit_file + attr_accessor :name - def initialize(fit_file, fit_activity) + # 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( start_time distance duration avg_speed ) + + def initialize(fit_file, fit_activity, name = nil) @fit_file = fit_file - @start_time = fit_activity.start_time + @fit_activity = fit_activity + @name = name || fit_file + + @@CachedVariables.each do |v| + v_str = "@#{v}" + instance_variable_set(v_str, fit_activity.send(v)) + self.class.send(:attr_reader, v.to_sym) + end + end + + def yaml_initialize(tag, value) + # Create attr_readers for cached variables. + @@CachedVariables.each { |v| self.class.send(:attr_reader, v.to_sym) } + + # Load all attributes and assign them to instance variables. + value.each do |a, v| + 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 + + def encode_with(coder) + attr_ignore = %w( @fit_activity ) + + instance_variables.each do |v| + v = v.to_s + next if attr_ignore.include?(v) + + coder[v[1..-1]] = instance_variable_get(v) + end + end + + def method_missing(method_name, *args, &block) + fit_file = File.join(Config['fit_dir'], @fit_file) + begin + @fit_activity = Fit4Ruby.read(fit_file) unless @fit_activity + rescue Fit4Ruby::Error + Log.error "Cannot read #{fit_file}: #{$!}" + return false + end + @fit_activity.send(method_name, *args, &block) end end diff --git a/lib/postrunner/Main.rb b/lib/postrunner/Main.rb index 26e1005..4e2f020 100644 --- a/lib/postrunner/Main.rb +++ b/lib/postrunner/Main.rb @@ -1,6 +1,7 @@ require 'optparse' require 'logger' require 'fit4ruby' +require 'postrunner/RuntimeConfig' require 'postrunner/ActivitiesDB' module PostRunner @@ -11,6 +12,7 @@ module PostRunner def initialize(args) @filter = nil + @name = nil @activities = ActivitiesDB.new(File.join(ENV['HOME'], '.postrunner')) execute_command(parse_options(args)) @@ -42,6 +44,18 @@ module PostRunner @filter.field_names = [] unless @filter.field_names @filter.field_names << n end + opts.on('--filter-undef', + "Don't show fields with undefined values") do + @filter = Fit4Ruby::FitFilter.new unless @filter + @filter.ignore_undef = true + end + + opts.separator "Options for the 'import' and 'rename' command:" + + opts.on('--name name', String, + 'Name or rename the activity to the specified name') do |n| + @name = n + end end parser.parse!(args) @@ -50,7 +64,7 @@ module PostRunner def execute_command(args) case args.shift when 'check' - process_files(args, :check) + process_files_or_activities(args, :check) when 'dump' @filter = Fit4Ruby::FitFilter.new unless @filter process_files_or_activities(args, :dump) @@ -58,8 +72,10 @@ module PostRunner process_files(args, :import) when 'list' @activities.list + when 'rename' + process_activities(args, :rename) when 'summary' - process_files(args, :summary) + process_files_or_activities(args, :summary) else Log.fatal("No command provided") end @@ -76,11 +92,27 @@ module PostRunner process_files(files, command) else - process_files(foa, command) + process_files([ foa ], command) end end end + def process_activities(activity_files, command) + activity_files.each do |a| + if a[0] == ':' + files = @activities.map_to_files(a[1..-1]) + if files.empty? + Log.warn "No matching activities found for '#{a}'" + return + end + process_files(files, command) + else + Log.fatal "Activity references must start with ':': #{a}" + end + end + + end + def process_files(files_or_dirs, command) if files_or_dirs.empty? Log.fatal("You must provide at least one .FIT file name") @@ -98,8 +130,11 @@ module PostRunner end def process_file(file, command) - if command == :import + case command + when :import @activities.add(file) + when :rename + @activities.rename(file, @name) else begin activity = Fit4Ruby::read(file, @filter) diff --git a/lib/postrunner/RuntimeConfig.rb b/lib/postrunner/RuntimeConfig.rb new file mode 100644 index 0000000..2d5dccb --- /dev/null +++ b/lib/postrunner/RuntimeConfig.rb @@ -0,0 +1,20 @@ +module PostRunner + + class RuntimeConfig + + def initialize + @settings = {} + @settings['data_dir'] = File.join(ENV['HOME'], '.postrunner') + @settings['fit_dir'] = File.join(@settings['data_dir'], 'fit') + end + + def [](key) + @settings[key] + end + + end + + Config = RuntimeConfig.new + +end + |