summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2017-11-11 22:05:12 +0100
committerChris Schlaeger <chris@linux.com>2017-11-11 22:05:12 +0100
commit30f754df20e08dd8162cdf5b0df54fba037a719e (patch)
tree79dc042e3b708a9953ac8d45fa41b0d6cd230472 /lib
parentd3c9294451b0a3c2e47fbf9ce10ed245394babac (diff)
downloadpostrunner-30f754df20e08dd8162cdf5b0df54fba037a719e.zip
New: Store hash of imported FIT files to speed up import
Garmin devices typically keep older activity FIT files on the device. Parsing a FIT file can be costly at scale. Postrunner now stores the MD5 sums of recently importet files and checks against that list before parsing the FIT file.
Diffstat (limited to 'lib')
-rw-r--r--lib/postrunner/FFS_Device.rb7
-rw-r--r--lib/postrunner/FitFileStore.rb18
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/postrunner/FFS_Device.rb b/lib/postrunner/FFS_Device.rb
index 06e1fc8..6ea6890 100644
--- a/lib/postrunner/FFS_Device.rb
+++ b/lib/postrunner/FFS_Device.rb
@@ -93,6 +93,13 @@ module PostRunner
entities << entity
entities.sort!
+ md5sums = @store['fit_file_md5sums']
+ md5sums << FitFileStore.calc_md5_sum(fit_file_name)
+ # We only store the 512 most recently added FIT files. This should be
+ # more than a device can store. This will allow us to skip the already
+ # imported FIT files quickly instead of having to parse them each time.
+ md5sums.shift if md5sums.length > 512
+
# Scan the activity for any potential new personal records and register
# them.
if entity.is_a?(FFS_Activity)
diff --git a/lib/postrunner/FitFileStore.rb b/lib/postrunner/FitFileStore.rb
index 981da6d..6ee484f 100644
--- a/lib/postrunner/FitFileStore.rb
+++ b/lib/postrunner/FitFileStore.rb
@@ -10,6 +10,7 @@
# published by the Free Software Foundation.
#
+require 'digest'
require 'fit4ruby'
require 'perobs'
@@ -54,6 +55,9 @@ module PostRunner
# safely to another directory.
@store['config']['devices_dir'] = @devices_dir
create_directory(@devices_dir, 'devices')
+ unless @store['fit_file_md5sums']
+ @store['fit_file_md5sums'] = @store.new(PEROBS::Array)
+ end
# Define which View objects the HTML output will consist of. This
# doesn't really belong in this class but for now it's the best place
@@ -76,6 +80,12 @@ module PostRunner
# @return [FFS_Activity or FFS_Monitoring] Corresponding entry in the
# FitFileStore or nil if file could not be added.
def add_fit_file(fit_file_name, fit_entity = nil, overwrite = false)
+ md5sum = FitFileStore.calc_md5_sum(fit_file_name)
+ if @store['fit_file_md5sums'].include?(md5sum)
+ # The FIT file is already stored in the DB.
+ return nil unless overwrite
+ end
+
# If we the file hasn't been read yet, read it in as a
# Fit4Ruby::Activity or Fit4Ruby::Monitoring entity.
unless fit_entity
@@ -420,6 +430,14 @@ module PostRunner
puts MonitoringStatistics.new(monitoring_files).monthly(day)
end
+ def FitFileStore::calc_md5_sum(file_name)
+ begin
+ Digest::MD5.hexdigest File.read(file_name)
+ rescue IOError
+ return 0
+ end
+ end
+
private
def read_fit_file(fit_file_name)