piotr_majewski_magic 0.0.3 → 0.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54f030e5007aa276f96f57d2ddf36a80279a6a43526c2dd3e0eaf6104952c120
4
- data.tar.gz: 735e920318f6d5b0e80cf3bbfb15db6d58b6f39ed29680b4c25e12051be76272
3
+ metadata.gz: ed5b3f6e3f03be200af1ad183e2018e7f6d8d1eafe176e9cd8fd36b390996794
4
+ data.tar.gz: bc1e6106249788a6557ac3834754e21984c4e69f93269d9885b74a23a6b22e12
5
5
  SHA512:
6
- metadata.gz: a7b0f349504dfcb6ffa8fad4db778e90b6870e5acbe62eb31d240cea6d09773b0cfc743bba877a5d20acb7970613f466a7b9a4001d08523cc7d17c316d1c7db6
7
- data.tar.gz: ba7fa731574493015ad361929c0a53e9d105f357ce1bb52300188c0d234b8ea7190995d8fcc84553d8d4bb27a65deca2106f44cd90f7f9d1b3a60130a846d9c2
6
+ metadata.gz: b0f242a31a2a4abb76daa022d29949c4a9808ec898df2f26c4cb0da5f3b86520063def5d25931e88bc3db5372af2e96dbb6f922190de34b0b8fe99269f54f451
7
+ data.tar.gz: 3c10ce8899227c17b46e4be6d87843b00e66dcab3aa2fc1d60c4a2cfdce9dfb8b72c205e21a28fe01ae93f2c708b8b49eda7b84592bb84665047f1ad8ddbe2f8
@@ -3,13 +3,13 @@
3
3
  require 'json'
4
4
  require_relative 'mtg_api_response'
5
5
 
6
- class CardsSource
6
+ class Cards
7
7
  def self.get(no_cache = nil)
8
8
  new(no_cache).get
9
9
  end
10
10
 
11
11
  def get
12
- JSON.parse(cards_source)
12
+ JSON.parse(cards)
13
13
  end
14
14
 
15
15
  private
@@ -20,14 +20,21 @@ class CardsSource
20
20
  @no_cache = no_cache
21
21
  end
22
22
 
23
- def cards_source
24
- return File.read(cache_file_path) if File.file?(cache_file_path) && !no_cache
23
+ def cards
24
+ fetch_and_save_cards_from_api if no_cache || cache_empty?
25
25
 
26
- cache_cards
26
+ read_cache
27
+ end
28
+
29
+ def read_cache
27
30
  File.read(cache_file_path)
28
31
  end
29
32
 
30
- def cache_cards
33
+ def cache_empty?
34
+ File.size(cache_file_path).zero?
35
+ end
36
+
37
+ def fetch_and_save_cards_from_api
31
38
  File.open(cache_file_path, 'w') do |file|
32
39
  file.write(MtgApiResponse.results)
33
40
  end
data/lib/cards_manager.rb CHANGED
@@ -22,15 +22,16 @@ class CardsManager
22
22
  private
23
23
 
24
24
  def group_and_select(query, cards)
25
- raise UnknownAttribute unless cards.first.key?(query[0][:attribute])
25
+ attribute = query[0][:attribute]
26
+ unknown_attribute(attribute) unless cards.first.key?(attribute)
26
27
 
27
28
  selected_cards = matching_cards(query[0], cards)
28
29
  new_query = query[1..]
29
30
 
30
31
  return selected_cards if new_query.empty?
31
32
 
32
- selected_cards.map.with_object({}) do |(attribute_value, cards), hash|
33
- hash[attribute_value] = group_and_select(new_query, cards)
33
+ selected_cards.map.with_object({}) do |(attribute_value, card_set), hash|
34
+ hash[attribute_value] = group_and_select(new_query, card_set)
34
35
  end
35
36
  end
36
37
 
@@ -46,6 +47,14 @@ class CardsManager
46
47
 
47
48
  cli_value.tally == source_value&.tally
48
49
  rescue NoMethodError
50
+ invalid_value(cli_value)
51
+ end
52
+
53
+ def unknown_attribute(attribute)
54
+ raise UnknownAttribute, "`#{attribute}`: Is not an MTG card attribute"
55
+ end
56
+
57
+ def invalid_value(cli_value)
49
58
  message = "`#{cli_value}`: Type of provided value doesn't match type of card attribute"
