reading 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/bin/reading +80 -10
  3. data/lib/reading/config.rb +27 -5
  4. data/lib/reading/errors.rb +4 -1
  5. data/lib/reading/item/time_length.rb +60 -23
  6. data/lib/reading/item/view.rb +14 -19
  7. data/lib/reading/item.rb +321 -54
  8. data/lib/reading/parsing/attributes/attribute.rb +0 -7
  9. data/lib/reading/parsing/attributes/experiences/dates_and_head_transformer.rb +10 -11
  10. data/lib/reading/parsing/attributes/experiences/history_transformer.rb +27 -18
  11. data/lib/reading/parsing/attributes/experiences/spans_validator.rb +18 -19
  12. data/lib/reading/parsing/attributes/experiences.rb +5 -5
  13. data/lib/reading/parsing/attributes/shared.rb +13 -6
  14. data/lib/reading/parsing/attributes/variants.rb +9 -6
  15. data/lib/reading/parsing/csv.rb +38 -35
  16. data/lib/reading/parsing/parser.rb +23 -24
  17. data/lib/reading/parsing/rows/blank.rb +23 -0
  18. data/lib/reading/parsing/rows/comment.rb +6 -7
  19. data/lib/reading/parsing/rows/compact_planned.rb +9 -9
  20. data/lib/reading/parsing/rows/compact_planned_columns/head.rb +2 -2
  21. data/lib/reading/parsing/rows/custom_config.rb +42 -0
  22. data/lib/reading/parsing/rows/regular.rb +15 -14
  23. data/lib/reading/parsing/rows/regular_columns/length.rb +8 -8
  24. data/lib/reading/parsing/rows/regular_columns/sources.rb +15 -9
  25. data/lib/reading/parsing/transformer.rb +13 -17
  26. data/lib/reading/stats/filter.rb +738 -0
  27. data/lib/reading/stats/grouping.rb +243 -0
  28. data/lib/reading/stats/operation.rb +313 -0
  29. data/lib/reading/stats/query.rb +37 -0
  30. data/lib/reading/stats/terminal_result_formatters.rb +91 -0
  31. data/lib/reading/util/exclude.rb +12 -0
  32. data/lib/reading/util/hash_to_data.rb +2 -2
  33. data/lib/reading/version.rb +1 -1
  34. data/lib/reading.rb +36 -21
  35. metadata +10 -6
  36. data/bin/readingfile +0 -31
  37. data/lib/reading/util/string_remove.rb +0 -28
  38. data/lib/reading/util/string_truncate.rb +0 -22
@@ -15,16 +15,16 @@ module Reading
15
15
  )
16
16
  (\s+|\z)
17
17
  )
18
- # each or repetitions, used in conjunction with the History column
18
+ # each and repetitions are used in conjunction with the History column
19
+ # each
19
20
  (
20
- # each
21
21
  (?<each>each)
22
- |
23
- # repetitions
24
- (
25
- x
26
- (?<repetitions>\d+)
27
- )
22
+ (\s+|\z)
23
+ )?
24
+ # repetitions
25
+ (
26
+ x
27
+ (?<repetitions>\d+)
28
28
  )?
29
29
  \z}x]
30
30
  end
@@ -6,17 +6,12 @@ module Reading
6
6
  # and https://github.com/fpsvogel/reading/blob/main/doc/csv-format.md#sources-column-variants
7
7
  class Sources < Column
