-
Notifications
You must be signed in to change notification settings - Fork 0
/
xml_data_feed.rb
79 lines (68 loc) · 2.66 KB
/
xml_data_feed.rb
1
2
3
4
5
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
73
74
75
76
77
78
79
require "json"
require "open-uri"
require "active_support"
require "active_support/core_ext/array"
require "active_support/core_ext/hash"
require "active_support/core_ext/date"
require "net/sftp"
require "stringio"
class XmlDataFeed
def initialize(opts = {date: Date.today})
@date = Date.parse opts[:date]
# TODO: Read these out of the .env-example
%w{API_ENDPOINT API_KEY SFTP_HOST SFTP_USERNAME SFTP_PASSWORD}.each do |c|
raise "Missing configuration: #{c}" if ENV[c].nil?
end
end
def api_url(date_scraped, page = 1)
"#{ENV["API_ENDPOINT"]}?v=2&key=#{ENV["API_KEY"]}&date_scraped=#{date_scraped}&page=#{page}"
end
def applications_on_date(date)
puts "Collecting applications for #{date}..."
first_page = JSON.parse(open(api_url(date)).read)
applications = first_page["applications"].map { |a| a["application"] }
(first_page["page_count"] - 1).times do |t|
page = t + 2
puts "Page #{page}..."
applications += JSON.parse(open(api_url(date, page)).read)["applications"].map { |a| a["application"] }
end
applications
end
# Returns all applications from the calendar week of the date specified as XML
def calendar_week_applications
puts "Collecting applications for #{year}, week #{@date.cweek}..."
raise "This week ain't over! It would result in a partial file, so stopping" if @date.end_of_week >= Date.today
applications = []
(@[email protected]_of_week).each do |d|
applications += applications_on_date(d)
end
puts "Collected #{applications.count} applications."
as_xml applications
end
def as_xml(applications)
applications.to_xml(root: "applications", skip_types: true, dasherize: false)
end
def transfer_applications
applications = calendar_week_applications
puts "Connecting to #{ENV["SFTP_HOST"]}..."
Net::SFTP.start(ENV["SFTP_HOST"], ENV["SFTP_USERNAME"], password: ENV["SFTP_PASSWORD"], port: (ENV["SFTP_PORT"] || 22), compression: true) do |sftp|
# Ignore StatusException since it's also used when there's already a directory
sftp.mkdir! "#{year}" rescue Net::SFTP::StatusException
puts "Uploading applications..."
# Workaround NET::SFTP file.open not supporting upload of UTF-8
io = StringIO.new(applications)
sftp.upload!(io, "#{year}/planningalerts_#{year}-week#{@date.cweek}.xml")
puts "Transfer complete."
end
end
# If this day is right at the start or end of a year then it might be part of next year
def year
if @date.cweek == 1 && @date.month == 12
@date.year + 1
elsif @date.cweek == 52 && @date.month == 1
@date.year - 1
else
@date.year
end
end
end