aoc_cli 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 523ec81af92a97e0d60f5e7490d29feb336e2c1577eecb00c7510c47171dfb87
4
- data.tar.gz: 6c6f424ee15d996c12d9552d6a7681fd946b0f0724c5803f3344bfdb41eaad72
3
+ metadata.gz: ddf7e8e1d35efd516bae0a1a9b4d773a0ff59120f3ae287491668fa81740ffba
4
+ data.tar.gz: 7fc18fbfcf0391b6d9b6ed43b6e6f35b372f368c9ffd8f5f23c2f3a305c470d2
5
5
  SHA512:
6
- metadata.gz: cd1fd05753d8fc593f37b6f28db96bb58cb9eae931a8b28852513ed25bf6cdcc300c44f4963a1581207dd8001b4d9fc0115ac582b6d79d49e1766c54dc17fbe7
7
- data.tar.gz: 1a5a042be37b1e4b661c05417a94312701c26eb794895cfc58455099ef9cd16f3c6df57ac74d096d20f5298019415b6beea15acc875f465728ef7314ad5dd031
6
+ metadata.gz: 41cb419b34d2d7a385e3c227e11b4f548f834d1f6d14566d11baff340367ff95ed7e87cdf512ae45aa3dc4339b65e9549ff2182960e33d0b26af06a6e36e1f24
7
+ data.tar.gz: e32591f10e88ff7aa402ebe0523328af2bc61a8458028ff3c559477ec81aa3ee34944b8cf63156ae8625e9000e4a9716d910c02a59a4010679c524dcf387652b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aoc_cli (1.0.0)
4
+ aoc_cli (1.0.1)
5
5
  http
6
6
  kangaru
7
7
  nokogiri
data/aoc_cli.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.bindir = "exe"
31
31
  spec.executables = ["aoc"]
32
- spec.require_paths = ["lib"]
32
+ spec.require_paths = %w[lib db]
33
33
 
34
34
  spec.add_dependency "http"
35
35
  spec.add_dependency "kangaru"
@@ -0,0 +1,17 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table :progresses do
4
+ primary_key :id
5
+
6
+ foreign_key :puzzle_id, :puzzles, null: false
7
+
8
+ integer :level, null: false
9
+
10
+ datetime :started_at, null: false
11
+ datetime :completed_at
12
+
13
+ datetime :created_at
14
+ datetime :updated_at
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table :puzzles do
4
+ drop_column :part_one_completed_at
5
+ drop_column :part_two_completed_at
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ module AocCli
2
+ class Progress < Kangaru::Model
3
+ many_to_one :puzzle
4
+
5
+ validates :puzzle, required: true
6
+ validates :level, integer: { between: 1..2 }
7
+ validates :started_at, required: true
8
+
9
+ def complete?
10
+ !incomplete?
11
+ end
12
+
13
+ def incomplete?
14
+ completed_at.nil?
15
+ end
16
+
17
+ def complete!
18
+ update(completed_at: Time.now)
19
+ end
20
+
21
+ def reset!
22
+ update(started_at: Time.now)
23
+ end
24
+
25
+ def time_taken
26
+ if complete?
27
+ completed_at - started_at
28
+ else
29
+ Time.now - started_at
30
+ end
31
+ end
32
+ end
33
+ end
@@ -6,6 +6,14 @@ module AocCli
6
6
  one_to_one :location, as: :resource
7
7
  one_to_many :attempts
8
8
 
9
+ one_to_one :part_one_progress,
10
+ class: "AocCli::Progress",
11
+ conditions: { level: 1 }
12
+
13
+ one_to_one :part_two_progress,
14
+ class: "AocCli::Progress",
15
+ conditions: { level: 2 }
16
+
9
17
  validates :event, required: true
10
18
  validates :day, integer: { between: 1..25 }
11
19
  validates :content, required: true
@@ -16,13 +24,5 @@ module AocCli
16
24
  def presenter
