rice-dining 0.2 → 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/Gemfile.lock +3 -3
- data/README.md +6 -1
- data/bin/rice-dining +5 -5
- data/lib/rice/dining.rb +92 -73
- data/lib/rice/dining/version.rb +1 -1
- data/png/screenshot.png +0 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb60ebd8074ac82c4320cc651b77244b701ffe1f
|
4
|
+
data.tar.gz: 032954ce38d5f06fb50fd2e51fa60e295d5a046e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88cc2e2a8f4ff5a2976543fbfa02d8e0070b4678b130c34f2140e2c5e030e54837e053d9fccff20f3a6688cb51559521f9f74dd21cfa557d9e31ed813c6e219f
|
7
|
+
data.tar.gz: bbb299f046fd5f85007768c53b5e2ab012ca307563ce47c6c3e564f90488348e6d8b554da0824ee3fd7459c7798a6bf7fd84b51782350bff0a295d9a8aa40b9a
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# rice-dining
|
2
2
|
|
3
|
-
Provides a `dining` executable that prints servery offerings at Rice.
|
3
|
+
Provides a `rice-dining` executable that prints servery offerings at Rice.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -10,3 +10,8 @@ Provides a `dining` executable that prints servery offerings at Rice.
|
|
10
10
|
|
11
11
|
Run `rice-dining` to print status for everything, or `rice-dining <regex>` to print status
|
12
12
|
for locations matching `<regex>`
|
13
|
+
|
14
|
+
## Screenshot
|
15
|
+
|
16
|
+

