-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.rb
More file actions
executable file
·139 lines (121 loc) · 3.39 KB
/
setup.rb
File metadata and controls
executable file
·139 lines (121 loc) · 3.39 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env ruby
require 'net/http'
require 'nokogiri'
require 'cli/ui'
require 'fileutils'
class Setup
attr_reader :dir
def initialize(dir)
@dir = Dir.new(dir)
end
def days_in_year(year)
case year
when 2015..2024
25
when (2025..)
12
else
0
end
end
def run
if ARGV.any? { |arg| arg == "--all" }
dir.each.select {|year| /\d{4}/ =~ year}.map(&:to_i).sort.each do |year|
setup_year(year)
end
elsif ARGV.any?
unless ARGV.size == 2 && ARGV.first =~ /\d{4}/ && ARGV.last =~ /\d{1,2}/ && ARGV.last.to_i.between?(1, days_in_year(ARGV.first.to_i))
puts "Usage: ruby setup.rb [year day]"
exit 1
end
SetupDay.new(dir, ARGV.first.to_i, ARGV.last.to_i, http, headers, force: true).run
else
year = dir.each.select {|year| /\d{4}/ =~ year}.map(&:to_i).sort.last
setup_year(year)
end
end
def setup_year(year)
puts "Setting up #{year}:"
(1..days_in_year(year)).each do |day|
SetupDay.new(dir, year, day, http, headers).run
end
end
def headers
@headers ||= {
'Cookie' => File.read(File.join(dir, 'cookies')).chomp,
'User-Agent' => 'https://github.com/lugray/advent_of_code/blob/main/setup.rb by lisa.ugray@gmail.com',
}
end
def http
@http ||= Net::HTTP.start('adventofcode.com', 443, use_ssl: true)
end
end
class SetupDay
attr_reader :dir, :year, :day, :http, :headers
def initialize(dir, year, day, http, headers, force: false)
@dir = dir
@day = day
@year = year
@http = http
@headers = headers
@force = force
end
def run
return if Time.new(year, 12, day) > Time.now && !@force # Don't generate for future days
unless File.exist?(input_file)
print_day
puts " Input"
resp = http.get("/#{year}/day/#{day}/input", headers)
File.write(input_file, resp.body)
end
unless File.exist?(example_input_file)
FileUtils.touch(example_input_file)
print_day
puts " Example Input"
resp = http.get("/#{year}/day/#{day}", headers)
document = Nokogiri::HTML.parse(resp.body)
document.css('pre code').each_with_index do |code, i|
File.write(example_input_file(i), code.text)
end
end
return if Time.new(year, 12, 30) < Time.now && !@force # Don't generate for previous years
unless File.exist?(day_file)
print_day
puts " Template"
File.write(day_file, File.read(template_file).gsub('###', day.to_s.rjust(2, '0')))
File.chmod(0755, day_file)
end
end
def print_day
return if @printed_day
puts "Day #{day}, #{year}"
@printed_day = true
end
def puts(str)
@last_start_color ||= 'green'
@color = @last_start_color
CLI::UI.puts(str.scan(/( +|[^ ]+)/).flatten.map do |word|
next word if word =~ /\s/
@color = flip_color(@color)
"{{#{@color}:#{word}}}"
end.join)
@last_start_color = flip_color(@last_start_color)
end
def flip_color(color)
color == 'green' ? 'red' : 'green'
end
def input_file
File.join(dir, year.to_s, sprintf('day%02d.input', day))
end
def example_input_file(i = 0)
suffix = i == 0 ? '' : ".#{i}"
File.join(dir, year.to_s, sprintf("day%02d.example#{suffix}", day))
end
def day_file
File.join(dir, year.to_s, sprintf('day%02d.rb', day))
end
def template_file
File.join(dir, 'day_template.rb')
end
end
Setup.new(__dir__).run