Class: GTFS::Meta::FeedManager

Inherits:
Object
  • Object
show all
Defined in:
lib/gtfs/meta/workers/feed_manager.rb

Defined Under Namespace

Classes: EtagError, FeedFileExists, FeedFileExtractionError, InvalidEntryName, LastModifiedError, SourceExtractionError, SourceRemovalError

Constant Summary collapse

FEED_FILE_NAMES =
GTFS::Source::ENTITIES.map{|e| e.name == "Agency" ? e.singular_name.to_s.concat(".txt") : e.name.to_s.concat(".txt")}

Class Method Summary collapse

Class Method Details

.perform(options = {}) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/gtfs/meta/workers/feed_manager.rb', line 6

def self.perform(options = {})
  feeds = options[:feeds] || GTFS::Meta::Feed.all

  feeds.find_each do |feed|
    begin
      # CHECK VERSION

      uri = URI.parse(feed.source_url)
      response = Net::HTTP.get_response(uri)
      etag = response.to_hash["etag"].first.gsub!(/[^0-9A-Za-z]/, '')
      last_modified_at = response.to_hash["last-modified"].first.try(:to_datetime)

      raise EtagError.new(etag) unless etag.is_a?(String)
      raise LastModifiedError.new(last_modified_at) unless last_modified_at.is_a?(DateTime)
      feed_version = GTFS::Meta::FeedVersion.where({
        :feed_id => feed.id,
        :etag => etag,
        :last_modified_at => last_modified_at
      }).first_or_create
      feed_version_check = GTFS::Meta::FeedVersionCheck.create({
        :feed_version_id => feed_version.id,
        :status => "IN PROGRESS"
      })

      # MANAGE FILES

      FileUtils.mkdir_p(feed_version.destination_path)

      zip_destination_path = "#{feed_version.destination_path}/#{feed.source_file_name}"
      unless File.exist?(zip_destination_path)
        File.open(zip_destination_path, "wb") do |zip_file|
          zip_file.write response.body
        end
        raise SourceExtractionError.new(zip_destination_path) unless File.exist?(zip_destination_path)
      end

      Zip::File.open(zip_destination_path) do |zip_file|
        zip_file.each do |entry|
          begin
            entry_name = entry.name
            raise InvalidEntryName.new(entry_name) unless FEED_FILE_NAMES.include?(entry_name)
            feed_version.file_names << entry_name unless feed_version.file_names.include?(entry_name)

            feed_file_path = "#{feed_version.destination_path}/#{entry_name}"
            raise FeedFileExists.new(feed_file_path) if File.exist?(feed_file_path)

            entry.extract(feed_file_path)
            raise FeedFileExtractionError.new(feed_file_path) unless File.exist?(feed_file_path)
          rescue InvalidEntryName => e
            next
          rescue FeedFileExists => e
            next
          end
        end
      end

      FileUtils.rm(zip_destination_path)
      raise SourceRemovalError.new(zip_destination_path) if File.exist?(zip_destination_path)

      feed_version.save!
      feed_version_check.update_attributes(:status => "SUCCESS")
    rescue => e
      puts "#{e.class} -- #{e.message}"
      feed_version_check.update_attributes(:status => "FAILURE") if feed_version_check
    end
  end
end