reading 0.8.0 → 0.9.0

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.
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