17
25
  @presenter ||= Presenters::PuzzlePresenter.new(self)
18
26
  end
19
-
20
- def mark_complete!(level)
21
- case level
22
- when 1 then update(part_one_completed_at: Time.now)
23
- when 2 then update(part_two_completed_at: Time.now)
24
- else raise "invalid level"
25
- end
26
- end
27
27
  end
28
28
  end
@@ -0,0 +1,48 @@
1
+ module AocCli
2
+ module Processors
3
+ class ProgressSyncer < Core::Processor
4
+ attr_accessor :puzzle, :stats
5
+
6
+ validates :puzzle, required: true
7
+ validates :stats, required: true
8
+
9
+ def run
10
+ case current_progress
11
+ when 0 then handle_not_complete!
12
+ when 1 then handle_partially_complete!
13
+ when 2 then handle_fully_complete!
14
+ else raise
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def_delegators :puzzle, :part_one_progress, :part_two_progress
21
+
22
+ def current_progress
23
+ stats.progress(puzzle.day)
24
+ end
25
+
26
+ def create_part_one_progress!
27
+ Progress.create(puzzle:, level: 1, started_at: Time.now)
28
+ end
29
+
30
+ def create_part_two_progress!
31
+ Progress.create(puzzle:, level: 2, started_at: Time.now)
32
+ end
33
+
34
+ def handle_not_complete!
35
+ create_part_one_progress! if part_one_progress.nil?
36
+ end
37
+
38
+ def handle_partially_complete!
39
+ part_one_progress&.complete! if part_one_progress&.incomplete?
40
+ create_part_two_progress! if part_two_progress.nil?
41
+ end
42
+
43
+ def handle_fully_complete!
44
+ part_two_progress&.complete! if part_two_progress&.incomplete?
45
+ end
46
+ end
47
+ end
48
+ end
@@ -8,6 +8,7 @@ module AocCli
8
8
 
9
9
  def validate
10
10
  super
11
+ validate_event_stats_set! if errors.empty?
11
12
  validate_event_location_set! if errors.empty?
12
13
  validate_event_dir_exists! if errors.empty?
13
14
  validate_puzzle_dir_does_not_exist! if errors.empty?
@@ -15,6 +16,8 @@ module AocCli
15
16
 
16
17
  def run
17
18
  create_or_update_puzzle!(fetch_content!, fetch_input!).tap do |puzzle|
19
+ sync_puzzle_progress!(puzzle)
20
+
18
21
  attach_puzzle_dir!(puzzle).tap do |location|
19
22
  write_puzzle_files!(puzzle, location)
20
23
  end
@@ -53,6 +56,10 @@ module AocCli
53
56
  end
54
57
  end
55
58
 
59
+ def sync_puzzle_progress!(puzzle)
60
+ ProgressSyncer.run!(puzzle:, stats: event.stats)
61
+ end
62
+
56
63
  def attach_puzzle_dir!(puzzle)
57
64
  puzzle_dir.mkdir
58
65
 
@@ -63,6 +70,14 @@ module AocCli
63
70
  PuzzleDirSynchroniser.run!(puzzle:, location:)
64
71
  end
65
72
 
73
+ def validate_event_stats_set!
74
+ return unless event.stats.nil?
75
+
76
+ errors << Kangaru::Validation::Error.new(
77
+ attribute: :event_stats, message: "can't be blank"
78
+ )
79
+ end
80
+
66
81
  def validate_event_location_set!
67
82
  return unless event.location.nil?
68
83
 
@@ -39,8 +39,8 @@ module AocCli
39
39
 
40
40
  def advance_puzzle!
41
41
  event.stats.advance_progress!(day)
42
- puzzle.mark_complete!(level)
43
42
 
43
+ ProgressSyncer.run!(puzzle:, stats: event.stats.reload)
44
44
  PuzzleDirSynchroniser.run!(puzzle:, location:, skip_cache: true)