50
59
  raise InvalidValue, message
51
60
  end
@@ -30,10 +30,10 @@ class MtgApiRequest
30
30
  private
31
31
 
32
32
  def unfetched_pages
33
- @unfetched_pages ||= (1..total_count).to_a
33
+ @unfetched_pages ||= (1..total_page_count).to_a
34
34
  end
35
35
 
36
- def total_count
36
+ def total_page_count
37
37
  response = Faraday.get(URL)
38
38
  (response.headers['total-count'].to_f / 100).ceil
39
39
  end
data/lib/query.rb CHANGED
@@ -5,6 +5,9 @@ require 'forwardable'
5
5
  class Query
6
6
  extend Forwardable
7
7
 
8
+ ATTRIBUTE_AND_VALUE_DIVIDERS = /(?<!~)=/.freeze
9
+ VALUE_TO_LIST_DIVIDERS = /(?<!~)&/.freeze
10
+
8
11
  RepeatedFilter = Class.new(StandardError)
9
12
  Group = Class.new
10
13
 
@@ -16,11 +19,10 @@ class Query
16
19
 
17
20
  def build
18
21
  @build ||= argv.map.with_object([]) do |argument, query_options|
19
- query_element = parse_argument(argument)
22
+ query_element = query_element(argument)
20
23
 
21
24
  if query_options.find { |el| el[:attribute] == query_element[:attribute] }
22
- message = "#{query_element[:attribute]}: Every filter can be passed only once"
23
- raise RepeatedFilter, message
25
+ repeated_filter(query_element[:attribute])
24
26
  end
25
27
 
26
28
  query_options << query_element
@@ -31,15 +33,35 @@ class Query
31
33
 
32
34
  private
33
35
 
34
- # TODO: pick a divider (something that is unlikely to show up)
35
- # potential problem with imageUrl values
36
- # NOTE: should allow escaping `#`
37
- def parse_argument(argument)
38
- return { attribute: argument, value: Group } unless argument.match?('=')
36
+ def query_element(argument)
37
+ return { attribute: argument, value: Group } unless argument.match?(ATTRIBUTE_AND_VALUE_DIVIDERS)
38
+
39
+ attribute, value = argument.split(ATTRIBUTE_AND_VALUE_DIVIDERS)
40
+
41
+ {
42
+ attribute: sanitize(attribute),
43
+ value: sanitize(parse_value(value))
44
+ }
45
+ end
46
+
47
+ def parse_value(value)
48
+ return value unless value&.match?(VALUE_TO_LIST_DIVIDERS)
39
49
 
40
- attribute, value = argument.split('=')
41
- value = value&.match?('#') ? value.split('#') : value
50
+ value.split(VALUE_TO_LIST_DIVIDERS)
51
+ end
52
+
53
+ def sanitize(query_part)
54
+ return unless query_part
55
+
56
+ if query_part.is_a?(String)
57
+ query_part.gsub(/~=/, '=').gsub(/~&/, '&')
58
+ else
59
+ query_part.map { |part| sanitize(part) }
60
+ end
61
+ end
42
62
 
43
- { attribute: attribute, value: value }
63
+ def repeated_filter(attribute)
64
+ message = "#{attribute}: Every filter can be passed only once"
65
+ raise RepeatedFilter, message
44
66
  end
45
67
  end
data/lib/query_mtg.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'json'
4
4
  require_relative 'cards_manager'
5
5
  require_relative 'query'
6
- require_relative 'cards_source'
6
+ require_relative 'cards'
7
7
 
8
8
  class QueryMtg
9
9
  def self.call(argv)
@@ -34,6 +34,6 @@ class QueryMtg
34
34
  end
35
35
 
36
36
  def cards_source
37
- CardsSource.get(no_cache)
37
+ Cards.get(no_cache)
38
38
  end
39
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: piotr_majewski_magic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Majewski
@@ -48,8 +48,8 @@ extra_rdoc_files: []
48
48
  files:
49
49
  - bin/query_mtg
50
50
  - cache/cards.json
51
+ - lib/cards.rb
51
52
  - lib/cards_manager.rb
52
- - lib/cards_source.rb
53
53
  - lib/mtg_api_request.rb
54
54
  - lib/mtg_api_response.rb
55
55
  - lib/query.rb