app/models/import.rb in reso-0.1.3.0 vs app/models/import.rb in reso-0.1.3.1

- old
+ new

@@ -1,7 +1,8 @@ class Import < ActiveRecord::Base + require 'nokogiri' require 'open-uri' require 'open_uri_redirections' before_save :set_import_format belongs_to :import_format @@ -32,6 +33,103 @@ def new_source_data_exists? self.source_data_modified.eql? self.source_url_last_modified ? false : true end + def run_import + if self.status == 'active' + unless self.new_source_data_exists? + self.update_attribute(:status, :running) + source_data_modified = self.source_url_last_modified + l, count, found_listing_keys, stream = 0, 0, [], '' + open_tag, close_tag = get_open_and_closing_tag_for self.repeating_element + + # Grab a file to work with + filepath = download_feed_to_import self + filepath = uncompress_and_return_new_filepath(filepath) if filepath.split('.').last.downcase == 'gz' + + # Grab the XML header to avoid namespace errors later + xml_header = get_xml_header filepath, self.repeating_element + + start_time = Time.now + import_result = ImportResult.create(import: self, start_time: start_time) + File.foreach(filepath) do |line| + stream += line + while (from_here = stream.index(open_tag)) && (to_there = stream.index(close_tag)) + xml = stream[from_here..to_there + (close_tag.length-1)] + doc = Nokogiri::XML([xml_header, xml].join).remove_namespaces! + found_listing_keys << create_queued_listing_and_return_listing_key(doc, self) + stream.gsub!(xml, '') + end + end + end_time = Time.now + removed_listing_keys = self.remove_listings_not_present(found_listing_keys) + import_result.assign_attributes({ + end_time: end_time, + found_listing_keys: found_listing_keys, + removed_listing_keys: removed_listing_keys.inspect + }) + import_result.save + self.update_attribute(:status, :active) + self.update_attribute(:source_data_modified, source_data_modified) + File.delete(filepath) + end + end + end + + def download_feed_to_import import + filename = import.source_url.split('/').last + filepath = Rails.root.join('tmp', filename).to_s + File.delete(filepath) if File.file? filepath + open(filepath, 'wb') do |file| + file << open(import.source_url, + http_basic_authentication: [import.source_user, import.source_pass], + allow_redirections: :all + ).read + end + filepath + end + + def get_open_and_closing_tag_for repeating_element + ApplicationController.helpers.content_tag(repeating_element, "\n").split + end + + def get_xml_header filepath, repeating_element + stream = '' + open_tag = get_open_and_closing_tag_for(repeating_element).first + File.foreach(filepath) do |line| + stream += line + pos = stream.index(open_tag) + return stream[0..pos-1] if pos + end + nil # Just in cases + end + + def create_queued_listing_and_return_listing_key doc, import + begin + doc.css(import.repeating_element).each do |o| + listing_data = {} + Hash.from_xml(o.to_xml)[import.repeating_element].each_pair{|key, value| listing_data[key] = value } + queued_listing = QueuedListing.new(import: import, listing_data: listing_data) + queued_listing.save + return Mapper::unique_identifier(queued_listing) + end + rescue Exception => e + puts e.inspect + exit if Rails.env.development? + return nil + end + end + + def uncompress_and_return_new_filepath filepath + output_path = [filepath, '.xml'].join + File.delete(output_path) if File.file? output_path + Zlib::GzipReader.open(filepath) do |gz| + File.open(output_path, "w") do |g| + IO.copy_stream(gz, g) + end + end + File.delete(filepath) + output_path + end + end