45
45
  end
46
46
 
@@ -1,3 +1,3 @@
1
1
  module AocCli
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.0.1".freeze
3
3
  end
data/lib/aoc_cli.rb CHANGED
@@ -14,9 +14,13 @@ module AocCli
14
14
  config_path "spec/aoc.yml", env: :test
15
15
 
16
16
  configure do |config|
17
+ migration_path = File.join(
18
+ File.expand_path(__dir__ || raise), "../db/migrate"
19
+ )
20
+
17
21
  config.database.adaptor = :sqlite
18
22
  config.database.path = File.expand_path("~/.local/share/aoc/aoc.sqlite3")
19
- config.database.migration_path = "db/migrate"
23
+ config.database.migration_path = migration_path
20
24
  end
21
25
 
22
26
  configure env: :test do |config|
@@ -6,7 +6,7 @@ gems:
6
6
  source:
7
7
  type: git
8
8
  name: ruby/gem_rbs_collection
9
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
9
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
10
10
  remote: https://github.com/ruby/gem_rbs_collection.git
11
11
  repo_dir: gems
12
12
  - name: addressable
@@ -14,7 +14,7 @@ gems:
14
14
  source:
15
15
  type: git
16
16
  name: ruby/gem_rbs_collection
17
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
17
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
18
18
  remote: https://github.com/ruby/gem_rbs_collection.git
19
19
  repo_dir: gems
20
20
  - name: base64
@@ -42,7 +42,7 @@ gems:
42
42
  source:
43
43
  type: git
44
44
  name: ruby/gem_rbs_collection
45
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
45
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
46
46
  remote: https://github.com/ruby/gem_rbs_collection.git
47
47
  repo_dir: gems
48
48
  - name: connection_pool
@@ -50,7 +50,7 @@ gems:
50
50
  source:
51
51
  type: git
52
52
  name: ruby/gem_rbs_collection
53
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
53
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
54
54
  remote: https://github.com/ruby/gem_rbs_collection.git
55
55
  repo_dir: gems
56
56
  - name: date
@@ -74,7 +74,7 @@ gems:
74
74
  source:
75
75
  type: git
76
76
  name: ruby/gem_rbs_collection
77
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
77
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
78
78
  remote: https://github.com/ruby/gem_rbs_collection.git
79
79
  repo_dir: gems
80
80
  - name: i18n
@@ -82,7 +82,7 @@ gems:
82
82
  source:
83
83
  type: git
84
84
  name: ruby/gem_rbs_collection
85
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
85
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
86
86
  remote: https://github.com/ruby/gem_rbs_collection.git
87
87
  repo_dir: gems
88
88
  - name: kangaru
@@ -114,7 +114,7 @@ gems:
114
114
  source:
115
115
  type: git
116
116
  name: ruby/gem_rbs_collection
117
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
117
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
118
118
  remote: https://github.com/ruby/gem_rbs_collection.git
119
119
  repo_dir: gems
120
120
  - name: pathname
@@ -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
@@ -9,8 +9,6 @@ module AocCli
9
9
  attr_accessor input: String
10
10
  attr_accessor created_at: Time
11
11
  attr_accessor updated_at: Time
12
- attr_accessor part_one_completed_at: Time
13
- attr_accessor part_two_completed_at: Time
14
12
 
15
13
  attr_accessor location: Location
16
14
  attr_accessor location_dataset: Sequel::Dataset
@@ -18,11 +16,12 @@ module AocCli
18
16
  attr_accessor attempts: Array[Attempt]
19
17
  attr_accessor attempts_dataset: Sequel::Dataset
20
18
 
19
+ attr_accessor part_one_progress: Progress?
20
+ attr_accessor part_two_progress: Progress?
21
+
21
22
  # Delegated to event
22
23
  def year: -> Integer
23
24
 
