opening_hours_converter 1.9.0 → 1.9.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78ca6634e9198554c0e918a2c3cbf684b0b8c2bb0dcf073433e13b0c1d3b71fc
|
|
4
|
+
data.tar.gz: 2f13efa6d51ac1734fd0cbd1742e3cd91be7e75fea61aab3dc83ca9db8614485
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1f4c60f861ba37003d6acbe4e0db75591c82b67e454a8d8b276ed1fab6eb7e71342b0f494c9e8124540d396da9fc5646eefedb833b2843969b6bdd8b981d887
|
|
7
|
+
data.tar.gz: c1e034583c921b93fbea2bd9210329a7e49d8fc6f0a67ddc28a1bc3d1a8952b9e1058d2f404d5fac5dd90fbd5aa925669c0bcd029df2bb1627d243adcc38ab1d
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'opening_hours_converter/constants'
|
|
2
|
+
|
|
3
|
+
module OpeningHoursConverter
|
|
4
|
+
class Token
|
|
5
|
+
include Constants
|
|
6
|
+
|
|
7
|
+
attr_accessor :type, :made_from
|
|
8
|
+
attr_reader :value, :start_index
|
|
9
|
+
|
|
10
|
+
def initialize(value, type, start_index, made_from = [])
|
|
11
|
+
@value = value
|
|
12
|
+
@type = type
|
|
13
|
+
@start_index = start_index
|
|
14
|
+
@made_from = made_from
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def year?
|
|
18
|
+
integer? && @value.length == 4
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def weekday?
|
|
22
|
+
string? && OSM_DAYS.any? { |day| day == @value }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def month?
|
|
26
|
+
string? && OSM_MONTHS.any? { |day| day == @value }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def week?
|
|
30
|
+
string? && @value == 'week'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def week_index?
|
|
34
|
+
# Nécessaire mais pas suffisant : 10 de 10:00 retourne true il faudra check le previous/next token pour décider ou garder le state week
|
|
35
|
+
integer? && @value.to_i <= 53 && @value.to_i >= 1
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def weekday_modifier?
|
|
39
|
+
# Nécessaire mais pas suffisant : 10 de 10:00 retourne true il faudra check le previous/next token pour décider ou garder le state week
|
|
40
|
+
integer? && (@value.to_i <= 5 && @value.to_i >= 1) || @value.to_i == -1
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def monthday?
|
|
44
|
+
# Nécessaire mais pas suffisant : 10 de 10:00 retourne true il faudra check le previous/next token pour décider
|
|
45
|
+
integer? && @value.to_i <= 31 && @value.to_i >= 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def time?
|
|
49
|
+
# Nécessaire mais pas suffisant : 10 de Jan 10 retourne true il faudra check le previous/next token pour décider
|
|
50
|
+
integer? && @value.to_i < 60 && @value.to_i >= 0
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def public_holiday?
|
|
54
|
+
string? && @value.downcase == 'ph'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def off?
|
|
58
|
+
string? && @value.downcase == 'off'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def string?
|
|
62
|
+
@type == :string
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def integer?
|
|
66
|
+
@type == :integer
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def hyphen?
|
|
70
|
+
@type == :hyphen
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def comma?
|
|
74
|
+
@type == :comma
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def quote?
|
|
78
|
+
@type == :quote
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def colon?
|
|
82
|
+
@type == :colon
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def slash?
|
|
86
|
+
@type == :slash
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def opening_square_bracket?
|
|
90
|
+
@type == :opening_square_bracket
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def closing_square_bracket?
|
|
94
|
+
@type == :closing_square_bracket
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
require 'opening_hours_converter/constants'
|
|
2
|
+
|
|
3
|
+
module OpeningHoursConverter
|
|
4
|
+
class Tokenizer
|
|
5
|
+
include Constants
|
|
6
|
+
|
|
7
|
+
attr_reader :tokens
|
|
8
|
+
|
|
9
|
+
def initialize(opening_hours_string)
|
|
10
|
+
@opening_hours_string = opening_hours_string
|
|
11
|
+
@index = 0
|
|
12
|
+
@tokens = []
|
|
13
|
+
tokenize
|
|
14
|
+
@tokens_handler = OpeningHoursConverter::TokensHandler.new(@tokens)
|
|
15
|
+
@tokens = @tokens_handler.tokens.map(&:value)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def tokenize
|
|
19
|
+
counter = 0
|
|
20
|
+
while @index < @opening_hours_string.length
|
|
21
|
+
raise 'ups' if counter > 200
|
|
22
|
+
skip_white_spaces
|
|
23
|
+
@tokens << handle_string if string?
|
|
24
|
+
|
|
25
|
+
skip_white_spaces
|
|
26
|
+
@tokens << handle_integer if integer?
|
|
27
|
+
|
|
28
|
+
skip_white_spaces
|
|
29
|
+
@tokens << handle_quote if quote?
|
|
30
|
+
|
|
31
|
+
skip_white_spaces
|
|
32
|
+
@tokens << handle_slash if slash?
|
|
33
|
+
|
|
34
|
+
skip_white_spaces
|
|
35
|
+
@tokens << handle_opening_square_bracket if opening_square_bracket?
|
|
36
|
+
|
|
37
|
+
skip_white_spaces
|
|
38
|
+
@tokens << handle_closing_square_bracket if closing_square_bracket?
|
|
39
|
+
|
|
40
|
+
skip_white_spaces
|
|
41
|
+
@tokens << handle_colon if colon?
|
|
42
|
+
|
|
43
|
+
skip_white_spaces
|
|
44
|
+
@tokens << handle_comma if comma?
|
|
45
|
+
|
|
46
|
+
skip_white_spaces
|
|
47
|
+
@tokens << handle_hyphen if hyphen?
|
|
48
|
+
counter += 1
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def current_character
|
|
55
|
+
@opening_hours_string[@index]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def current_character?
|
|
59
|
+
!current_character.nil?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def handle_string
|
|
63
|
+
type = :string
|
|
64
|
+
start_index = @index
|
|
65
|
+
value = ''
|
|
66
|
+
|
|
67
|
+
while string? && current_character?
|
|
68
|
+
value << current_character
|
|
69
|
+
@index += 1
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
token(value, type, start_index)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def handle_integer
|
|
76
|
+
type = :integer
|
|
77
|
+
start_index = @index
|
|
78
|
+
value = ''
|
|
79
|
+
|
|
80
|
+
while integer? && current_character?
|
|
81
|
+
value << current_character
|
|
82
|
+
@index += 1
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
token(value, type, start_index)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def handle_quote
|
|
89
|
+
type = :quote
|
|
90
|
+
start_index = @index
|
|
91
|
+
|
|
92
|
+
value = current_character
|
|
93
|
+
@index += 1
|
|
94
|
+
|
|
95
|
+
while current_character?
|
|
96
|
+
if quote?
|
|
97
|
+
value << current_character
|
|
98
|
+
@index += 1
|
|
99
|
+
break
|
|
100
|
+
else
|
|
101
|
+
value << current_character
|
|
102
|
+
@index += 1
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
token(value, type, start_index)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def handle_slash
|
|
110
|
+
type = :slash
|
|
111
|
+
start_index = @index
|
|
112
|
+
|
|
113
|
+
value = current_character
|
|
114
|
+
@index += 1
|
|
115
|
+
|
|
116
|
+
token(value, type, start_index)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def handle_opening_square_bracket
|
|
120
|
+
type = :opening_square_bracket
|
|
121
|
+
start_index = @index
|
|
122
|
+
|
|
123
|
+
value = current_character
|
|
124
|
+
@index += 1
|
|
125
|
+
|
|
126
|
+
token(value, type, start_index)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def handle_closing_square_bracket
|
|
130
|
+
type = :closing_square_bracket
|
|
131
|
+
start_index = @index
|
|
132
|
+
|
|
133
|
+
value = current_character
|
|
134
|
+
@index += 1
|
|
135
|
+
|
|
136
|
+
token(value, type, start_index)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def handle_colon
|
|
140
|
+
type = :colon
|
|
141
|
+
start_index = @index
|
|
142
|
+
|
|
143
|
+
value = current_character
|
|
144
|
+
@index += 1
|
|
145
|
+
|
|
146
|
+
token(value, type, start_index)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def handle_comma
|
|
150
|
+
type = :comma
|
|
151
|
+
start_index = @index
|
|
152
|
+
|
|
153
|
+
value = current_character
|
|
154
|
+
@index += 1
|
|
155
|
+
|
|
156
|
+
token(value, type, start_index)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def handle_hyphen
|
|
160
|
+
type = :hyphen
|
|
161
|
+
start_index = @index
|
|
162
|
+
|
|
163
|
+
value = current_character
|
|
164
|
+
@index += 1
|
|
165
|
+
|
|
166
|
+
token(value, type, start_index)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def token(value, type, start_index)
|
|
170
|
+
OpeningHoursConverter::Token.new(value, type, start_index)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def skip_white_spaces
|
|
174
|
+
until current_character.nil? || !white_space?
|
|
175
|
+
@index += 1
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def integer?
|
|
180
|
+
!(current_character =~ /[0-9]/).nil?
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def white_space?
|
|
184
|
+
!(current_character =~ /\s/).nil?
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def string?
|
|
188
|
+
# all char but space, digits and punctuations
|
|
189
|
+
!(current_character =~ /[^\s\d.,;:"()\[\]\-\_]/).nil?
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def punctuation?
|
|
193
|
+
!(current_character =~ /[.,;:"'()\[\]]/).nil?
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def quote?
|
|
197
|
+
current_character == '"'
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def hyphen?
|
|
201
|
+
current_character == '-'
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def colon?
|
|
205
|
+
current_character == ':'
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def slash?
|
|
209
|
+
current_character == '/'
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def semicolon?
|
|
213
|
+
current_character == ';'
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def comma?
|
|
217
|
+
current_character == ','
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def opening_square_bracket?
|
|
221
|
+
current_character == '['
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def closing_square_bracket?
|
|
225
|
+
current_character == ']'
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
require 'opening_hours_converter/constants'
|
|
2
|
+
|
|
3
|
+
module OpeningHoursConverter
|
|
4
|
+
class TokensHandler
|
|
5
|
+
include Constants
|
|
6
|
+
|
|
7
|
+
attr_reader :tokens
|
|
8
|
+
|
|
9
|
+
def initialize(tokens)
|
|
10
|
+
@unhandled_tokens = tokens
|
|
11
|
+
@index = 0
|
|
12
|
+
@tokens = []
|
|
13
|
+
|
|
14
|
+
handle_tokens
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def handle_tokens
|
|
18
|
+
while current_token?
|
|
19
|
+
if current_token.year?
|
|
20
|
+
@tokens << handle_year
|
|
21
|
+
next
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if current_token.month?
|
|
25
|
+
@tokens << handle_month
|
|
26
|
+
next
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if current_token.week?
|
|
30
|
+
@tokens << handle_week
|
|
31
|
+
next
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if current_token.weekday?
|
|
35
|
+
@tokens << handle_weekday
|
|
36
|
+
next
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if current_token_is_time?
|
|
40
|
+
@tokens << handle_time
|
|
41
|
+
next
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if current_token.public_holiday?
|
|
45
|
+
@tokens << handle_public_holiday
|
|
46
|
+
next
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if current_token_is_all_time?
|
|
50
|
+
@tokens << handle_all_time
|
|
51
|
+
next
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if current_token.off?
|
|
55
|
+
@tokens << handle_off
|
|
56
|
+
next
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if current_token.quote?
|
|
60
|
+
@tokens << handle_quote
|
|
61
|
+
next
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if current_token.comma?
|
|
65
|
+
# catches "Mo off, Tu 10:00-20:00"
|
|
66
|
+
@index += 1
|
|
67
|
+
next
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
raise "can't read current token #{current_token}"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def add_current_token_value_to(value, leading = '', trailing = '')
|
|
77
|
+
"#{value}#{leading}#{current_token.value}#{trailing}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def add_current_token_to(base_value, base_type, made_from, type = nil, leading = '', trailing = '')
|
|
81
|
+
base_type[type] = true unless type.nil? || type.length.zero?
|
|
82
|
+
value = add_current_token_value_to(base_value, leading, trailing)
|
|
83
|
+
made_from << current_token
|
|
84
|
+
@index += 1
|
|
85
|
+
|
|
86
|
+
[value, made_from, base_type]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def handle_year
|
|
90
|
+
type = { year: true }
|
|
91
|
+
start_index = current_token.start_index
|
|
92
|
+
value = current_token.value
|
|
93
|
+
made_from = [current_token]
|
|
94
|
+
@index += 1
|
|
95
|
+
|
|
96
|
+
while current_token?
|
|
97
|
+
if current_token.hyphen? || current_token.comma? || current_token.slash?
|
|
98
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
99
|
+
next
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if current_token.year?
|
|
103
|
+
type[:multi_year] = true
|
|
104
|
+
if previous_token.hyphen? || previous_token.comma?
|
|
105
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
106
|
+
next
|
|
107
|
+
end
|
|
108
|
+
raise "you can\'t have two years with just space between them previous token: #{previous_token}, current token: #{current_token}"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if current_token.string?
|
|
112
|
+
break if current_token.weekday?
|
|
113
|
+
|
|
114
|
+
if current_token.week?
|
|
115
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :week, ' ')
|
|
116
|
+
next
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
if current_token.month?
|
|
120
|
+
if previous_token.hyphen? || previous_token.comma?
|
|
121
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_month)
|
|
122
|
+
next
|
|
123
|
+
else
|
|
124
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :month, ' ')
|
|
125
|
+
next
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
if current_token.integer?
|
|
131
|
+
break if current_token_is_time? # we don't want time range in the wide interval token
|
|
132
|
+
break if current_token_is_all_time? # nor 24/7
|
|
133
|
+
|
|
134
|
+
if type[:week]
|
|
135
|
+
if current_token.week_index?
|
|
136
|
+
if previous_token.slash?
|
|
137
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :modified_week)
|
|
138
|
+
next
|
|
139
|
+
elsif previous_token.comma? || previous_token.hyphen?
|
|
140
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_week)
|
|
141
|
+
next
|
|
142
|
+
else
|
|
143
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :week, ' ')
|
|
144
|
+
next
|
|
145
|
+
end
|
|
146
|
+
if current_token_is_week_modifier?
|
|
147
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :modified_week)
|
|
148
|
+
next
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
elsif type[:month]
|
|
153
|
+
if current_token_monthday?
|
|
154
|
+
if previous_token.comma? || previous_token.hyphen?
|
|
155
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_month)
|
|
156
|
+
next
|
|
157
|
+
else
|
|
158
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :month, ' ')
|
|
159
|
+
next
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
break
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
token(value, type, start_index, made_from)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def token(value, type, start_index, made_from)
|
|
172
|
+
OpeningHoursConverter::Token.new(value, type, start_index, made_from)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def handle_month
|
|
176
|
+
type = { month: true }
|
|
177
|
+
start_index = current_token.start_index
|
|
178
|
+
value = current_token.value
|
|
179
|
+
made_from = [current_token]
|
|
180
|
+
@index += 1
|
|
181
|
+
|
|
182
|
+
while current_token?
|
|
183
|
+
break if current_token_is_all_time?
|
|
184
|
+
break if current_token_is_time?
|
|
185
|
+
|
|
186
|
+
if current_token.hyphen? || current_token.comma? || current_token.slash?
|
|
187
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
188
|
+
next
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if current_token_monthday?
|
|
192
|
+
if previous_token.comma? || previous_token.hyphen?
|
|
193
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_monthday)
|
|
194
|
+
next
|
|
195
|
+
else
|
|
196
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :monthday, ' ')
|
|
197
|
+
next
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
if current_token.month?
|
|
202
|
+
if previous_token.hyphen? || previous_token.comma?
|
|
203
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_month)
|
|
204
|
+
next
|
|
205
|
+
else
|
|
206
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :month, ' ')
|
|
207
|
+
next
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
break
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
token(value, type, start_index, made_from)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def handle_week
|
|
218
|
+
type = { week: true }
|
|
219
|
+
start_index = current_token.start_index
|
|
220
|
+
value = current_token.value
|
|
221
|
+
made_from = [current_token]
|
|
222
|
+
@index += 1
|
|
223
|
+
|
|
224
|
+
while current_token?
|
|
225
|
+
break if current_token.string?
|
|
226
|
+
break if current_token_is_time?
|
|
227
|
+
|
|
228
|
+
if current_token.hyphen? || current_token.comma?
|
|
229
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_week)
|
|
230
|
+
next
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
if current_token.slash?
|
|
234
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :modified_week)
|
|
235
|
+
next
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
if current_token.week_index?
|
|
239
|
+
if previous_token.week?
|
|
240
|
+
value = add_current_token_value_to(value, ' ')
|
|
241
|
+
else
|
|
242
|
+
value = add_current_token_value_to(value)
|
|
243
|
+
end
|
|
244
|
+
made_from << current_token
|
|
245
|
+
@index += 1
|
|
246
|
+
next
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
break
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
token(value, type, start_index, made_from)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def handle_weekday
|
|
256
|
+
type = { weekday: true }
|
|
257
|
+
start_index = current_token.start_index
|
|
258
|
+
value = current_token.value
|
|
259
|
+
made_from = [current_token]
|
|
260
|
+
@index += 1
|
|
261
|
+
|
|
262
|
+
while current_token?
|
|
263
|
+
break if current_token.integer?
|
|
264
|
+
|
|
265
|
+
if current_token.hyphen? || current_token.comma?
|
|
266
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_weekday)
|
|
267
|
+
next
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
if current_token.weekday?
|
|
271
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :multi_weekday)
|
|
272
|
+
next
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
if current_token.public_holiday?
|
|
276
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :public_holiday)
|
|
277
|
+
next
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
if current_token.opening_square_bracket?
|
|
281
|
+
value, made_from, type = add_current_token_to(value, type, made_from, :modified_weekday)
|
|
282
|
+
|
|
283
|
+
while current_token?
|
|
284
|
+
if current_token.closing_square_bracket?
|
|
285
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
286
|
+
break
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
if current_token.hyphen? || current_token.weekday_modifier?
|
|
290
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
291
|
+
next
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
next
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
break
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
token(value, type, start_index, made_from)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def handle_time
|
|
305
|
+
type = { time: true }
|
|
306
|
+
start_index = current_token.start_index
|
|
307
|
+
|
|
308
|
+
value = current_token.value
|
|
309
|
+
made_from = [current_token]
|
|
310
|
+
@index += 1
|
|
311
|
+
|
|
312
|
+
raise unless current_token.colon?
|
|
313
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
314
|
+
|
|
315
|
+
raise unless current_token.time?
|
|
316
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
317
|
+
|
|
318
|
+
raise unless current_token.hyphen?
|
|
319
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
320
|
+
|
|
321
|
+
# second part of time range
|
|
322
|
+
raise unless current_token.time?
|
|
323
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
324
|
+
|
|
325
|
+
raise unless current_token.colon?
|
|
326
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
327
|
+
|
|
328
|
+
raise unless current_token.time?
|
|
329
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
330
|
+
|
|
331
|
+
token(value, type, start_index, made_from)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def handle_public_holiday
|
|
335
|
+
type = { time: true }
|
|
336
|
+
start_index = current_token.start_index
|
|
337
|
+
|
|
338
|
+
value = current_token.value
|
|
339
|
+
made_from = [current_token]
|
|
340
|
+
@index += 1
|
|
341
|
+
|
|
342
|
+
if current_token.comma?
|
|
343
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
344
|
+
|
|
345
|
+
weekdays_token = handle_weekday
|
|
346
|
+
value += weekdays_token.value
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
token(value, type, start_index, made_from)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def handle_all_time
|
|
353
|
+
type = { all_time: true }
|
|
354
|
+
start_index = current_token.start_index
|
|
355
|
+
|
|
356
|
+
value = current_token.value
|
|
357
|
+
made_from = [current_token]
|
|
358
|
+
@index += 1
|
|
359
|
+
|
|
360
|
+
raise unless current_token.slash?
|
|
361
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
362
|
+
|
|
363
|
+
raise unless current_token.value == '7'
|
|
364
|
+
value, made_from, type = add_current_token_to(value, type, made_from)
|
|
365
|
+
|
|
366
|
+
token(value, type, start_index, made_from)
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def handle_off
|
|
370
|
+
type = { off: true }
|
|
371
|
+
start_index = current_token.start_index
|
|
372
|
+
|
|
373
|
+
value = current_token.value
|
|
374
|
+
made_from = [current_token]
|
|
375
|
+
@index += 1
|
|
376
|
+
|
|
377
|
+
token(value, type, start_index, made_from)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def handle_quote
|
|
381
|
+
type = { comment: true }
|
|
382
|
+
start_index = current_token.start_index
|
|
383
|
+
|
|
384
|
+
value = current_token.value
|
|
385
|
+
made_from = [current_token]
|
|
386
|
+
@index += 1
|
|
387
|
+
|
|
388
|
+
token(value, type, start_index, made_from)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def current_token_is_time?
|
|
392
|
+
return false unless current_token?
|
|
393
|
+
|
|
394
|
+
if current_token.time?
|
|
395
|
+
if previous_token.hyphen?
|
|
396
|
+
return false unless next_token? && next_token.colon?
|
|
397
|
+
return true
|
|
398
|
+
end
|
|
399
|
+
if next_token? && next_token.hyphen?
|
|
400
|
+
return false unless previous_token.colon?
|
|
401
|
+
return true
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
return false unless previous_token.colon? || next_token? && next_token.colon?
|
|
405
|
+
return true
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
return false
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def current_token_is_week_modifier?
|
|
412
|
+
current_token? &&
|
|
413
|
+
|
|
414
|
+
# check if current token is 2 in week 1-10/2
|
|
415
|
+
current_token.integer? && current_token.value.to_i <= 53 &&
|
|
416
|
+
previous_token? && previous_token.slash? &&
|
|
417
|
+
next_token?
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def current_token_monthday?
|
|
421
|
+
current_token? &&
|
|
422
|
+
|
|
423
|
+
# check if current token is 22 in either Jan 22 off or Jan 21,22 or Jan 21-22
|
|
424
|
+
current_token.monthday? &&
|
|
425
|
+
previous_token? && previous_token.month? || previous_token.comma? || previous_token.hyphen? &&
|
|
426
|
+
next_token?
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def current_token_is_all_time?
|
|
430
|
+
current_token? &&
|
|
431
|
+
|
|
432
|
+
# check if current token is 24 or / or 7 in 24/7
|
|
433
|
+
current_token.integer? &&
|
|
434
|
+
previous_token? && previous_token.slash? && current_token.value == '7' ||
|
|
435
|
+
next_token? && next_token.slash? && current_token.value == '24' ||
|
|
436
|
+
|
|
437
|
+
current_token.slash? &&
|
|
438
|
+
previous_token? && previous_token.value == '24' &&
|
|
439
|
+
next_token? && next_token.value == '7'
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
def current_token
|
|
443
|
+
@unhandled_tokens[@index]
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def next_token
|
|
447
|
+
@unhandled_tokens[@index + 1]
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def previous_token
|
|
451
|
+
@unhandled_tokens[@index - 1]
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def current_token?
|
|
455
|
+
!current_token.nil?
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def next_token?
|
|
459
|
+
!next_token.nil?
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
def previous_token?
|
|
463
|
+
!previous_token.nil?
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module OpeningHoursConverter
|
|
2
|
+
module Utils
|
|
3
|
+
def reindex_sunday_week_to_monday_week(wday)
|
|
4
|
+
(wday + 6) % 7
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def timstring_as_minutes(time)
|
|
8
|
+
values = time.split(':')
|
|
9
|
+
values[0].to_i * 60 + values[1].to_i
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add_days_to_time(time, days)
|
|
13
|
+
time + days * seconds_in_day
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def day_difference(from, to)
|
|
17
|
+
to - from
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def week_difference(from, to)
|
|
21
|
+
day_diff = to - from
|
|
22
|
+
day_diff -= (day_diff % 7)
|
|
23
|
+
(day_diff / 7).to_i
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def seconds_in_day
|
|
27
|
+
24 * 60 * 60
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def leap_year?(year = Time.now.year)
|
|
31
|
+
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def last_day_of_month(month, year)
|
|
35
|
+
return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] unless leap_year?(year) && month == 1
|
|
36
|
+
return 29
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def time_to_datetime(time)
|
|
40
|
+
DateTime.new(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.gmt_offset / 3600, 24))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def datetime_to_time(datetime)
|
|
44
|
+
Time.new(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec, datetime.zone)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opening_hours_converter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ziserman Martin
|
|
@@ -57,6 +57,10 @@ files:
|
|
|
57
57
|
- lib/opening_hours_converter/opening_hours_rule.rb
|
|
58
58
|
- lib/opening_hours_converter/opening_hours_time.rb
|
|
59
59
|
- lib/opening_hours_converter/public_holiday.rb
|
|
60
|
+
- lib/opening_hours_converter/token.rb
|
|
61
|
+
- lib/opening_hours_converter/tokenizer.rb
|
|
62
|
+
- lib/opening_hours_converter/tokens_handler.rb
|
|
63
|
+
- lib/opening_hours_converter/utils.rb
|
|
60
64
|
- lib/opening_hours_converter/week.rb
|
|
61
65
|
- lib/opening_hours_converter/wide_interval.rb
|
|
62
66
|
- lib/opening_hours_converter/year.rb
|