|
17
|
+
|
data/bin/rice-dining
CHANGED
@@ -28,7 +28,7 @@ require 'colorize'
|
|
28
28
|
begin
|
29
29
|
regex = !ARGV.empty? ? Regexp.compile(ARGV.first, Regexp::IGNORECASE) : //
|
30
30
|
manifest = Rice::Dining.manifest
|
31
|
-
allergens = manifest.allergens.sort {|a, b| a.
|
31
|
+
allergens = manifest.allergens.sort {|a, b| a.shortcode <=> b.shortcode}
|
32
32
|
allergen_colors = {
|
33
33
|
vegan: :magenta,
|
34
34
|
vegetarian: :light_green,
|
@@ -47,7 +47,7 @@ begin
|
|
47
47
|
next unless location.name =~ regex
|
48
48
|
STDOUT.print "#{location.name}: "
|
49
49
|
if location.open?
|
50
|
-
STDOUT.puts 'OPEN'.
|
50
|
+
STDOUT.puts 'OPEN'.green
|
51
51
|
location.items.each_with_index do |item, idx|
|
52
52
|
STDOUT.print idx == 0 ? ' \- ' : ' |- '
|
53
53
|
allergens.each do |allergen|
|
@@ -57,7 +57,7 @@ begin
|
|
57
57
|
STDOUT.puts " #{item.name}"
|
58
58
|
end
|
59
59
|
else
|
60
|
-
STDOUT.puts 'CLOSED'.
|
60
|
+
STDOUT.puts 'CLOSED'.red
|
61
61
|
end
|
62
62
|
|
63
63
|
printed += 1
|
@@ -69,9 +69,9 @@ begin
|
|
69
69
|
max_width = allergen.id.length if allergen.id.length > max_width
|
70
70
|
end
|
71
71
|
|
72
|
-
STDOUT.puts '-' * ((max_width + 3) * 5 +
|
72
|
+
STDOUT.puts '-' * ((max_width + 3) * 5 + 8)
|
73
73
|
allergens.each_with_index do |allergen, idx|
|
74
|
-
newline = (idx + 1) % 5 == 0
|
74
|
+
newline = idx == allergens.length - 1 || (idx + 1) % 5 == 0
|
75
75
|
color = allergen_colors.include?(allergen.id) ? allergen_colors[allergen.id] : :white
|
76
76
|
str = "#{allergen.shortcode.to_s.colorize(color)}: #{allergen.id}"
|
77
77
|
str << ' ' * (max_width - allergen.id.length) unless newline
|
data/lib/rice/dining.rb
CHANGED
@@ -94,95 +94,114 @@ module Rice
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
|
97
|
+
class ManifestFetcher
|
98
|
+
def initialize
|
99
|
+
@allergen_map = {}
|
100
|
+
@allergen_shortcodes = Set.new
|
101
|
+
end
|
98
102
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
#
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
while allergen_shortcodes.include? shortcode
|
144
|
-
shortcode = shortcode.downcase.succ
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# create the allergen
|
149
|
-
allergen = allergens[key] = Rice::Dining::Allergen.new(key, shortcode)
|
150
|
-
allergen_shortcodes << shortcode
|
151
|
-
else
|
152
|
-
allergen = allergens[key]
|
103
|
+
def fetch
|
104
|
+
@allergen_map.clear
|
105
|
+
@allergen_shortcodes.clear
|
106
|
+
|
107
|
+
# Make the request
|
108
|
+
req = Net::HTTP::Get.new Rice::Dining::BASE
|
109
|
+
req['User-Agent'.freeze] = Rice::Dining::IDENT
|
110
|
+
res = Net::HTTP.start(Rice::Dining::BASE.hostname, Rice::Dining::BASE.port,
|
111
|
+
use_ssl: Rice::Dining::BASE.scheme == 'https'.freeze) {|h| h.request(req)}
|
112
|
+
|
113
|
+
if res.is_a? Net::HTTPSuccess
|
114
|
+
doc = Nokogiri::HTML(res.body)
|
115
|
+
|
116
|
+
# stash allergen references in the "key" section
|
117
|
+
doc.css('div#key div.diet'.freeze).each do |allergen_node|
|
118
|
+
self.allergen_reference allergen_node['class'.freeze]
|
119
|
+
end
|
120
|
+
|
121
|
+
# build each location
|
122
|
+
locations = []
|
123
|
+
location_nodes = doc.css('div.item'.freeze)
|
124
|
+
raise ManifestCreateError, "couldn't find locations".freeze if location_nodes.empty?
|
125
|
+
location_nodes.each do |location_node|
|
126
|
+
# get the servery name
|
127
|
+
name_nodes = location_node.css('div.servery-title h1'.freeze)
|
128
|
+
next if name_nodes.empty?
|
129
|
+
name = name_nodes.first.text
|
130
|
+
name.strip!
|
131
|
+
|
132
|
+
# might be closed
|
133
|
+
closed = !location_node.css('div.nothere'.freeze).empty?
|
134
|
+
if closed
|
135
|
+
locations << Rice::Dining::Location.new(name)
|
136
|
+
else
|
137
|
+
# grab the items
|
138
|
+
items = []
|
139
|
+
item_nodes = location_node.css('div.menu-item'.freeze)
|
140
|
+
item_nodes.each do |item_node|
|
141
|
+
item_allergens, item_name = [], item_node.text
|
142
|
+
item_name.strip!
|
143
|
+
item_node.parent.css('div.allergen div.diet'.freeze).each do |allergen_node|
|
144
|
+
allergen = self.allergen_reference allergen_node['class'.freeze]
|
145
|
+
item_allergens << allergen if allergen
|
153
146
|
end
|
154
147
|
|
155
|
-
|
148
|
+
items << Rice::Dining::Item.new(item_name, *item_allergens.sort)
|
156
149
|
end
|
157
150
|
|
158
|
-
|
151
|
+
locations << Rice::Dining::Location.new(name, *items)
|
159
152
|
end
|
153
|
+
end
|
160
154
|
|
161
|
-
|
155
|
+
locations.sort! do |a, b|
|
156
|
+
if a.closed? and b.open?
|
157
|
+
1
|
158
|
+
elsif a.open? and b.closed?
|
159
|
+
-1
|
160
|
+
else
|
161
|
+
a.name <=> b.name
|
162
|
+
end
|
162
163
|
end
|
164
|
+
|
165
|
+
Rice::Dining::Manifest.new locations, @allergen_map.values
|
166
|
+
else
|
167
|
+
# Problem with the response
|
168
|
+
raise ManifestCreateError, "got HTTP #{res.code} from #{Rice::Dining::BASE}"
|
163
169
|
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def allergen_reference allergen_class
|
173
|
+
# build the allergen key
|
174
|
+
key = allergen_cleanup allergen_class
|
175
|
+
return nil if key.nil?
|
176
|
+
|
177
|
+
if !@allergen_map.include? key
|
178
|
+
# find a unique value for the shortcode
|
179
|
+
shortcode = key[0].to_sym
|
180
|
+
if @allergen_shortcodes.include? shortcode
|
181
|
+
shortcode = shortcode.swapcase
|
164
182
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
elsif a.open? and b.closed?
|
169
|
-
-1
|
170
|
-
else
|
171
|
-
a.name <=> b.name
|
183
|
+
while @allergen_shortcodes.include? shortcode
|
184
|
+
shortcode = shortcode.downcase.succ
|
185
|
+
end
|
172
186
|
end
|
187
|
+
|
188
|
+
# create the allergen
|
189
|
+
allergen = @allergen_map[key] = Rice::Dining::Allergen.new(key, shortcode)
|
190
|
+
@allergen_shortcodes << shortcode
|
191
|
+
else
|
192
|
+
allergen = @allergen_map[key]
|
173
193
|
end
|
194
|
+
end
|
174
195
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
196
|
+
def allergen_cleanup allergens
|
197
|
+
ret = allergens.match(/\Adiet\s+(?<type>[a-z]+)/i)
|
198
|
+
return nil if ret.nil?
|
199
|
+
ret[:type].downcase.to_sym
|
179
200
|
end
|
180
201
|
end
|
181
202
|
|
182
|
-
def self.
|
183
|
-
|
184
|
-
return nil if ret.nil?
|
185
|
-
ret[:type].downcase.to_sym
|
203
|
+
def self.manifest
|
204
|
+
ManifestFetcher.new.fetch
|
186
205
|
end
|
187
206
|
end
|
188
207
|
end
|
data/lib/rice/dining/version.rb
CHANGED
data/png/screenshot.png
ADDED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rice-dining
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Morgan Jones
|
@@ -54,6 +54,7 @@ files:
|
|
54
54
|
- bin/rice-dining
|
55
55
|
- lib/rice/dining.rb
|
56
56
|
- lib/rice/dining/version.rb
|
57
|
+
- png/screenshot.png
|
57
58
|
- rice-dining.gemspec
|
58
59
|
homepage: https://numin.it
|
59
60
|
licenses:
|