24
25
  attr_reader presenter: Presenters::PuzzlePresenter
25
-
26
- def mark_complete!: (Integer) -> void
27
26
  end
28
27
  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
@@ -23,10 +23,14 @@ module AocCli
23
23
 
24
24
  def create_or_update_puzzle!: (String, String) -> Puzzle
25
25
 
26
+ def sync_puzzle_progress!: (Puzzle) -> void
27
+
26
28
  def attach_puzzle_dir!: (Puzzle) -> Location
27
29
 
28
30
  def write_puzzle_files!: (Puzzle, Location) -> PuzzleDirSyncLog
29
31
 
32
+ def validate_event_stats_set!: -> void
33
+
30
34
  def validate_event_location_set!: -> void
31
35
 
32
36
  def validate_event_dir_exists!: -> void
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aoc_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Welham
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-20 00:00:00.000000000 Z
11
+ date: 2024-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -123,6 +123,8 @@ files:
123
123
  - db/migrate/4_create_attempts.rb
124
124
  - db/migrate/5_create_locations.rb
125
125
  - db/migrate/6_create_puzzle_dir_sync_logs.rb
126
+ - db/migrate/7_create_progresses.rb
127
+ - db/migrate/8_remove_legacy_timestamps.rb
126
128
  - exe/aoc
127
129
  - lib/aoc_cli.rb
128
130
  - lib/aoc_cli/components/attempts_table.erb
@@ -155,6 +157,7 @@ files:
155
157
  - lib/aoc_cli/models/attempt.rb
156
158
  - lib/aoc_cli/models/event.rb
157
159
  - lib/aoc_cli/models/location.rb
160
+ - lib/aoc_cli/models/progress.rb
158
161
  - lib/aoc_cli/models/puzzle.rb
159
162
  - lib/aoc_cli/models/puzzle_dir_sync_log.rb
160
163
  - lib/aoc_cli/models/stats.rb
@@ -162,6 +165,7 @@ files:
162
165
  - lib/aoc_cli/presenters/puzzle_presenter.rb
163
166
  - lib/aoc_cli/presenters/stats_presenter.rb
164
167
  - lib/aoc_cli/processors/event_initialiser.rb
168
+ - lib/aoc_cli/processors/progress_syncer.rb
165
169
  - lib/aoc_cli/processors/puzzle_dir_synchroniser.rb
166
170
  - lib/aoc_cli/processors/puzzle_initialiser.rb
167
171
  - lib/aoc_cli/processors/puzzle_refresher.rb
@@ -215,6 +219,7 @@ files:
215
219
  - sig/aoc_cli/models/attempt.rbs
216
220
  - sig/aoc_cli/models/event.rbs
217
221
  - sig/aoc_cli/models/location.rbs
222
+ - sig/aoc_cli/models/progress.rbs
218
223
  - sig/aoc_cli/models/puzzle.rbs
219
224
  - sig/aoc_cli/models/puzzle_dir_sync_log.rbs
220
225
  - sig/aoc_cli/models/stats.rbs
@@ -222,6 +227,7 @@ files:
222
227
  - sig/aoc_cli/presenters/puzzle_presenter.rbs
223
228
  - sig/aoc_cli/presenters/stats_presenter.rbs
224
229
  - sig/aoc_cli/processors/event_initialiser.rbs
230
+ - sig/aoc_cli/processors/progress_syncer.rbs
225
231
  - sig/aoc_cli/processors/puzzle_dir_synchroniser.rbs
226
232
  - sig/aoc_cli/processors/puzzle_initialiser.rbs
227
233
  - sig/aoc_cli/processors/puzzle_refresher.rbs
@@ -249,6 +255,7 @@ post_install_message:
249
255
  rdoc_options: []
250
256
  require_paths:
251
257
  - lib
258
+ - db
252
259
  required_ruby_version: !ruby/object:Gem::Requirement
253
260
  requirements:
254
261
  - - ">="