toilet_tracker 0.1.1 β 0.2.1
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/CHANGELOG.md +24 -0
- data/PARSING_SPEC.md +32 -2
- data/lib/toilet_tracker/configuration.rb +31 -30
- data/lib/toilet_tracker/core/parse_result.rb +4 -4
- data/lib/toilet_tracker/parsers/base_parser.rb +15 -0
- data/lib/toilet_tracker/parsers/message_parser.rb +46 -25
- data/lib/toilet_tracker/version.rb +1 -1
- metadata +17 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4e179c9943225797758be0ca803a1dcde9ee9f7b98ee7466d74cb208a49040b8
|
|
4
|
+
data.tar.gz: ea5b5ab8fb0e4da1ca4a8e7e48575bc72a9a967769c375e52e11dcfab3dd4801
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33081c85110a522542ae3c50209cbe5a1d302bb34bb513bc4c6118daaabf0093673e37695a7200818ed77d5e37bd725e22074a7898cd82f63df9518c105beaf9
|
|
7
|
+
data.tar.gz: 0ebf346d3c2afde44224885c4879bad74e1d29203c7c2f567fc573fbc989e48eee71f613257707df3e4b4359a861356111cd1e2395f9035d573259de6d0579c8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.1] - 2025-12-18
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Update activesupport to 8.1.1 (from 8.0.2.1)
|
|
7
|
+
- Update rubyzip to 3.2.2 (from 3.0.1)
|
|
8
|
+
- Update rake to 13.3.1 (from 13.3.0)
|
|
9
|
+
- Update rspec to 3.13.2 (from 3.13.1)
|
|
10
|
+
- Update overcommit to 0.68.0 (from 0.67.1)
|
|
11
|
+
- Relax version constraints for activesupport and rubyzip
|
|
12
|
+
|
|
13
|
+
## [0.2.0] - 2025-12-18
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- Metadata emoji support for both π© and π½ commands
|
|
17
|
+
- Format: `[command emoji] [metadata emojis...] [shift/timezone] [time]`
|
|
18
|
+
- Metadata stored as array of individual emoji strings
|
|
19
|
+
- New `metadata` field on `PoopEventResult` and `ToiletShiftResult`
|
|
20
|
+
- `BaseParser#parse_metadata` and `#metadata_emoji?` helper methods
|
|
21
|
+
- Comprehensive test suite for metadata parsing (28 new tests)
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- All regex patterns updated to capture optional metadata group
|
|
25
|
+
- Result objects now include `metadata: []` by default (backward compatible)
|
|
26
|
+
|
|
3
27
|
## [0.1.1] - 2025-12-18
|
|
4
28
|
|
|
5
29
|
### Added
|
data/PARSING_SPEC.md
CHANGED
|
@@ -20,6 +20,24 @@ All WhatsApp messages follow this format:
|
|
|
20
20
|
- **Functional Shifts**: Applied to event timestamps (patterns 1, 2, 5)
|
|
21
21
|
- **Decorative Shifts**: For statistics only, do not affect timestamps (patterns 7, 9)
|
|
22
22
|
|
|
23
|
+
### Metadata Emojis
|
|
24
|
+
Both π© and π½ commands support optional metadata emojis placed between the command emoji and the time/shift specifications. Metadata emojis are stored as an array and can be used for additional categorization or tagging of events.
|
|
25
|
+
|
|
26
|
+
**Format**: `[command emoji] [metadata emojis...] [shift/timezone] [time]`
|
|
27
|
+
|
|
28
|
+
**Examples**:
|
|
29
|
+
- `π© π©Έ` β Event with metadata `["π©Έ"]`
|
|
30
|
+
- `π© π©Έπ§π₯` β Event with metadata `["π©Έ", "π§", "π₯"]`
|
|
31
|
+
- `π© π©Έ +2` β Event with metadata `["π©Έ"]` and shift `+2`
|
|
32
|
+
- `π½ βοΈπ +5:30` β Setting with metadata `["βοΈ", "π"]` and shift `+5:30`
|
|
33
|
+
|
|
34
|
+
**Behavior**:
|
|
35
|
+
- Metadata is any emoji placed after the command emoji but before time specs
|
|
36
|
+
- Emojis are extracted as individual grapheme clusters (supports complex emojis)
|
|
37
|
+
- Command emojis (π©, π½) are excluded from metadata
|
|
38
|
+
- Stored as an array of strings in result objects
|
|
39
|
+
- Does not affect parsing of shifts, timezones, or times
|
|
40
|
+
|
|
23
41
|
## Supported Parsing Patterns
|
|
24
42
|
|
|
25
43
|
### WhatsApp Message Format
|
|
@@ -262,8 +280,9 @@ When timezone shifts are set retroactively:
|
|
|
262
280
|
type: :shift_set | :shift_set_at_time | :timezone_set,
|
|
263
281
|
status: :ok | :alert | :error,
|
|
264
282
|
message: Core::Message,
|
|
265
|
-
shift: Integer,
|
|
283
|
+
shift: Integer | Float,
|
|
266
284
|
effective_time: Time,
|
|
285
|
+
metadata: Array<String>,
|
|
267
286
|
error_details: String | nil
|
|
268
287
|
}
|
|
269
288
|
```
|
|
@@ -275,9 +294,10 @@ When timezone shifts are set retroactively:
|
|
|
275
294
|
:event_in_timezone | :event_in_timezone_at_time,
|
|
276
295
|
status: :ok | :alert | :error,
|
|
277
296
|
message: Core::Message,
|
|
278
|
-
shift: Integer | nil,
|
|
297
|
+
shift: Integer | Float | nil,
|
|
279
298
|
poop_time: Time,
|
|
280
299
|
timezone: String | nil,
|
|
300
|
+
metadata: Array<String>,
|
|
281
301
|
error_details: String | nil
|
|
282
302
|
}
|
|
283
303
|
```
|
|
@@ -342,6 +362,16 @@ When timezone shifts are set retroactively:
|
|
|
342
362
|
[02/01/25, 15:00:00] Bob: π© PST 2025-01-02 12:00:00
|
|
343
363
|
```
|
|
344
364
|
|
|
365
|
+
### Valid Examples with Metadata
|
|
366
|
+
```
|
|
367
|
+
[01/01/25, 08:30:00] Alice: π© π©Έ # metadata: ["π©Έ"]
|
|
368
|
+
[01/01/25, 10:00:00] Alice: π© π©Έπ§ +2 # metadata: ["π©Έ", "π§"], shift: 2
|
|
369
|
+
[01/01/25, 12:00:00] Alice: π© π§± 14:30 # metadata: ["π§±"], time: 14:30
|
|
370
|
+
[01/01/25, 14:00:00] Alice: π© π₯ +2 2025-01-01 13:00 # metadata + shift + time
|
|
371
|
+
[02/01/25, 09:00:00] Bob: π½ βοΈ +5:30 # metadata: ["βοΈ"], shift: 5.5
|
|
372
|
+
[02/01/25, 10:00:00] Bob: π½ π βοΈ Europe/Rome # metadata: ["π ", "βοΈ"], timezone
|
|
373
|
+
```
|
|
374
|
+
|
|
345
375
|
### Invalid Examples
|
|
346
376
|
```
|
|
347
377
|
[01/01/25, 10:00:00] Alice: π½ +25 # Exceeds max_shift_hours
|
|
@@ -9,37 +9,38 @@ module ToiletTracker
|
|
|
9
9
|
def initialize
|
|
10
10
|
@default_timezone = "UTC"
|
|
11
11
|
@max_shift_hours = 12
|
|
12
|
+
# Capture group 1 is always metadata emojis, subsequent groups are pattern-specific
|
|
12
13
|
@message_patterns = {
|
|
13
|
-
# π© 14:30
|
|
14
|
-
event_at_time_only: /π©\s*(\d{1,2}:\d{2})$/,
|
|
15
|
-
# π© +5 14:30, π© +5:30 14:30
|
|
16
|
-
event_at_time_only_shifted: /π©\s*([+-]?\d+(?::\d{2})?)\s+(\d{1,2}:\d{2})$/,
|
|
17
|
-
# π© Asia/Kolkata 14:30
|
|
18
|
-
event_in_timezone_at_time_only: %r{π©\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{1,2}:\d{2})$},
|
|
19
|
-
# π½ +5 14:30, π½ +5:30 14:30
|
|
20
|
-
shift_set_at_time_only: /π½\s*([+-]?\d+(?::\d{2})?)\s+(\d{1,2}:\d{2})$/,
|
|
21
|
-
# π½ Asia/Kolkata 14:30
|
|
22
|
-
timezone_set_at_time_only: %r{π½\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{1,2}:\d{2})$},
|
|
23
|
-
# π½ +2, π½ -3, π½ +5:30
|
|
24
|
-
shift_set: /π½\s*([+-]?\d+(?::\d{2})?)$/,
|
|
25
|
-
# π½ +2 2025-01-15 14:30, π½ +5:30 2025-01-15 14:30
|
|
26
|
-
shift_set_at_time: %r{π½\s*([+-]?\d+(?::\d{2})?)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
27
|
-
# π½ Europe/Rome, π½ PST
|
|
28
|
-
timezone_set: %r{π½\s*([A-Za-z_/][A-Za-z0-9_/+-]*)$},
|
|
29
|
-
# π½ Asia/Kolkata 2025-01-15 14:30
|
|
30
|
-
timezone_set_at_time: %r{π½\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
31
|
-
# π©
|
|
32
|
-
event_now:
|
|
33
|
-
# π© +2, π© -1, π© +5:30
|
|
34
|
-
event_now_shifted: /π©\s*([+-]?\d+(?::\d{2})?)$/,
|
|
35
|
-
# π© 2025-01-15 14:30
|
|
36
|
-
event_at_time: %r{π©\s*(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
37
|
-
# π© +2 2025-01-15 14:30, π© +5:30 2025-01-15 14:30
|
|
38
|
-
event_at_time_shifted: %r{π©\s*([+-]?\d+(?::\d{2})?)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
39
|
-
# π© Europe/Rome, π© PST
|
|
40
|
-
event_in_timezone: %r{π©\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s*$},
|
|
41
|
-
# π© Asia/Kolkata 2025-01-15 14:30
|
|
42
|
-
event_in_timezone_at_time: %r{π©\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$}
|
|
14
|
+
# π© π©Έ 14:30
|
|
15
|
+
event_at_time_only: /π©\s*([^+\-\dA-Za-z\s]*)\s*(\d{1,2}:\d{2})$/,
|
|
16
|
+
# π© π©Έ +5 14:30, π© π©Έ +5:30 14:30
|
|
17
|
+
event_at_time_only_shifted: /π©\s*([^+\-\dA-Za-z\s]*)\s*([+-]?\d+(?::\d{2})?)\s+(\d{1,2}:\d{2})$/,
|
|
18
|
+
# π© π©Έ Asia/Kolkata 14:30
|
|
19
|
+
event_in_timezone_at_time_only: %r{π©\s*([^+\-\dA-Za-z\s]*)\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{1,2}:\d{2})$},
|
|
20
|
+
# π½ π +5 14:30, π½ π +5:30 14:30
|
|
21
|
+
shift_set_at_time_only: /π½\s*([^+\-\dA-Za-z\s]*)\s*([+-]?\d+(?::\d{2})?)\s+(\d{1,2}:\d{2})$/,
|
|
22
|
+
# π½ π Asia/Kolkata 14:30
|
|
23
|
+
timezone_set_at_time_only: %r{π½\s*([^+\-\dA-Za-z\s]*)\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{1,2}:\d{2})$},
|
|
24
|
+
# π½ π +2, π½ π -3, π½ π +5:30
|
|
25
|
+
shift_set: /π½\s*([^+\-\dA-Za-z\s]*)\s*([+-]?\d+(?::\d{2})?)$/,
|
|
26
|
+
# π½ π +2 2025-01-15 14:30, π½ π +5:30 2025-01-15 14:30
|
|
27
|
+
shift_set_at_time: %r{π½\s*([^+\-\dA-Za-z\s]*)\s*([+-]?\d+(?::\d{2})?)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
28
|
+
# π½ π Europe/Rome, π½ π PST
|
|
29
|
+
timezone_set: %r{π½\s*([^+\-\dA-Za-z\s]*)\s*([A-Za-z_/][A-Za-z0-9_/+-]*)$},
|
|
30
|
+
# π½ π Asia/Kolkata 2025-01-15 14:30
|
|
31
|
+
timezone_set_at_time: %r{π½\s*([^+\-\dA-Za-z\s]*)\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
32
|
+
# π©, π© π©Έ
|
|
33
|
+
event_now: /π©\s*([^+\-\dA-Za-z\s]*)$/,
|
|
34
|
+
# π© π©Έ +2, π© π©Έ -1, π© π©Έ +5:30
|
|
35
|
+
event_now_shifted: /π©\s*([^+\-\dA-Za-z\s]*)\s*([+-]?\d+(?::\d{2})?)$/,
|
|
36
|
+
# π© π©Έ 2025-01-15 14:30
|
|
37
|
+
event_at_time: %r{π©\s*([^+\-\dA-Za-z\s]*)\s*(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
38
|
+
# π© π©Έ +2 2025-01-15 14:30, π© π©Έ +5:30 2025-01-15 14:30
|
|
39
|
+
event_at_time_shifted: %r{π©\s*([^+\-\dA-Za-z\s]*)\s*([+-]?\d+(?::\d{2})?)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$},
|
|
40
|
+
# π© π©Έ Europe/Rome, π© π©Έ PST
|
|
41
|
+
event_in_timezone: %r{π©\s*([^+\-\dA-Za-z\s]*)\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s*$},
|
|
42
|
+
# π© π©Έ Asia/Kolkata 2025-01-15 14:30
|
|
43
|
+
event_in_timezone_at_time: %r{π©\s*([^+\-\dA-Za-z\s]*)\s*([A-Za-z_/][A-Za-z0-9_/+-]*)\s+(\d{4}[-/]\d{1,2}[-/]\d{1,2}\s+\d{1,2}:\d{1,2}(?::\d{1,2})?)$}
|
|
43
44
|
}
|
|
44
45
|
@date_formats = [
|
|
45
46
|
"%Y-%m-%d %H:%M:%S",
|
|
@@ -22,15 +22,15 @@ module ToiletTracker
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
# Result for toilet shift settings
|
|
25
|
-
ToiletShiftResult = Data.define(:type, :status, :message, :shift, :effective_time, :error_details) do
|
|
26
|
-
def initialize(type:, status:, message:, shift: nil, effective_time: nil, error_details: nil)
|
|
25
|
+
ToiletShiftResult = Data.define(:type, :status, :message, :shift, :effective_time, :metadata, :error_details) do
|
|
26
|
+
def initialize(type:, status:, message:, shift: nil, effective_time: nil, metadata: [], error_details: nil)
|
|
27
27
|
super
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Result for poop events
|
|
32
|
-
PoopEventResult = Data.define(:type, :status, :message, :shift, :poop_time, :timezone, :error_details) do
|
|
33
|
-
def initialize(type:, status:, message:, shift: nil, poop_time: nil, timezone: nil, error_details: nil)
|
|
32
|
+
PoopEventResult = Data.define(:type, :status, :message, :shift, :poop_time, :timezone, :metadata, :error_details) do
|
|
33
|
+
def initialize(type:, status:, message:, shift: nil, poop_time: nil, timezone: nil, metadata: [], error_details: nil)
|
|
34
34
|
super
|
|
35
35
|
end
|
|
36
36
|
end
|
|
@@ -98,6 +98,21 @@ module ToiletTracker
|
|
|
98
98
|
time_diff = (message_time - event_time).abs
|
|
99
99
|
(time_diff > 30.days) ? :alert : :ok
|
|
100
100
|
end
|
|
101
|
+
|
|
102
|
+
def parse_metadata(metadata_string)
|
|
103
|
+
return [] if metadata_string.nil? || metadata_string.strip.empty?
|
|
104
|
+
|
|
105
|
+
metadata_string.grapheme_clusters
|
|
106
|
+
.reject { |char| char.match?(/\s/) }
|
|
107
|
+
.select { |char| metadata_emoji?(char) }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def metadata_emoji?(char)
|
|
111
|
+
return false if char.match?(/\A[\p{ASCII}]\z/)
|
|
112
|
+
return false if %w[π© π½].include?(char)
|
|
113
|
+
|
|
114
|
+
char.match?(/\p{Emoji}/) && !char.match?(/\A\d\z/)
|
|
115
|
+
end
|
|
101
116
|
end
|
|
102
117
|
end
|
|
103
118
|
end
|
|
@@ -96,7 +96,7 @@ module ToiletTracker
|
|
|
96
96
|
def parse_poop_type(type, match, message)
|
|
97
97
|
case type
|
|
98
98
|
when :event_now
|
|
99
|
-
parse_poop_live(message)
|
|
99
|
+
parse_poop_live(match, message)
|
|
100
100
|
when :event_now_shifted
|
|
101
101
|
parse_poop_live_shift(match, message)
|
|
102
102
|
when :event_at_time
|
|
@@ -111,20 +111,23 @@ module ToiletTracker
|
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def parse_toilet_shift(match, message)
|
|
114
|
-
|
|
114
|
+
metadata = parse_metadata(match[1])
|
|
115
|
+
shift = parse_shift(match[2])
|
|
115
116
|
|
|
116
117
|
Core::ToiletShiftResult.new(
|
|
117
118
|
type: :shift_set,
|
|
118
119
|
status: :ok,
|
|
119
120
|
message: message,
|
|
120
121
|
shift: shift,
|
|
121
|
-
effective_time: message.timestamp
|
|
122
|
+
effective_time: message.timestamp,
|
|
123
|
+
metadata: metadata
|
|
122
124
|
)
|
|
123
125
|
end
|
|
124
126
|
|
|
125
127
|
def parse_toilet_shift_with_time(match, message)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
metadata = parse_metadata(match[1])
|
|
129
|
+
shift = parse_shift(match[2])
|
|
130
|
+
effective_time = parse_datetime(match[3], @current_message)
|
|
128
131
|
|
|
129
132
|
status = determine_status(effective_time, message.timestamp)
|
|
130
133
|
|
|
@@ -133,12 +136,14 @@ module ToiletTracker
|
|
|
133
136
|
status: status,
|
|
134
137
|
message: message,
|
|
135
138
|
shift: shift,
|
|
136
|
-
effective_time: effective_time
|
|
139
|
+
effective_time: effective_time,
|
|
140
|
+
metadata: metadata
|
|
137
141
|
)
|
|
138
142
|
end
|
|
139
143
|
|
|
140
144
|
def parse_toilet_timezone(match, message)
|
|
141
|
-
|
|
145
|
+
metadata = parse_metadata(match[1])
|
|
146
|
+
timezone_str = match[2]
|
|
142
147
|
shift = calculate_shift_from_timezone(timezone_str)
|
|
143
148
|
|
|
144
149
|
Core::ToiletShiftResult.new(
|
|
@@ -146,13 +151,15 @@ module ToiletTracker
|
|
|
146
151
|
status: :ok,
|
|
147
152
|
message: message,
|
|
148
153
|
shift: shift,
|
|
149
|
-
effective_time: message.timestamp
|
|
154
|
+
effective_time: message.timestamp,
|
|
155
|
+
metadata: metadata
|
|
150
156
|
)
|
|
151
157
|
end
|
|
152
158
|
|
|
153
159
|
def parse_toilet_timezone_with_time(match, message)
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
metadata = parse_metadata(match[1])
|
|
161
|
+
timezone_str = match[2]
|
|
162
|
+
datetime_str = match[3]
|
|
156
163
|
|
|
157
164
|
effective_time = parse_datetime(datetime_str, @current_message)
|
|
158
165
|
status = determine_status(effective_time, message.timestamp)
|
|
@@ -163,7 +170,8 @@ module ToiletTracker
|
|
|
163
170
|
status: status,
|
|
164
171
|
message: message,
|
|
165
172
|
shift: shift,
|
|
166
|
-
effective_time: effective_time
|
|
173
|
+
effective_time: effective_time,
|
|
174
|
+
metadata: metadata
|
|
167
175
|
)
|
|
168
176
|
end
|
|
169
177
|
|
|
@@ -176,30 +184,36 @@ module ToiletTracker
|
|
|
176
184
|
(shift == shift.to_i) ? shift.to_i : shift
|
|
177
185
|
end
|
|
178
186
|
|
|
179
|
-
def parse_poop_live(message)
|
|
187
|
+
def parse_poop_live(match, message)
|
|
188
|
+
metadata = parse_metadata(match[1])
|
|
189
|
+
|
|
180
190
|
Core::PoopEventResult.new(
|
|
181
191
|
type: :event_now,
|
|
182
192
|
status: :ok,
|
|
183
193
|
message: message,
|
|
184
194
|
shift: 0,
|
|
185
|
-
poop_time: message.timestamp
|
|
195
|
+
poop_time: message.timestamp,
|
|
196
|
+
metadata: metadata
|
|
186
197
|
)
|
|
187
198
|
end
|
|
188
199
|
|
|
189
200
|
def parse_poop_live_shift(match, message)
|
|
190
|
-
|
|
201
|
+
metadata = parse_metadata(match[1])
|
|
202
|
+
shift = parse_shift(match[2])
|
|
191
203
|
|
|
192
204
|
Core::PoopEventResult.new(
|
|
193
205
|
type: :event_now_shifted,
|
|
194
206
|
status: :ok,
|
|
195
207
|
message: message,
|
|
196
208
|
shift: shift,
|
|
197
|
-
poop_time: message.timestamp
|
|
209
|
+
poop_time: message.timestamp,
|
|
210
|
+
metadata: metadata
|
|
198
211
|
)
|
|
199
212
|
end
|
|
200
213
|
|
|
201
214
|
def parse_poop_past(match, message)
|
|
202
|
-
|
|
215
|
+
metadata = parse_metadata(match[1])
|
|
216
|
+
poop_time = parse_datetime(match[2], @current_message)
|
|
203
217
|
status = determine_status(poop_time, message.timestamp)
|
|
204
218
|
|
|
205
219
|
Core::PoopEventResult.new(
|
|
@@ -207,13 +221,15 @@ module ToiletTracker
|
|
|
207
221
|
status: status,
|
|
208
222
|
message: message,
|
|
209
223
|
shift: 0,
|
|
210
|
-
poop_time: poop_time
|
|
224
|
+
poop_time: poop_time,
|
|
225
|
+
metadata: metadata
|
|
211
226
|
)
|
|
212
227
|
end
|
|
213
228
|
|
|
214
229
|
def parse_poop_past_with_shift(match, message)
|
|
215
|
-
|
|
216
|
-
|
|
230
|
+
metadata = parse_metadata(match[1])
|
|
231
|
+
shift = parse_shift(match[2])
|
|
232
|
+
poop_time = parse_datetime(match[3], @current_message)
|
|
217
233
|
status = determine_status(poop_time, message.timestamp)
|
|
218
234
|
|
|
219
235
|
Core::PoopEventResult.new(
|
|
@@ -221,25 +237,29 @@ module ToiletTracker
|
|
|
221
237
|
status: status,
|
|
222
238
|
message: message,
|
|
223
239
|
shift: shift,
|
|
224
|
-
poop_time: poop_time
|
|
240
|
+
poop_time: poop_time,
|
|
241
|
+
metadata: metadata
|
|
225
242
|
)
|
|
226
243
|
end
|
|
227
244
|
|
|
228
245
|
def parse_poop_timezone(match, message)
|
|
229
|
-
|
|
246
|
+
metadata = parse_metadata(match[1])
|
|
247
|
+
timezone_str = match[2]
|
|
230
248
|
|
|
231
249
|
Core::PoopEventResult.new(
|
|
232
250
|
type: :event_in_timezone,
|
|
233
251
|
status: :ok,
|
|
234
252
|
message: message,
|
|
235
253
|
poop_time: message.timestamp,
|
|
236
|
-
timezone: timezone_str
|
|
254
|
+
timezone: timezone_str,
|
|
255
|
+
metadata: metadata
|
|
237
256
|
)
|
|
238
257
|
end
|
|
239
258
|
|
|
240
259
|
def parse_poop_timezone_with_time(match, message)
|
|
241
|
-
|
|
242
|
-
|
|
260
|
+
metadata = parse_metadata(match[1])
|
|
261
|
+
timezone_str = match[2]
|
|
262
|
+
poop_time = parse_datetime(match[3], @current_message)
|
|
243
263
|
status = determine_status(poop_time, message.timestamp)
|
|
244
264
|
|
|
245
265
|
Core::PoopEventResult.new(
|
|
@@ -247,7 +267,8 @@ module ToiletTracker
|
|
|
247
267
|
status: status,
|
|
248
268
|
message: message,
|
|
249
269
|
poop_time: poop_time,
|
|
250
|
-
timezone: timezone_str
|
|
270
|
+
timezone: timezone_str,
|
|
271
|
+
metadata: metadata
|
|
251
272
|
)
|
|
252
273
|
end
|
|
253
274
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: toilet_tracker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- NetherSoul
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: activesupport
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: 8.0.2.1
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 8.2.0
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: 8.0.2.1
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: 8.2.0
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: csv
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -41,16 +47,22 @@ dependencies:
|
|
|
41
47
|
name: rubyzip
|
|
42
48
|
requirement: !ruby/object:Gem::Requirement
|
|
43
49
|
requirements:
|
|
44
|
-
- - "
|
|
50
|
+
- - ">="
|
|
45
51
|
- !ruby/object:Gem::Version
|
|
46
52
|
version: 3.0.1
|
|
53
|
+
- - "<"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: 3.3.0
|
|
47
56
|
type: :runtime
|
|
48
57
|
prerelease: false
|
|
49
58
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
59
|
requirements:
|
|
51
|
-
- - "
|
|
60
|
+
- - ">="
|
|
52
61
|
- !ruby/object:Gem::Version
|
|
53
62
|
version: 3.0.1
|
|
63
|
+
- - "<"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 3.3.0
|
|
54
66
|
- !ruby/object:Gem::Dependency
|
|
55
67
|
name: thor
|
|
56
68
|
requirement: !ruby/object:Gem::Requirement
|