aoc_cli 0.2.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.rubocop.yml +88 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +187 -0
- data/README.md +88 -282
- data/Rakefile +9 -2
- data/Steepfile +13 -0
- data/aoc_cli.gemspec +36 -26
- data/db/migrate/1_create_events.rb +14 -0
- data/db/migrate/2_create_puzzles.rb +21 -0
- data/db/migrate/3_create_stats.rb +19 -0
- data/db/migrate/4_create_attempts.rb +19 -0
- data/db/migrate/5_create_locations.rb +17 -0
- data/db/migrate/6_create_puzzle_dir_sync_logs.rb +18 -0
- data/db/migrate/7_create_progresses.rb +17 -0
- data/db/migrate/8_remove_legacy_timestamps.rb +8 -0
- data/exe/aoc +5 -0
- data/lib/aoc_cli/components/attempts_table.erb +5 -0
- data/lib/aoc_cli/components/attempts_table.rb +58 -0
- data/lib/aoc_cli/components/docs_component.erb +19 -0
- data/lib/aoc_cli/components/docs_component.rb +41 -0
- data/lib/aoc_cli/components/errors_component.erb +8 -0
- data/lib/aoc_cli/components/errors_component.rb +36 -0
- data/lib/aoc_cli/components/progress_table.erb +1 -0
- data/lib/aoc_cli/components/progress_table.rb +43 -0
- data/lib/aoc_cli/components/puzzle_sync_component.erb +2 -0
- data/lib/aoc_cli/components/puzzle_sync_component.rb +26 -0
- data/lib/aoc_cli/configurators/session_configurator.rb +7 -0
- data/lib/aoc_cli/controllers/application_controller.rb +27 -0
- data/lib/aoc_cli/controllers/concerns/error_concern.rb +17 -0
- data/lib/aoc_cli/controllers/concerns/location_concern.rb +79 -0
- data/lib/aoc_cli/controllers/default_controller.rb +9 -0
- data/lib/aoc_cli/controllers/event_controller.rb +35 -0
- data/lib/aoc_cli/controllers/help/event_controller.rb +11 -0
- data/lib/aoc_cli/controllers/help/puzzle_controller.rb +13 -0
- data/lib/aoc_cli/controllers/puzzle_controller.rb +39 -0
- data/lib/aoc_cli/core/attempt_parser.rb +69 -0
- data/lib/aoc_cli/core/processor.rb +32 -0
- data/lib/aoc_cli/core/repository.rb +74 -0
- data/lib/aoc_cli/core/request.rb +37 -0
- data/lib/aoc_cli/core/resource.rb +39 -0
- data/lib/aoc_cli/core/stats_parser.rb +43 -0
- data/lib/aoc_cli/helpers/table_generator.rb +64 -0
- data/lib/aoc_cli/helpers/view_helper.rb +35 -0
- data/lib/aoc_cli/models/attempt.rb +67 -0
- data/lib/aoc_cli/models/event.rb +9 -0
- data/lib/aoc_cli/models/location.rb +24 -0
- data/lib/aoc_cli/models/progress.rb +33 -0
- data/lib/aoc_cli/models/puzzle.rb +28 -0
- data/lib/aoc_cli/models/puzzle_dir_sync_log.rb +14 -0
- data/lib/aoc_cli/models/stats.rb +43 -0
- data/lib/aoc_cli/presenters/attempt_presenter.rb +29 -0
- data/lib/aoc_cli/presenters/puzzle_presenter.rb +29 -0
- data/lib/aoc_cli/presenters/stats_presenter.rb +32 -0
- data/lib/aoc_cli/processors/event_initialiser.rb +64 -0
- data/lib/aoc_cli/processors/progress_syncer.rb +48 -0
- data/lib/aoc_cli/processors/puzzle_dir_synchroniser.rb +80 -0
- data/lib/aoc_cli/processors/puzzle_initialiser.rb +106 -0
- data/lib/aoc_cli/processors/puzzle_refresher.rb +27 -0
- data/lib/aoc_cli/processors/resource_attacher.rb +22 -0
- data/lib/aoc_cli/processors/solution_poster.rb +72 -0
- data/lib/aoc_cli/processors/stats_initialiser.rb +36 -0
- data/lib/aoc_cli/processors/stats_refresher.rb +23 -0
- data/lib/aoc_cli/validators/collection_type_validator.rb +57 -0
- data/lib/aoc_cli/validators/event_year_validator.rb +42 -0
- data/lib/aoc_cli/validators/included_validator.rb +21 -0
- data/lib/aoc_cli/validators/integer_validator.rb +32 -0
- data/lib/aoc_cli/validators/path_validator.rb +39 -0
- data/lib/aoc_cli/validators/type_validator.rb +54 -0
- data/lib/aoc_cli/version.rb +1 -1
- data/lib/aoc_cli/views/event/attach.erb +3 -0
- data/lib/aoc_cli/views/event/init.erb +3 -0
- data/lib/aoc_cli/views/help/event/attach.erb +32 -0
- data/lib/aoc_cli/views/help/event/init.erb +38 -0
- data/lib/aoc_cli/views/help/event/progress.erb +12 -0
- data/lib/aoc_cli/views/help/puzzle/attempts.erb +12 -0
- data/lib/aoc_cli/views/help/puzzle/init.erb +31 -0
- data/lib/aoc_cli/views/help/puzzle/solve.erb +33 -0
- data/lib/aoc_cli/views/help/puzzle/sync.erb +32 -0
- data/lib/aoc_cli/views/puzzle/init.erb +3 -0
- data/lib/aoc_cli/views/puzzle/solve.erb +10 -0
- data/lib/aoc_cli.rb +36 -16
- data/rbs_collection.lock.yaml +168 -0
- data/rbs_collection.yaml +28 -0
- data/sig/aoc_cli/components/attempts_table.rbs +29 -0
- data/sig/aoc_cli/components/docs_component.rbs +15 -0
- data/sig/aoc_cli/components/errors_component.rbs +19 -0
- data/sig/aoc_cli/components/progress_table.rbs +28 -0
- data/sig/aoc_cli/components/puzzle_sync_component.rbs +19 -0
- data/sig/aoc_cli/configurators/session_configurator.rbs +7 -0
- data/sig/aoc_cli/controllers/application_controller.rbs +12 -0
- data/sig/aoc_cli/controllers/concerns/error_concern.rbs +9 -0
- data/sig/aoc_cli/controllers/concerns/location_concern.rbs +35 -0
- data/sig/aoc_cli/controllers/default_controller.rbs +7 -0
- data/sig/aoc_cli/controllers/event_controller.rbs +18 -0
- data/sig/aoc_cli/controllers/help/event_controller.rbs +11 -0
- data/sig/aoc_cli/controllers/help/puzzle_controller.rbs +13 -0
- data/sig/aoc_cli/controllers/puzzle_controller.rbs +15 -0
- data/sig/aoc_cli/core/attempt_parser.rbs +41 -0
- data/sig/aoc_cli/core/processor.rbs +25 -0
- data/sig/aoc_cli/core/repository.rbs +25 -0
- data/sig/aoc_cli/core/request.rbs +29 -0
- data/sig/aoc_cli/core/resource.rbs +25 -0
- data/sig/aoc_cli/core/stats_parser.rbs +23 -0
- data/sig/aoc_cli/helpers/table_generator.rbs +36 -0
- data/sig/aoc_cli/helpers/view_helper.rbs +15 -0
- data/sig/aoc_cli/models/attempt.rbs +35 -0
- data/sig/aoc_cli/models/event.rbs +17 -0
- data/sig/aoc_cli/models/location.rbs +19 -0
- data/sig/aoc_cli/models/progress.rbs +21 -0
- data/sig/aoc_cli/models/puzzle.rbs +27 -0
- data/sig/aoc_cli/models/puzzle_dir_sync_log.rbs +11 -0
- data/sig/aoc_cli/models/stats.rbs +53 -0
- data/sig/aoc_cli/presenters/attempt_presenter.rbs +13 -0
- data/sig/aoc_cli/presenters/puzzle_presenter.rbs +19 -0
- data/sig/aoc_cli/presenters/stats_presenter.rbs +19 -0
- data/sig/aoc_cli/processors/event_initialiser.rbs +26 -0
- data/sig/aoc_cli/processors/progress_syncer.rbs +29 -0
- data/sig/aoc_cli/processors/puzzle_dir_synchroniser.rbs +40 -0
- data/sig/aoc_cli/processors/puzzle_initialiser.rbs +41 -0
- data/sig/aoc_cli/processors/puzzle_refresher.rbs +21 -0
- data/sig/aoc_cli/processors/resource_attacher.rbs +16 -0
- data/sig/aoc_cli/processors/solution_poster.rbs +34 -0
- data/sig/aoc_cli/processors/stats_initialiser.rbs +15 -0
- data/sig/aoc_cli/processors/stats_refresher.rbs +19 -0
- data/sig/aoc_cli/validators/collection_type_validator.rbs +24 -0
- data/sig/aoc_cli/validators/event_year_validator.rbs +19 -0
- data/sig/aoc_cli/validators/included_validator.rbs +11 -0
- data/sig/aoc_cli/validators/integer_validator.rbs +15 -0
- data/sig/aoc_cli/validators/path_validator.rbs +17 -0
- data/sig/aoc_cli/validators/type_validator.rbs +22 -0
- data/sig/aoc_cli.rbs +6 -0
- data/sig/http.rbs +3 -0
- data/sig/kangaru.rbs +5 -0
- data/sig/nokogiri.rbs +3 -0
- data/sig/reverse_markdown.rbs +3 -0
- metadata +149 -34
- data/.gitignore +0 -5
- data/bin/aoc +0 -4
- data/bin/console +0 -15
- data/bin/setup +0 -7
- data/lib/aoc_cli/commands.rb +0 -232
- data/lib/aoc_cli/database.rb +0 -224
- data/lib/aoc_cli/day.rb +0 -124
- data/lib/aoc_cli/db/reddit.db +0 -0
- data/lib/aoc_cli/errors.rb +0 -275
- data/lib/aoc_cli/files.rb +0 -163
- data/lib/aoc_cli/help.rb +0 -77
- data/lib/aoc_cli/interface.rb +0 -81
- data/lib/aoc_cli/paths.rb +0 -101
- data/lib/aoc_cli/solve.rb +0 -104
- data/lib/aoc_cli/tables.rb +0 -138
- data/lib/aoc_cli/tools.rb +0 -120
- data/lib/aoc_cli/year.rb +0 -116
- data/sample/aoc.rc +0 -21
data/lib/aoc_cli/solve.rb
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
module AocCli
|
|
2
|
-
module Solve
|
|
3
|
-
CORRECT = "That's the right answer"
|
|
4
|
-
INCORRECT = "That's not the right answer"
|
|
5
|
-
WAIT = "You gave an answer too recently"
|
|
6
|
-
class Attempt
|
|
7
|
-
attr_reader :user, :year, :day, :part, :answer
|
|
8
|
-
def initialize(u:Metafile.get(:user),
|
|
9
|
-
y:Metafile.get(:year),
|
|
10
|
-
d:Metafile.get(:day),
|
|
11
|
-
p:Metafile.get(:part), a:)
|
|
12
|
-
@user = Validate.user(u)
|
|
13
|
-
@year = Validate.year(y)
|
|
14
|
-
@day = Validate.day(d)
|
|
15
|
-
@part = Validate.part(p)
|
|
16
|
-
@answer = Validate.ans(attempt:self, ans:a)
|
|
17
|
-
end
|
|
18
|
-
def exists?
|
|
19
|
-
Database::Attempt.new(attempt:self)
|
|
20
|
-
end
|
|
21
|
-
def raw
|
|
22
|
-
@raw ||= Tools::Post.new(u:user, y:year, d:day,
|
|
23
|
-
data:{level:part, answer:answer}).plain
|
|
24
|
-
end
|
|
25
|
-
def check
|
|
26
|
-
case raw
|
|
27
|
-
when /#{CORRECT}/ then :Correct
|
|
28
|
-
when /#{INCORRECT}/ then :Incorrect
|
|
29
|
-
when /#{WAIT}/ then :Wait
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
def respond
|
|
33
|
-
Respond.const_get(check)
|
|
34
|
-
.new(attempt:self)
|
|
35
|
-
.respond
|
|
36
|
-
.react
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
module Respond
|
|
40
|
-
class Response
|
|
41
|
-
attr_reader :attempt
|
|
42
|
-
def initialize(attempt:)
|
|
43
|
-
@attempt = attempt
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
class Correct < Response
|
|
47
|
-
def react
|
|
48
|
-
Database.correct(attempt:attempt)
|
|
49
|
-
Year.refresh
|
|
50
|
-
Day.refresh(files:[:Puzzle])
|
|
51
|
-
end
|
|
52
|
-
def respond
|
|
53
|
-
puts <<~response
|
|
54
|
-
#{"Correct!".bold.green} #{
|
|
55
|
-
case attempt.part
|
|
56
|
-
when "1" then "Downloading part two..."
|
|
57
|
-
when "2" then "This day is now complete!".green
|
|
58
|
-
end }
|
|
59
|
-
response
|
|
60
|
-
self
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
class Incorrect < Response
|
|
64
|
-
def react
|
|
65
|
-
Database::Attempt
|
|
66
|
-
.new(attempt:attempt)
|
|
67
|
-
.incorrect(high:high, low:low)
|
|
68
|
-
end
|
|
69
|
-
def respond
|
|
70
|
-
puts <<~response
|
|
71
|
-
#{"Incorrect".red.bold}: You guessed - #{attempt
|
|
72
|
-
.answer.to_s.red} #{
|
|
73
|
-
high ? "(too high)" :
|
|
74
|
-
low ? "(too low)" : ""}
|
|
75
|
-
#{"Please wait".yellow} #{wait_time} before answering again
|
|
76
|
-
response
|
|
77
|
-
self
|
|
78
|
-
end
|
|
79
|
-
def high
|
|
80
|
-
/too high/.match?(attempt.raw)
|
|
81
|
-
end
|
|
82
|
-
def low
|
|
83
|
-
/too low/.match?(attempt.raw)
|
|
84
|
-
end
|
|
85
|
-
def wait_time
|
|
86
|
-
attempt.raw.scan(/(?:(one minute|\d+ minutes))/)
|
|
87
|
-
.first.first.to_s
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
class Wait < Response
|
|
91
|
-
def respond
|
|
92
|
-
puts <<~response
|
|
93
|
-
#{"Please wait".yellow.bold}: #{time.to_s}
|
|
94
|
-
response
|
|
95
|
-
self
|
|
96
|
-
end
|
|
97
|
-
def time
|
|
98
|
-
attempt.raw.scan(/(?:\d+m\s)?\d+s/).first.to_s
|
|
99
|
-
end
|
|
100
|
-
def react; end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
data/lib/aoc_cli/tables.rb
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
module AocCli
|
|
2
|
-
module Tables
|
|
3
|
-
class Table
|
|
4
|
-
require 'terminal-table'
|
|
5
|
-
attr_reader :user, :year, :table, :cols, :where
|
|
6
|
-
def initialize(u:Metafile.get(:user), y:Metafile.get(:year))
|
|
7
|
-
@user = Validate.user(u)
|
|
8
|
-
@year = Validate.year(y)
|
|
9
|
-
end
|
|
10
|
-
def border
|
|
11
|
-
Prefs.bool(key:"unicode_tables") ? :unicode : :ascii
|
|
12
|
-
end
|
|
13
|
-
def data
|
|
14
|
-
Database::Query
|
|
15
|
-
.new(path:Paths::Database.cfg(user))
|
|
16
|
-
.select(t:table, cols:cols, where:where)
|
|
17
|
-
end
|
|
18
|
-
def print
|
|
19
|
-
puts rows.count > 0 ? make : nil_message
|
|
20
|
-
end
|
|
21
|
-
def make
|
|
22
|
-
tab = Terminal::Table.new(
|
|
23
|
-
:headings => headings,
|
|
24
|
-
:rows => rows,
|
|
25
|
-
:title => title)
|
|
26
|
-
tab.style = {
|
|
27
|
-
:border => border,
|
|
28
|
-
:alignment => :center}
|
|
29
|
-
tab
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
class Attempts < Table
|
|
33
|
-
attr_reader :day, :part
|
|
34
|
-
def initialize(u:Metafile.get(:user),
|
|
35
|
-
y:Metafile.get(:year),
|
|
36
|
-
d:Metafile.get(:day),
|
|
37
|
-
p:Metafile.get(:part))
|
|
38
|
-
super(u:u, y:y)
|
|
39
|
-
@day = Validate.day(d)
|
|
40
|
-
@part = Validate.part(p)
|
|
41
|
-
@table = :attempts
|
|
42
|
-
@cols = "time, answer, high, low, correct"
|
|
43
|
-
@where = {year:year, day:day, part:part}
|
|
44
|
-
end
|
|
45
|
-
def title
|
|
46
|
-
"#{year} - Day #{day}:#{part}".bold
|
|
47
|
-
end
|
|
48
|
-
def headings
|
|
49
|
-
["Answer", "Time", "Hint"]
|
|
50
|
-
end
|
|
51
|
-
def rows
|
|
52
|
-
@rows ||= data.map do |d|
|
|
53
|
-
[parse_ans(d), parse_time(d), parse_hint(d)]
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
def parse_ans(row)
|
|
57
|
-
row[4] == 1 ? row[1].to_s.green : row[1].to_s.red
|
|
58
|
-
end
|
|
59
|
-
def parse_time(row)
|
|
60
|
-
DateTime.strptime(row[0], "%Y-%m-%d %H:%M:%S %Z")
|
|
61
|
-
.strftime("%H:%M - %d/%m/%y")
|
|
62
|
-
end
|
|
63
|
-
def parse_hint(row)
|
|
64
|
-
row[3] == 1 ? "low" :
|
|
65
|
-
row[2] == 1 ? "high" : "-"
|
|
66
|
-
end
|
|
67
|
-
def nil_message
|
|
68
|
-
"You have not attempted part #{part} yet!"
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
module Stats
|
|
72
|
-
class Year < Table
|
|
73
|
-
def initialize(u:Metafile.get(:user),
|
|
74
|
-
y:Metafile.get(:year))
|
|
75
|
-
super(u:u, y:y)
|
|
76
|
-
@table = :stats
|
|
77
|
-
@cols = "day, part, attempts, elapsed"
|
|
78
|
-
@where = {year:"'#{year}'", correct:"'1'"}
|
|
79
|
-
end
|
|
80
|
-
def title
|
|
81
|
-
"Year #{year}"
|
|
82
|
-
end
|
|
83
|
-
def headings
|
|
84
|
-
["Day", "Part", "Attempts", "Time (h:m:s)"]
|
|
85
|
-
end
|
|
86
|
-
def rows
|
|
87
|
-
@rows ||= data.map{|d| [d[0], d[1], d[2], d[3]]}
|
|
88
|
-
end
|
|
89
|
-
def nil_message
|
|
90
|
-
"You have not completed any puzzles yet"
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
class Day < Year
|
|
94
|
-
attr_reader :day
|
|
95
|
-
def initialize(u:Metafile.get(:user),
|
|
96
|
-
y:Metafile.get(:year),
|
|
97
|
-
d:Metafile.get(:day))
|
|
98
|
-
super(u:u, y:y)
|
|
99
|
-
@day = Validate.day(d)
|
|
100
|
-
@cols = "part, attempts, elapsed"
|
|
101
|
-
@where = { year:"'#{year}'",
|
|
102
|
-
day:"'#{day}'",
|
|
103
|
-
correct:"'1'" }
|
|
104
|
-
end
|
|
105
|
-
def title
|
|
106
|
-
"Year #{year}: Day #{day}"
|
|
107
|
-
end
|
|
108
|
-
def headings
|
|
109
|
-
["Part", "Attempts", "Time (h:m:s)"]
|
|
110
|
-
end
|
|
111
|
-
def rows
|
|
112
|
-
@rows ||= data.map{|d| [d[0], d[1], d[2]]}
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
class Calendar < Table
|
|
117
|
-
def initialize(u:Metafile.get(:user),
|
|
118
|
-
y:Metafile.get(:year))
|
|
119
|
-
super(u:u, y:y)
|
|
120
|
-
@table = :calendar
|
|
121
|
-
@cols = "*"
|
|
122
|
-
@where = {year:year}
|
|
123
|
-
end
|
|
124
|
-
def title
|
|
125
|
-
"#{user}: #{year}"
|
|
126
|
-
end
|
|
127
|
-
def headings
|
|
128
|
-
["Day", "Stars"]
|
|
129
|
-
end
|
|
130
|
-
def rows
|
|
131
|
-
@rows ||= data.map{|d| [d[1], parse_stars(d[2])]}
|
|
132
|
-
end
|
|
133
|
-
def parse_stars(day)
|
|
134
|
-
day.to_i == 0 ? ".." : ("*" * day.to_i).ljust(2, ".")
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
end
|
data/lib/aoc_cli/tools.rb
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
module AocCli
|
|
2
|
-
module Tools
|
|
3
|
-
class Request
|
|
4
|
-
require 'curb'
|
|
5
|
-
attr_reader :user, :year, :day, :base, :page, :ua
|
|
6
|
-
def initialize(u:Metafile.get(:user),
|
|
7
|
-
y:Metafile.get(:year),
|
|
8
|
-
d:Metafile.get(:day), p:)
|
|
9
|
-
@user = Validate.user(u)
|
|
10
|
-
@year = Validate.year(y)
|
|
11
|
-
@day = d
|
|
12
|
-
@page = p
|
|
13
|
-
@base = "https://adventofcode.com/#{year}"
|
|
14
|
-
@ua = "github.com/apexatoll/aoc-cli"
|
|
15
|
-
end
|
|
16
|
-
protected
|
|
17
|
-
def get
|
|
18
|
-
Curl.get(url) do |h|
|
|
19
|
-
h.headers['Cookie'] = cookie
|
|
20
|
-
h.headers['User-Agent'] = ua
|
|
21
|
-
end.body
|
|
22
|
-
end
|
|
23
|
-
def post(data:)
|
|
24
|
-
Curl.post(url, data) do |h|
|
|
25
|
-
h.headers['Cookie'] = cookie
|
|
26
|
-
h.headers['User-Agent'] = ua
|
|
27
|
-
end.body
|
|
28
|
-
end
|
|
29
|
-
private
|
|
30
|
-
def cookie
|
|
31
|
-
Files::Config::Cookie.key(user:user)
|
|
32
|
-
end
|
|
33
|
-
def url
|
|
34
|
-
case page.to_sym
|
|
35
|
-
when :Calendar then base
|
|
36
|
-
when :Stats then base + "/leaderboard/self"
|
|
37
|
-
when :Puzzle then base + "/day/#{day}"
|
|
38
|
-
when :Input then base + "/day/#{day}/input"
|
|
39
|
-
when :Answer then base + "/day/#{day}/answer"
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
class Convert < Request
|
|
44
|
-
require 'pandoc-ruby'
|
|
45
|
-
attr_accessor :input
|
|
46
|
-
def array
|
|
47
|
-
input.split("\n")
|
|
48
|
-
end
|
|
49
|
-
def chunk(f:, t:, t_off:0, f_off:0)
|
|
50
|
-
pt1 = array.index {|l| l =~ /#{f}/} + t_off
|
|
51
|
-
pt2 = array.rindex{|l| l =~ /#{t}/} + f_off
|
|
52
|
-
@input = array.slice(pt1, pt2 - pt1).join("\n")
|
|
53
|
-
self
|
|
54
|
-
end
|
|
55
|
-
def raw
|
|
56
|
-
input.split("\n").join("\n")
|
|
57
|
-
end
|
|
58
|
-
def plain
|
|
59
|
-
PandocRuby.new(input, f: html, t: :plain).convert
|
|
60
|
-
end
|
|
61
|
-
def md
|
|
62
|
-
PandocRuby.new(input, {f: html, t: :gfm},
|
|
63
|
-
md_head, md_ref).convert
|
|
64
|
-
end
|
|
65
|
-
private
|
|
66
|
-
def html
|
|
67
|
-
"html-native_divs-native_spans"
|
|
68
|
-
end
|
|
69
|
-
def md_head
|
|
70
|
-
"--markdown-headings=setext"
|
|
71
|
-
end
|
|
72
|
-
def md_ref
|
|
73
|
-
"--reference-links"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
class Get < Convert
|
|
77
|
-
def initialize(u:Metafile.get(:user),
|
|
78
|
-
y:Metafile.get(:year), d:nil, p:)
|
|
79
|
-
@input = Request.new(u:u, y:y, d:d, p:p).get
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
class Post < Convert
|
|
83
|
-
def initialize(u:Metafile.get(:user),
|
|
84
|
-
y:Metafile.get(:year),
|
|
85
|
-
d:Metafile.get(:day),
|
|
86
|
-
p:"Answer", data:)
|
|
87
|
-
@input = Request
|
|
88
|
-
.new(u:u, y:y, d:d, p:p)
|
|
89
|
-
.post(data:data)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
class Reddit
|
|
93
|
-
attr_reader :year, :day, :uniq, :browser
|
|
94
|
-
def initialize(y:Metafile.get(:year),
|
|
95
|
-
d:Metafile.get(:day),
|
|
96
|
-
b:Prefs.bool(key:"reddit_in_browser"))
|
|
97
|
-
@year = Validate.year(y)
|
|
98
|
-
@day = Validate.day(d)
|
|
99
|
-
@uniq = Database::Query
|
|
100
|
-
.new(path:Paths::Database.root("reddit"))
|
|
101
|
-
.select(t:"'#{year}'", where:{day:"'#{day}'"})
|
|
102
|
-
.flatten[1]
|
|
103
|
-
@browser = b
|
|
104
|
-
end
|
|
105
|
-
def open
|
|
106
|
-
system("#{browser ? "open" : cmd} #{link}")
|
|
107
|
-
end
|
|
108
|
-
def cmd
|
|
109
|
-
["ttrv", "rtv"]
|
|
110
|
-
.map{|cli| cli unless `which #{cli}`.empty?}
|
|
111
|
-
.reject{|cmd| cmd.nil?}&.first || "open"
|
|
112
|
-
end
|
|
113
|
-
def link
|
|
114
|
-
"https://www.reddit.com/r/"\
|
|
115
|
-
"adventofcode/comments/#{uniq}/"\
|
|
116
|
-
"#{year}_day_#{day}_solutions"
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
data/lib/aoc_cli/year.rb
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
module AocCli
|
|
2
|
-
module Year
|
|
3
|
-
def self.refresh
|
|
4
|
-
puts "- Updating calendar...".blue
|
|
5
|
-
Year::Meta.new.write
|
|
6
|
-
Year::Progress.new.write
|
|
7
|
-
.init_calendar_db
|
|
8
|
-
end
|
|
9
|
-
class Meta
|
|
10
|
-
attr_reader :user, :year, :paths
|
|
11
|
-
def initialize(u:Prefs.default_alias,
|
|
12
|
-
y:Metafile.get(:year))
|
|
13
|
-
@user = Validate.user(u)
|
|
14
|
-
@year = Validate.year(y)
|
|
15
|
-
@paths = Paths::Year.new(u:user, y:year)
|
|
16
|
-
end
|
|
17
|
-
def write
|
|
18
|
-
File.write(paths.local(f:"meta"),
|
|
19
|
-
Metafile.year(u:user, y:year))
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
class Progress < Meta
|
|
23
|
-
def stats
|
|
24
|
-
@stats ||= Requests::Stats.new(u:user, y:year)
|
|
25
|
-
end
|
|
26
|
-
def cal
|
|
27
|
-
@cal ||= Requests::Calendar.new(u:user, y:year)
|
|
28
|
-
.fill(stars:stats.stars)
|
|
29
|
-
end
|
|
30
|
-
def file
|
|
31
|
-
Files::Calendar.new(stats:stats, cal:cal).make
|
|
32
|
-
end
|
|
33
|
-
def write?
|
|
34
|
-
Prefs.bool(key:"calendar_file")
|
|
35
|
-
end
|
|
36
|
-
def write
|
|
37
|
-
File.write(paths.local(f:"Stars"), file) if write?
|
|
38
|
-
self
|
|
39
|
-
end
|
|
40
|
-
def init_calendar_db
|
|
41
|
-
Database::Calendar::Init
|
|
42
|
-
.new(u:user, y:year, stars:stats.stars)
|
|
43
|
-
.insert
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
module Requests
|
|
47
|
-
class Request < Meta
|
|
48
|
-
attr_reader :data
|
|
49
|
-
def initialize(u:Metafile.get(:user),
|
|
50
|
-
y:Metafile.get(:year))
|
|
51
|
-
super(u:u, y:y)
|
|
52
|
-
@data = parse(raw: fetch)
|
|
53
|
-
end
|
|
54
|
-
private
|
|
55
|
-
def fetch
|
|
56
|
-
Tools::Get.new(u:user, y:year, p:page)
|
|
57
|
-
.plain.split("\n")
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
class Calendar < Request
|
|
61
|
-
def page
|
|
62
|
-
:Calendar
|
|
63
|
-
end
|
|
64
|
-
def parse(raw:)
|
|
65
|
-
raw.drop(raw.index{|l| l =~ /\*\*/})
|
|
66
|
-
.map{|l| l.gsub(/\*\*/, "")}
|
|
67
|
-
end
|
|
68
|
-
def fill(stars:)
|
|
69
|
-
stars.each{|s, n| data.each{|l| l
|
|
70
|
-
.gsub!(/(^.*)\b#{s}\b.$/, "\\1#{s}\s#{"*" * n}")}}
|
|
71
|
-
self
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
class Stats < Request
|
|
75
|
-
def page
|
|
76
|
-
:Stats
|
|
77
|
-
end
|
|
78
|
-
def parse(raw:)
|
|
79
|
-
/You haven't collected/.match?(raw.to_s) ?
|
|
80
|
-
raw : raw.drop(raw.index{|l| l =~ /^.*Part 1/})
|
|
81
|
-
end
|
|
82
|
-
def stars
|
|
83
|
-
data.map{|l| l.scan(/^\s+\d+/)&.first}
|
|
84
|
-
.reject{|s| s == nil}
|
|
85
|
-
.map{|s| [s.to_i, data
|
|
86
|
-
.grep(/^.*#{s}.*(\-.*){3}$/)
|
|
87
|
-
.count == 0 ? 2 : 1]}.to_h
|
|
88
|
-
end
|
|
89
|
-
def total_stars
|
|
90
|
-
stars.values.reduce(:+).to_i || 0
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
class GitWrap
|
|
95
|
-
require 'git'
|
|
96
|
-
attr_reader :git
|
|
97
|
-
def initialize
|
|
98
|
-
@git = Git.init
|
|
99
|
-
File.write(".gitignore", ignore)
|
|
100
|
-
git.add(".gitignore")
|
|
101
|
-
end
|
|
102
|
-
def ignore_md?
|
|
103
|
-
Prefs.bool(key:"ignore_md_files")
|
|
104
|
-
end
|
|
105
|
-
def ignore_meta?
|
|
106
|
-
Prefs.bool(key:"ignore_meta_files")
|
|
107
|
-
end
|
|
108
|
-
def ignore
|
|
109
|
-
<<~ignore
|
|
110
|
-
#{".meta\n**/.meta" if ignore_meta?}#{
|
|
111
|
-
"\n*.md\n**/*.md" if ignore_md?}
|
|
112
|
-
ignore
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
data/sample/aoc.rc
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
//aoc-cli example config
|
|
2
|
-
//See the github repo for more information on configuring aoc-cli
|
|
3
|
-
//https://github.com/apexatoll/aoc-cli
|
|
4
|
-
|
|
5
|
-
[General]
|
|
6
|
-
//Print table in unicode rather than ascii
|
|
7
|
-
unicode_tables=>true
|
|
8
|
-
//Open Reddit in browser rather than use a Reddit CLI
|
|
9
|
-
reddit_in_browser=>false
|
|
10
|
-
|
|
11
|
-
[Initialise Year]
|
|
12
|
-
//Create a calendar file
|
|
13
|
-
calendar_file=>true
|
|
14
|
-
//Initialise git repo on year initialisation
|
|
15
|
-
init_git=>false
|
|
16
|
-
//Add calendar and puzzle files to gitignore
|
|
17
|
-
ignore_md_files=>true
|
|
18
|
-
//Add .meta files to gitignore
|
|
19
|
-
ignore_meta_files=>true
|
|
20
|
-
//Include leaderboard stats in calendar file
|
|
21
|
-
lb_in_calendar=>true
|