reading 1.1.2 → 1.3.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.
- checksums.yaml +4 -4
- data/lib/reading/config.rb +4 -0
- data/lib/reading/filter.rb +15 -3
- data/lib/reading/parsing/attributes/notes.rb +33 -1
- data/lib/reading/parsing/rows/regular_columns/history.rb +1 -1
- data/lib/reading/parsing/rows/regular_columns/notes.rb +18 -2
- data/lib/reading/parsing/rows/regular_columns/start_dates.rb +1 -1
- data/lib/reading/stats/filter.rb +32 -0
- data/lib/reading/stats/operation.rb +1 -1
- data/lib/reading/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a081fbab3e05154fcd493884223c2eedcc0c60dd4be99d56f2373ef5689d337
|
|
4
|
+
data.tar.gz: e7f4dfef59413ce4ade78d2452193bec233482700cecee699655a1ea72a5e499
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 45e98e729dd0422b5e0e2abe014f8bab41190b5bd4d3df6969097a60c5738dace9c190bea8e82476c8de880a5d1c34772caf0d9957a975ce417c663190128b11
|
|
7
|
+
data.tar.gz: f5a9e4645ccc2b6b9a076197c1df92efb6f2219f51de1c7b8d746d08c98b4457aef143702cfabdf0b86eac4ac80bab56324814badae9bf739e56bcf4d49cd64f
|
data/lib/reading/config.rb
CHANGED
|
@@ -105,6 +105,7 @@ module Reading
|
|
|
105
105
|
course: "🏫",
|
|
106
106
|
piece: "✏️",
|
|
107
107
|
website: "🌐",
|
|
108
|
+
game: "🎲",
|
|
108
109
|
},
|
|
109
110
|
source_names_from_urls:
|
|
110
111
|
{
|
|
@@ -135,6 +136,7 @@ module Reading
|
|
|
135
136
|
piece: { emoji: "✏️" },
|
|
136
137
|
video: { emoji: "🎞️" },
|
|
137
138
|
audio: { emoji: "🎤" },
|
|
139
|
+
game: { emoji: "🎲" },
|
|
138
140
|
},
|
|
139
141
|
default_type: :book,
|
|
140
142
|
},
|
|
@@ -191,6 +193,8 @@ module Reading
|
|
|
191
193
|
[{
|
|
192
194
|
blurb?: false,
|
|
193
195
|
private?: false,
|
|
196
|
+
date: nil,
|
|
197
|
+
rating_change: [],
|
|
194
198
|
content: nil,
|
|
195
199
|
}],
|
|
196
200
|
},
|
data/lib/reading/filter.rb
CHANGED
|
@@ -60,9 +60,21 @@ module Reading
|
|
|
60
60
|
return items unless minimum_rating
|
|
61
61
|
|
|
62
62
|
items.select! do |item|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
item.rating && item.rating >= minimum_rating
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Mutates the given array of Items to select only Items that were at some
|
|
68
|
+
# point greater than or equal to (but are now less than) the given minimum.
|
|
69
|
+
# @param items [Array<Item>]
|
|
70
|
+
# @param minimum_rating [Integer]
|
|
71
|
+
def by_minimum_previous_rating!(items, minimum_previous_rating)
|
|
72
|
+
return items unless minimum_previous_rating
|
|
73
|
+
|
|
74
|
+
items.select! do |item|
|
|
75
|
+
max_previous_rating = item.notes.map { it.rating_change.first }.compact.max
|
|
76
|
+
max_previous_rating && max_previous_rating >= minimum_previous_rating &&
|
|
77
|
+
item.rating && item.rating < minimum_previous_rating
|
|
66
78
|
end
|
|
67
79
|
end
|
|
68
80
|
|
|
@@ -12,9 +12,41 @@ module Reading
|
|
|
12
12
|
{
|
|
13
13
|
blurb?: note.has_key?(:blurb),
|
|
14
14
|
private?: note.has_key?(:private),
|
|
15
|
+
date: date(note[:date]),
|
|
16
|
+
rating_change: rating_change(note[:rating_from], note[:rating_to]),
|
|
15
17
|
content: note[:content],
|
|
16
18
|
}
|
|
17
|
-
}
|
|
19
|
+
}.then { distribute_dates_to_rating_changes!(it, parsed_row) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def date(date_string)
|
|
25
|
+
return nil unless date_string
|
|
26
|
+
|
|
27
|
+
Date.parse(date_string)
|
|
28
|
+
rescue Date::Error
|
|
29
|
+
raise InvalidDateError, "Unparsable date \"#{date_string}\""
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def rating_change(rating_from, rating_to)
|
|
33
|
+
return [] unless rating_from && rating_to
|
|
34
|
+
|
|
35
|
+
[Integer(rating_from), Integer(rating_to)]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Rating change notes without dates are automatically given the end or
|
|
39
|
+
# start dates of the item's experiences in reverse order.
|
|
40
|
+
def distribute_dates_to_rating_changes!(transformed_notes, parsed_row)
|
|
41
|
+
return unless transformed_notes
|
|
42
|
+
experiences = Experiences.new.transform_from_parsed(parsed_row, 0)
|
|
43
|
+
|
|
44
|
+
transformed_notes.reverse_each do |note|
|
|
45
|
+
return if experiences.empty?
|
|
46
|
+
next if note[:rating_change].empty? || note[:date]
|
|
47
|
+
last_experience = experiences.pop
|
|
48
|
+
note[:date] = last_experience[:spans].last[:dates]&.end || last_experience[:spans].first[:dates]&.begin
|
|
49
|
+
end
|
|
18
50
|
end
|
|
19
51
|
end
|
|
20
52
|
end
|
|
@@ -11,8 +11,24 @@ module Reading
|
|
|
11
11
|
|
|
12
12
|
def self.regexes(segment_index)
|
|
13
13
|
[%r{\A
|
|
14
|
-
(?:(?<blurb>💬)|(?<private>🔒))?
|
|
15
|
-
|
|
14
|
+
(?:(?<blurb>💬)|(?<private>🔒))?
|
|
15
|
+
(?<date>\d{4}/\d\d?/\d\d?)?:?\s*
|
|
16
|
+
(?:
|
|
17
|
+
(?:
|
|
18
|
+
(?:downgraded|upgraded|updated|changed)?\s*rating
|
|
19
|
+
|
|
|
20
|
+
rating\s*(?:downgraded|upgraded|updated|changed)?
|
|
21
|
+
)?
|
|
22
|
+
(?:\s+from\s+)?
|
|
23
|
+
(?:
|
|
24
|
+
(?<rating_from>\d)
|
|
25
|
+
\s+to\s+
|
|
26
|
+
(?<rating_to>\d)
|
|
27
|
+
)
|
|
28
|
+
(?:\s+because\s+|\s*[[:punct:]]\s*)?
|
|
29
|
+
)?
|
|
30
|
+
(?<content>.+)?
|
|
31
|
+
\z}xi]
|
|
16
32
|
end
|
|
17
33
|
end
|
|
18
34
|
end
|
data/lib/reading/stats/filter.rb
CHANGED
|
@@ -101,6 +101,36 @@ module Reading
|
|
|
101
101
|
|
|
102
102
|
matches
|
|
103
103
|
},
|
|
104
|
+
:"previous-rating" => proc { |values, operator, items|
|
|
105
|
+
previous_ratings = values.map { |value|
|
|
106
|
+
if value
|
|
107
|
+
Integer(value, exception: false) ||
|
|
108
|
+
Float(value, exception: false) ||
|
|
109
|
+
(raise InputError, "Previous rating must be a number")
|
|
110
|
+
end
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
positive_operator = operator == :"!=" ? :== : operator
|
|
114
|
+
|
|
115
|
+
matches = items.select { |item|
|
|
116
|
+
actual_previous_ratings = item.notes.map { it.rating_change.first }.compact
|
|
117
|
+
|
|
118
|
+
previous_ratings.any? { |previous_rating|
|
|
119
|
+
if !actual_previous_ratings.empty? || %i[== !=].include?(operator)
|
|
120
|
+
actual_previous_ratings.any? { it.send(positive_operator, previous_rating) }
|
|
121
|
+
end
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# Instead of using it.send(operator, format) above, invert the matches
|
|
126
|
+
# here to ensure multiple values after a negative operator have an
|
|
127
|
+
# "and" relation: "not(x and y)", rather than "not(x or y)".
|
|
128
|
+
if operator == :"!="
|
|
129
|
+
matches = items - matches
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
matches
|
|
133
|
+
},
|
|
104
134
|
progress: proc { |values, operator, items|
|
|
105
135
|
progresses = values.map { |value|
|
|
106
136
|
value = "0%" if value == "0"
|
|
@@ -640,6 +670,7 @@ module Reading
|
|
|
640
670
|
|
|
641
671
|
NUMERIC_OPERATORS = {
|
|
642
672
|
rating: true,
|
|
673
|
+
:"previous-rating" => true,
|
|
643
674
|
progress: true,
|
|
644
675
|
experience: true,
|
|
645
676
|
date: true,
|
|
@@ -654,6 +685,7 @@ module Reading
|
|
|
654
685
|
}
|
|
655
686
|
|
|
656
687
|
PROHIBIT_NONE_VALUE = {
|
|
688
|
+
:"previous-rating" => true,
|
|
657
689
|
progress: true,
|
|
658
690
|
title: true,
|
|
659
691
|
:"end-date" => true,
|
data/lib/reading/version.rb
CHANGED