From ee458b6ee25b9a34ca0cb9841b17b6e155ebcc87 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Tue, 11 Jun 2019 12:57:00 +0100 Subject: [PATCH] Parse each GPX file in an archive separately Fixes #2253 --- Gemfile | 3 +++ Gemfile.lock | 7 +++++++ app/models/trace.rb | 2 +- lib/gpx.rb | 35 ++++++++++++++++++++++++----------- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index dc1615ffc..0e02c2311 100644 --- a/Gemfile +++ b/Gemfile @@ -118,6 +118,9 @@ gem "canonical-rails" gem "logstasher" # Used to generate images for traces +gem "mimemagic" +gem "ffi-libarchive" +gem "bzip2-ffi" gem "gd2-ffij", ">= 0.4.0" # Used for browser detection diff --git a/Gemfile.lock b/Gemfile.lock index 479818938..f9a0af7d4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,6 +79,8 @@ GEM msgpack (~> 1.0) browser (2.5.3) builder (3.2.3) + bzip2-ffi (1.0.0) + ffi (~> 1.0) cancancan (3.0.1) canonical-rails (0.2.5) rails (>= 4.1, < 6.1) @@ -177,6 +179,8 @@ GEM faraday (0.15.4) multipart-post (>= 1.2, < 3) ffi (1.11.1) + ffi-libarchive (0.4.6) + ffi (~> 1.0) fspath (3.1.1) gd2-ffij (0.4.0) ffi (>= 1.0.0) @@ -455,6 +459,7 @@ DEPENDENCIES binding_of_caller bootsnap (>= 1.1.0) browser + bzip2-ffi cancancan canonical-rails capybara (~> 2.13) @@ -471,6 +476,7 @@ DEPENDENCIES factory_bot_rails fakefs faraday + ffi-libarchive gd2-ffij (>= 0.4.0) geoip htmlentities @@ -485,6 +491,7 @@ DEPENDENCIES libxml-ruby (>= 2.0.5) listen logstasher + mimemagic minitest (~> 5.1) oauth-plugin (>= 0.5.1) omniauth diff --git a/app/models/trace.rb b/app/models/trace.rb index 7c97b4e96..9d710d1ce 100644 --- a/app/models/trace.rb +++ b/app/models/trace.rb @@ -275,7 +275,7 @@ class Trace < ActiveRecord::Base def import logger.info("GPX Import importing #{name} (#{id}) from #{user.email}") - gpx = ::GPX::File.new(xml_file) + gpx = ::GPX::File.new(trace_name) f_lat = 0 f_lon = 0 diff --git a/lib/gpx.rb b/lib/gpx.rb index 1b1c17ac7..068b84815 100644 --- a/lib/gpx.rb +++ b/lib/gpx.rb @@ -12,17 +12,7 @@ module GPX @file = file end - def points - return enum_for(:points) unless block_given? - - @possible_points = 0 - @actual_points = 0 - @tracksegs = 0 - - @file.rewind - - reader = XML::Reader.io(@file) - + def parse_file(reader) point = nil while reader.read @@ -47,6 +37,29 @@ module GPX end end + def points(&block) + return enum_for(:points) unless block_given? + + @possible_points = 0 + @actual_points = 0 + @tracksegs = 0 + + begin + Archive::Reader.open_filename(@file).each_entry_with_data do |_entry, data| + parse_file(XML::Reader.string(data), &block) + end + rescue Archive::Error + io = ::File.open(@file) + + case MimeMagic.by_magic(io).type + when "application/gzip" then io = Zlib::GzipReader.open(@file) + when "application/x-bzip" then io = Bzip2::FFI::Reader.open(@file) + end + + parse_file(XML::Reader.io(io), &block) + end + end + def picture(min_lat, min_lon, max_lat, max_lon, num_points) nframes = 10 width = 250 -- 2.43.2