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
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Core
|
|
3
|
+
class AttemptParser
|
|
4
|
+
attr_reader response: String
|
|
5
|
+
|
|
6
|
+
def initialize: (String) -> void
|
|
7
|
+
|
|
8
|
+
def to_h: -> Hash[Symbol, untyped]
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
module Prefixes
|
|
13
|
+
CORRECT: Regexp
|
|
14
|
+
INCORRECT: Regexp
|
|
15
|
+
RATE_LIMITED: Regexp
|
|
16
|
+
WRONG_LEVEL: Regexp
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module Hints
|
|
20
|
+
TOO_LOW: Regexp
|
|
21
|
+
TOO_HIGH: Regexp
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module WaitTimes
|
|
25
|
+
ONE_MINUTE: Regexp
|
|
26
|
+
INCORRECT_FORMAT: Regexp
|
|
27
|
+
RATE_LIMITED_FORMAT: Regexp
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def status: -> Symbol
|
|
31
|
+
|
|
32
|
+
def hint: -> Symbol?
|
|
33
|
+
|
|
34
|
+
def wait_time: -> Integer?
|
|
35
|
+
|
|
36
|
+
def scan_incorrect_wait_time!: -> Integer?
|
|
37
|
+
|
|
38
|
+
def scan_rated_limited_wait_time!: -> Integer?
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Core
|
|
3
|
+
class Processor
|
|
4
|
+
extend Forwardable
|
|
5
|
+
|
|
6
|
+
include Kangaru::Attributable
|
|
7
|
+
extend Kangaru::Attributable::ClassMethods
|
|
8
|
+
|
|
9
|
+
include Kangaru::Validatable
|
|
10
|
+
extend Kangaru::Validatable::ClassMethods
|
|
11
|
+
|
|
12
|
+
class Error < StandardError
|
|
13
|
+
attr_reader processor: Processor
|
|
14
|
+
|
|
15
|
+
def initialize: (Processor) -> void
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run: -> untyped
|
|
19
|
+
|
|
20
|
+
def run!: -> untyped
|
|
21
|
+
|
|
22
|
+
def self.run!: (**untyped) -> untyped
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Core
|
|
3
|
+
class Repository
|
|
4
|
+
HOST: String
|
|
5
|
+
|
|
6
|
+
RESOURCES: Hash[Symbol, Hash[Symbol, untyped]]
|
|
7
|
+
|
|
8
|
+
def self.get_stats: (year: Integer) -> Hash[Symbol, Integer]
|
|
9
|
+
|
|
10
|
+
def self.get_puzzle: (year: Integer, day: Integer) -> String
|
|
11
|
+
|
|
12
|
+
def self.get_input: (year: Integer, day: Integer) -> String
|
|
13
|
+
|
|
14
|
+
def self.post_solution: (
|
|
15
|
+
year: Integer, day: Integer, level: Integer, answer: untyped
|
|
16
|
+
) -> Hash[Symbol, untyped]
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def self.build_resource: (Symbol, **untyped) -> Resource
|
|
21
|
+
|
|
22
|
+
def self.format_url: (String, **untyped) -> String
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Core
|
|
3
|
+
class Request
|
|
4
|
+
extend Forwardable
|
|
5
|
+
|
|
6
|
+
attr_reader client: HTTP::Client
|
|
7
|
+
|
|
8
|
+
def initialize: (token: String) -> void
|
|
9
|
+
|
|
10
|
+
def get: (String) -> HTTP::Response
|
|
11
|
+
|
|
12
|
+
def post: (String, **untyped) -> HTTP::Response
|
|
13
|
+
|
|
14
|
+
def self.build: -> Request
|
|
15
|
+
|
|
16
|
+
def self.get: (String) -> HTTP::Response
|
|
17
|
+
|
|
18
|
+
def self.post: (String, **untyped) -> HTTP::Response
|
|
19
|
+
|
|
20
|
+
class ::Class
|
|
21
|
+
def def_delegators: (Symbol, *Symbol) -> void
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def setup_client!: (String) -> HTTP::Client
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Core
|
|
3
|
+
class Resource
|
|
4
|
+
attr_reader url: String
|
|
5
|
+
attr_reader scope: String?
|
|
6
|
+
attr_reader method: Symbol
|
|
7
|
+
attr_reader params: Hash[Symbol, untyped]
|
|
8
|
+
|
|
9
|
+
def initialize: (
|
|
10
|
+
url: String,
|
|
11
|
+
?scope: String?,
|
|
12
|
+
?method: Symbol,
|
|
13
|
+
?params: Hash[Symbol, untyped]
|
|
14
|
+
) -> void
|
|
15
|
+
|
|
16
|
+
def fetch: -> String
|
|
17
|
+
|
|
18
|
+
def fetch_markdown: -> String
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def response: -> String
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Core
|
|
3
|
+
class StatsParser
|
|
4
|
+
DAY_CLASS_PREFIX: String
|
|
5
|
+
ONE_STAR_CLASS: String
|
|
6
|
+
TWO_STARS_CLASS: String
|
|
7
|
+
|
|
8
|
+
attr_reader calendar_html: String
|
|
9
|
+
|
|
10
|
+
def initialize: (String) -> void
|
|
11
|
+
|
|
12
|
+
def to_h: -> Hash[Symbol, Integer]
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def calendar_link_classes: -> Array[Array[String]]
|
|
17
|
+
|
|
18
|
+
def calendar_links: -> Nokogiri::XML::NodeSet
|
|
19
|
+
|
|
20
|
+
def count_stars: (Array[String]) -> Integer
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Helpers
|
|
3
|
+
class TableGenerator
|
|
4
|
+
type matrix[T] = Array[Array[T]]
|
|
5
|
+
|
|
6
|
+
include Kangaru::Validatable
|
|
7
|
+
extend Kangaru::Validatable::ClassMethods
|
|
8
|
+
|
|
9
|
+
attr_reader rows: matrix[String]
|
|
10
|
+
attr_reader gap: Integer
|
|
11
|
+
attr_reader indent: Integer
|
|
12
|
+
|
|
13
|
+
def initialize: (
|
|
14
|
+
rows: matrix[String],
|
|
15
|
+
?gap: Integer,
|
|
16
|
+
?indent: Integer
|
|
17
|
+
) -> void
|
|
18
|
+
|
|
19
|
+
def validate!: -> void
|
|
20
|
+
|
|
21
|
+
def generate!: -> String
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
CELL_GAP: Integer
|
|
26
|
+
|
|
27
|
+
attr_reader column_widths: Array[Integer]
|
|
28
|
+
|
|
29
|
+
def space: (Integer) -> String
|
|
30
|
+
|
|
31
|
+
def format_row!: (Array[String]) -> String
|
|
32
|
+
|
|
33
|
+
def validate_rows_are_same_length!: -> void
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Helpers
|
|
3
|
+
module ViewHelper
|
|
4
|
+
def main_header: -> String
|
|
5
|
+
|
|
6
|
+
def heading: (String) -> String
|
|
7
|
+
|
|
8
|
+
def success_tag: -> String
|
|
9
|
+
|
|
10
|
+
def table_for: (*Array[String], ?gap: Integer, ?indent: Integer) -> String
|
|
11
|
+
|
|
12
|
+
def wrap_text: (String, ?width: Integer, ?indent: Integer) -> String
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class Attempt < Kangaru::Model
|
|
3
|
+
attr_accessor id: Integer
|
|
4
|
+
attr_accessor level: Integer
|
|
5
|
+
attr_accessor answer: String
|
|
6
|
+
attr_accessor status: Symbol
|
|
7
|
+
attr_accessor hint: Symbol?
|
|
8
|
+
attr_accessor wait_time: Integer?
|
|
9
|
+
attr_accessor created_at: Time
|
|
10
|
+
attr_accessor updated_at: Time
|
|
11
|
+
|
|
12
|
+
attr_accessor puzzle: Puzzle
|
|
13
|
+
attr_accessor puzzle_dataset: Sequel::Dataset
|
|
14
|
+
|
|
15
|
+
attr_reader presenter: Presenters::AttemptPresenter
|
|
16
|
+
|
|
17
|
+
def incorrect?: -> bool
|
|
18
|
+
def correct?: -> bool
|
|
19
|
+
def rate_limited?: -> bool
|
|
20
|
+
def wrong_level?: -> bool
|
|
21
|
+
|
|
22
|
+
def too_low?: -> bool
|
|
23
|
+
def too_high?: -> bool
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def validate_hint_not_set!: -> void
|
|
28
|
+
|
|
29
|
+
def validate_hint!: -> void
|
|
30
|
+
|
|
31
|
+
def validate_wait_time_not_set!: -> void
|
|
32
|
+
|
|
33
|
+
def validate_wait_time_integer!: -> void
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class Event < Kangaru::Model
|
|
3
|
+
attr_accessor id: Integer
|
|
4
|
+
attr_accessor year: Integer
|
|
5
|
+
attr_accessor created_at: Time
|
|
6
|
+
attr_accessor updated_at: Time
|
|
7
|
+
|
|
8
|
+
attr_accessor puzzles: Array[Puzzle]
|
|
9
|
+
attr_accessor puzzles_dataset: Sequel::Dataset
|
|
10
|
+
|
|
11
|
+
attr_accessor stats: Stats
|
|
12
|
+
attr_accessor stats_dataset: Sequel::Dataset
|
|
13
|
+
|
|
14
|
+
attr_accessor location: Location
|
|
15
|
+
attr_accessor location_dataset: Sequel::Dataset
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class Location < Kangaru::Model
|
|
3
|
+
type resource = (Event | Puzzle)
|
|
4
|
+
|
|
5
|
+
attr_accessor id: Integer
|
|
6
|
+
attr_accessor path: String
|
|
7
|
+
attr_accessor resource: resource
|
|
8
|
+
attr_accessor created_at: Time
|
|
9
|
+
attr_accessor updated_at: Time
|
|
10
|
+
|
|
11
|
+
def exists?: -> bool
|
|
12
|
+
|
|
13
|
+
def event_dir?: -> bool
|
|
14
|
+
|
|
15
|
+
def puzzle_dir?: -> bool
|
|
16
|
+
|
|
17
|
+
def to_pathname: -> Pathname
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class Progress < Kangaru::Model
|
|
3
|
+
attr_accessor id: Integer
|
|
4
|
+
attr_accessor puzzle: Puzzle
|
|
5
|
+
attr_accessor level: Integer
|
|
6
|
+
attr_accessor started_at: Time
|
|
7
|
+
attr_accessor completed_at: Time
|
|
8
|
+
attr_accessor created_at: Time
|
|
9
|
+
attr_accessor updated_at: Time
|
|
10
|
+
|
|
11
|
+
def complete?: -> bool
|
|
12
|
+
|
|
13
|
+
def incomplete?: -> bool
|
|
14
|
+
|
|
15
|
+
def complete!: -> void
|
|
16
|
+
|
|
17
|
+
def reset!: -> void
|
|
18
|
+
|
|
19
|
+
def time_taken: -> Float
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class Puzzle < Kangaru::Model
|
|
3
|
+
extend Forwardable
|
|
4
|
+
|
|
5
|
+
attr_accessor id: Integer
|
|
6
|
+
attr_accessor event: Event
|
|
7
|
+
attr_accessor day: Integer
|
|
8
|
+
attr_accessor content: String
|
|
9
|
+
attr_accessor input: String
|
|
10
|
+
attr_accessor created_at: Time
|
|
11
|
+
attr_accessor updated_at: Time
|
|
12
|
+
|
|
13
|
+
attr_accessor location: Location
|
|
14
|
+
attr_accessor location_dataset: Sequel::Dataset
|
|
15
|
+
|
|
16
|
+
attr_accessor attempts: Array[Attempt]
|
|
17
|
+
attr_accessor attempts_dataset: Sequel::Dataset
|
|
18
|
+
|
|
19
|
+
attr_accessor part_one_progress: Progress?
|
|
20
|
+
attr_accessor part_two_progress: Progress?
|
|
21
|
+
|
|
22
|
+
# Delegated to event
|
|
23
|
+
def year: -> Integer
|
|
24
|
+
|
|
25
|
+
attr_reader presenter: Presenters::PuzzlePresenter
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class PuzzleDirSyncLog < Kangaru::Model
|
|
3
|
+
attr_accessor id: Integer
|
|
4
|
+
attr_accessor puzzle: Puzzle
|
|
5
|
+
attr_accessor location: Location
|
|
6
|
+
attr_accessor puzzle_status: Symbol
|
|
7
|
+
attr_accessor input_status: Symbol
|
|
8
|
+
|
|
9
|
+
STATUS_ENUM: Hash[Symbol, Integer]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
class Stats < Kangaru::Model
|
|
3
|
+
extend Forwardable
|
|
4
|
+
|
|
5
|
+
attr_accessor id: Integer
|
|
6
|
+
attr_accessor day_1: Integer
|
|
7
|
+
attr_accessor day_2: Integer
|
|
8
|
+
attr_accessor day_3: Integer
|
|
9
|
+
attr_accessor day_4: Integer
|
|
10
|
+
attr_accessor day_5: Integer
|
|
11
|
+
attr_accessor day_6: Integer
|
|
12
|
+
attr_accessor day_7: Integer
|
|
13
|
+
attr_accessor day_8: Integer
|
|
14
|
+
attr_accessor day_9: Integer
|
|
15
|
+
attr_accessor day_10: Integer
|
|
16
|
+
attr_accessor day_11: Integer
|
|
17
|
+
attr_accessor day_12: Integer
|
|
18
|
+
attr_accessor day_13: Integer
|
|
19
|
+
attr_accessor day_14: Integer
|
|
20
|
+
attr_accessor day_15: Integer
|
|
21
|
+
attr_accessor day_16: Integer
|
|
22
|
+
attr_accessor day_17: Integer
|
|
23
|
+
attr_accessor day_18: Integer
|
|
24
|
+
attr_accessor day_19: Integer
|
|
25
|
+
attr_accessor day_20: Integer
|
|
26
|
+
attr_accessor day_21: Integer
|
|
27
|
+
attr_accessor day_22: Integer
|
|
28
|
+
attr_accessor day_23: Integer
|
|
29
|
+
attr_accessor day_24: Integer
|
|
30
|
+
attr_accessor day_25: Integer
|
|
31
|
+
attr_accessor created_at: Time
|
|
32
|
+
attr_accessor updated_at: Time
|
|
33
|
+
attr_accessor completed_at: Time
|
|
34
|
+
|
|
35
|
+
attr_accessor event: Event
|
|
36
|
+
attr_accessor event_dataset: Sequel::Dataset
|
|
37
|
+
|
|
38
|
+
# Delegated to event
|
|
39
|
+
def year: -> Integer
|
|
40
|
+
|
|
41
|
+
attr_reader presenter: Presenters::StatsPresenter
|
|
42
|
+
|
|
43
|
+
def total: -> Integer
|
|
44
|
+
|
|
45
|
+
def progress: (Integer) -> Integer
|
|
46
|
+
|
|
47
|
+
def current_level: (Integer) -> Integer?
|
|
48
|
+
|
|
49
|
+
def complete?: (Integer) -> bool
|
|
50
|
+
|
|
51
|
+
def advance_progress!: (Integer) -> void
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Presenters
|
|
3
|
+
class PuzzlePresenter
|
|
4
|
+
attr_reader puzzle: Puzzle
|
|
5
|
+
|
|
6
|
+
def initialize: (Puzzle) -> void
|
|
7
|
+
|
|
8
|
+
def date: -> String
|
|
9
|
+
|
|
10
|
+
def puzzle_filename: -> String
|
|
11
|
+
|
|
12
|
+
def input_filename: -> String
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def formatted_day: -> String
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Presenters
|
|
3
|
+
class StatsPresenter
|
|
4
|
+
attr_reader stats: Stats
|
|
5
|
+
|
|
6
|
+
def initialize: (Stats) -> void
|
|
7
|
+
|
|
8
|
+
def total_progress: -> String
|
|
9
|
+
|
|
10
|
+
def progress_icons: (Integer) -> String
|
|
11
|
+
|
|
12
|
+
module Icons
|
|
13
|
+
INCOMPLETE: String
|
|
14
|
+
HALF_COMPLETE: String
|
|
15
|
+
COMPLETE: String
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Processors
|
|
3
|
+
class EventInitialiser < Core::Processor
|
|
4
|
+
attr_accessor year: Integer
|
|
5
|
+
attr_accessor dir: String
|
|
6
|
+
|
|
7
|
+
def self.run!: (year: untyped, dir: untyped) -> Event
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
attr_reader event_dir: Pathname
|
|
12
|
+
|
|
13
|
+
def create_event!: -> Event
|
|
14
|
+
|
|
15
|
+
def initialise_stats!: (Event) -> void
|
|
16
|
+
|
|
17
|
+
def make_event_directory!: -> void
|
|
18
|
+
|
|
19
|
+
def attach_event!: (Event) -> void
|
|
20
|
+
|
|
21
|
+
def validate_event_dir_does_not_exist!: -> void
|
|
22
|
+
|
|
23
|
+
def validate_event_not_already_initialised!: -> void
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Processors
|
|
3
|
+
class ProgressSyncer < Core::Processor
|
|
4
|
+
attr_accessor puzzle: Puzzle
|
|
5
|
+
attr_accessor stats: Stats
|
|
6
|
+
|
|
7
|
+
def run: -> void
|
|
8
|
+
|
|
9
|
+
def self.run!: (puzzle: untyped, stats: untyped) -> void
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def part_one_progress: -> Progress?
|
|
14
|
+
def part_two_progress: -> Progress?
|
|
15
|
+
|
|
16
|
+
def current_progress: -> Integer
|
|
17
|
+
|
|
18
|
+
def create_part_one_progress!: -> void
|
|
19
|
+
|
|
20
|
+
def create_part_two_progress!: -> void
|
|
21
|
+
|
|
22
|
+
def handle_not_complete!: -> void
|
|
23
|
+
|
|
24
|
+
def handle_partially_complete!: -> void
|
|
25
|
+
|
|
26
|
+
def handle_fully_complete!: -> void
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Processors
|
|
3
|
+
class PuzzleDirSynchroniser < Core::Processor
|
|
4
|
+
attr_accessor puzzle: Puzzle
|
|
5
|
+
attr_accessor location: Location
|
|
6
|
+
attr_accessor skip_cache: bool
|
|
7
|
+
|
|
8
|
+
def self.run!: (
|
|
9
|
+
puzzle: untyped,
|
|
10
|
+
location: untyped,
|
|
11
|
+
?skip_cache: untyped
|
|
12
|
+
)-> PuzzleDirSyncLog
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# Delegated to Puzzle
|
|
17
|
+
def year: -> Integer
|
|
18
|
+
def day: -> Integer
|
|
19
|
+
def presenter: -> Presenters::PuzzlePresenter
|
|
20
|
+
|
|
21
|
+
# Delegated to Presenter
|
|
22
|
+
def puzzle_filename: -> String
|
|
23
|
+
def input_filename: -> String
|
|
24
|
+
|
|
25
|
+
attr_reader puzzle_dir: Pathname
|
|
26
|
+
attr_reader puzzle_file: Pathname
|
|
27
|
+
attr_reader input_file: Pathname
|
|
28
|
+
|
|
29
|
+
def refresh_puzzle!: -> void
|
|
30
|
+
|
|
31
|
+
def create_puzzle_dir_sync_log!: -> PuzzleDirSyncLog
|
|
32
|
+
|
|
33
|
+
def puzzle_status: -> Symbol
|
|
34
|
+
|
|
35
|
+
def input_status: -> Symbol
|
|
36
|
+
|
|
37
|
+
def validate_puzzle_dir_exists!: -> void
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Processors
|
|
3
|
+
class PuzzleInitialiser < Core::Processor
|
|
4
|
+
attr_accessor event: Event
|
|
5
|
+
attr_accessor day: Integer
|
|
6
|
+
|
|
7
|
+
def run: -> Puzzle
|
|
8
|
+
|
|
9
|
+
def self.run!: (event: untyped, day: untyped) -> Puzzle
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# Delegated to Event
|
|
14
|
+
def year: -> Integer
|
|
15
|
+
|
|
16
|
+
attr_reader event_dir: Pathname
|
|
17
|
+
attr_reader puzzle_dir: Pathname
|
|
18
|
+
attr_reader existing_puzzle: Puzzle?
|
|
19
|
+
|
|
20
|
+
def fetch_content!: -> String
|
|
21
|
+
|
|
22
|
+
def fetch_input!: -> String
|
|
23
|
+
|
|
24
|
+
def create_or_update_puzzle!: (String, String) -> Puzzle
|
|
25
|
+
|
|
26
|
+
def sync_puzzle_progress!: (Puzzle) -> void
|
|
27
|
+
|
|
28
|
+
def attach_puzzle_dir!: (Puzzle) -> Location
|
|
29
|
+
|
|
30
|
+
def write_puzzle_files!: (Puzzle, Location) -> PuzzleDirSyncLog
|
|
31
|
+
|
|
32
|
+
def validate_event_stats_set!: -> void
|
|
33
|
+
|
|
34
|
+
def validate_event_location_set!: -> void
|
|
35
|
+
|
|
36
|
+
def validate_event_dir_exists!: -> void
|
|
37
|
+
|
|
38
|
+
def validate_puzzle_dir_does_not_exist!: -> void
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Processors
|
|
3
|
+
class PuzzleRefresher < Core::Processor
|
|
4
|
+
attr_accessor puzzle: Puzzle
|
|
5
|
+
|
|
6
|
+
def self.run!: (puzzle: Puzzle) -> Puzzle
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
extend Forwardable
|
|
11
|
+
|
|
12
|
+
def year: -> Integer
|
|
13
|
+
|
|
14
|
+
def day: -> Integer
|
|
15
|
+
|
|
16
|
+
def content: -> String
|
|
17
|
+
|
|
18
|
+
def input: -> String
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module AocCli
|
|
2
|
+
module Processors
|
|
3
|
+
class ResourceAttacher < Core::Processor
|
|
4
|
+
type resource = Event | Puzzle
|
|
5
|
+
|
|
6
|
+
attr_accessor resource: resource
|
|
7
|
+
attr_accessor path: String
|
|
8
|
+
|
|
9
|
+
def run: -> Location
|
|
10
|
+
|
|
11
|
+
def self.run!: (resource: resource, path: String) -> Location
|
|
12
|
+
|
|
13
|
+
def location: -> Location?
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|