8
8
  SOURCES_PARSING_ERRORS = {
9
- "Missing comma before URL(s) in the Sources column" =>
10
- ->(source) {
11
- source.match?(/\shttps?:\/\//) || source.scan(/https?:\/\//).count > 1
12
- },
13
- "The ISBN/ASIN must be placed after sources in the Sources column" =>
9
+ "The ISBN/ASIN must be placed last in the Sources column" =>
14
10
  ->(source) {
15
11
  source.match?(/\A#{ISBN_REGEX}/o) || source.match(/\A#{ASIN_REGEX}/o)
16
12
  },
17
13
  }
18
14
 
19
-
20
15
  def self.split_by_format?
21
16
  true
22
17
  end
@@ -32,7 +27,18 @@ module Reading
32
27
  def self.tweaks
33
28
  {
34
29
  sources: -> {
35
- sources = _1.split(/\s*,\s*/)
30
+ comma = /\s*,\s*/
31
+ space_before_url = / (?=https?:\/\/)/
32
+ sources = _1.split(Regexp.union(comma, space_before_url))
33
+
34
+ # Split by space after URL.
35
+ sources = sources.flat_map { |src|
36
+ if src.match?(/\Ahttps?:\/\//)
37
+ src.split(" ", 2)
38
+ else
39
+ src
40
+ end
41
+ }
36
42
 
37
43
  SOURCES_PARSING_ERRORS.each do |message, check|
38
44
  if sources.any? { |source| check.call(source) }
@@ -58,7 +64,7 @@ module Reading
58
64
  |
59
65
  (?<length_time>\d+:\d\d)
60
66
  )?
61
- \z}x if segment_index.zero?),
67
+ \z}x if segment_index.zero?),
62
68
  # sources, ISBN/ASIN, length
63
69
  (%r{\A
64
70
  (
@@ -78,7 +84,7 @@ module Reading
78
84
  |
79
85
  (?<length_time>\d+:\d\d)
80
86
  )?
81
- \z}xo if segment_index.zero?),
87
+ \z}xo if segment_index.zero?),
82
88
  *Column::SHARED_REGEXES[:series_and_extra_info],
83
89
  ].compact
84
90
  end
@@ -1,12 +1,12 @@
1
- require_relative "attributes/shared"
2
- require_relative "attributes/attribute"
3
- require_relative "attributes/rating"
4
- require_relative "attributes/author"
5
- require_relative "attributes/title"
6
- require_relative "attributes/genres"
7
- require_relative "attributes/variants"
8
- require_relative "attributes/experiences"
9
- require_relative "attributes/notes"
1
+ require_relative 'attributes/shared'
2
+ require_relative 'attributes/attribute'
3
+ require_relative 'attributes/rating'
4
+ require_relative 'attributes/author'
5
+ require_relative 'attributes/title'
6
+ require_relative 'attributes/genres'
7
+ require_relative 'attributes/variants'
8
+ require_relative 'attributes/experiences'
9
+ require_relative 'attributes/notes'
10
10
 
11
11
  module Reading
12
12
  module Parsing
@@ -20,13 +20,9 @@ module Reading
20
20
  using Util::HashArrayDeepFetch
21
21
  using Util::HashCompactByTemplate
22
22
 
23
- attr_reader :config
24
23
  private attr_reader :attributes
25
24
 
26
- # @param config [Hash] an entire config.
27
- def initialize(config)
28
- @config = config
29
-
25
+ def initialize
30
26
  set_attributes
31
27
  end
32
28
 
@@ -40,7 +36,7 @@ module Reading
40
36
  raise InvalidHeadError, "Blank or missing Head column"
41
37
  end
42
38
 
43
- template = config.deep_fetch(:item, :template)
39
+ template = Config.hash.deep_fetch(:item, :template)
44
40
 
45
41
  parsed_row[:head].map.with_index { |_head, head_index|
46
42
  template.map { |attribute_name, default_value|
@@ -58,11 +54,11 @@ module Reading
58
54
  # Sets the attributes classes which do all the transforming work.
59
55
  # See parsing/attributes/*.
60
56
  def set_attributes
61
- @attributes ||= config.deep_fetch(:item, :template).map { |attribute_name, _default|
57
+ @attributes ||= Config.hash.deep_fetch(:item, :template).map { |attribute_name, _default|
62
58
  attribute_name_camelcase = attribute_name.to_s.split("_").map(&:capitalize).join
63
59
  attribute_class = Attributes.const_get(attribute_name_camelcase)
64
60
 
65
- [attribute_name, attribute_class.new(config)]
61
+ [attribute_name, attribute_class.new]
66
62
  }.to_h
67
63
  end
68
64
  end