rice-dining 0.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9daa87593abac15b47c885be99cac5417c530d4
4
- data.tar.gz: 99c5275f06dc486a268dc90020122738425ea965
3
+ metadata.gz: fb60ebd8074ac82c4320cc651b77244b701ffe1f
4
+ data.tar.gz: 032954ce38d5f06fb50fd2e51fa60e295d5a046e
5
5
  SHA512:
6
- metadata.gz: c8cb808dd1528715fee7f9049b328b8590cfad5f03e8d45e0a0598a14d8fbcf6fd0d42a02118e8bf91731f79601c550b21ed6fa6119afe7e6a8f4b61393b65e3
7
- data.tar.gz: 1cabcc2322f47969b27c9713aa90c1490b54106ff164726b0cf7738c441949a77b76420b54699661ea2adbd885a0b7e8b2c10b1e4862879cd70486b5dc229194
6
+ metadata.gz: 88cc2e2a8f4ff5a2976543fbfa02d8e0070b4678b130c34f2140e2c5e030e54837e053d9fccff20f3a6688cb51559521f9f74dd21cfa557d9e31ed813c6e219f
7
+ data.tar.gz: bbb299f046fd5f85007768c53b5e2ab012ca307563ce47c6c3e564f90488348e6d8b554da0824ee3fd7459c7798a6bf7fd84b51782350bff0a295d9a8aa40b9a
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rice-dining (0.1)
5
- colorize (>= 0.7.0)
6
- nokogiri (>= 1.6.0)
4
+ rice-dining (0.2.1)
5
+ colorize (~> 0.7)
6
+ nokogiri (~> 1.6)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
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
+ ![Screenshot](/png/screenshot.png?raw=true)
17
+
@@ -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.id <=> b.id}
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'.white.on_green
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'.white.on_red
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 + 12)
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
@@ -94,95 +94,114 @@ module Rice
94
94
  end
95
95
  end
96
96
 
97
- ManifestCreateError ||= Class.new StandardError
97
+ class ManifestFetcher
98
+ def initialize
99
+ @allergen_map = {}
100
+ @allergen_shortcodes = Set.new
101
+ end
98
102
 
99
- def self.manifest
100
- # Make the request
101
- req = Net::HTTP::Get.new Rice::Dining::BASE
102
- req['User-Agent'.freeze] = Rice::Dining::IDENT
103
- res = Net::HTTP.start(Rice::Dining::BASE.hostname, Rice::Dining::BASE.port,
104
- use_ssl: Rice::Dining::BASE.scheme == 'https'.freeze) {|h| h.request(req)}
105
-
106
- if res.is_a? Net::HTTPSuccess
107
- doc = Nokogiri::HTML(res.body)
108
-
109
- # stash allergen references
110
- allergens, allergen_shortcodes = {}, Set.new
111
-
112
- # build locations
113
- locations = []
114
- location_nodes = doc.css('div.item'.freeze)
115
- raise ManifestCreateError, "couldn't find locations".freeze if location_nodes.empty?
116
- location_nodes.each do |location_node|
117
- # Get the servery name
118
- name_nodes = location_node.css('div.servery-title h1'.freeze)
119
- next if name_nodes.empty?
120
- name = name_nodes.first.text
121
- name.strip!
122
-
123
- # might be closed
124
- closed = !location_node.css('div.nothere'.freeze).empty?
125
- if closed
126
- locations << Rice::Dining::Location.new(name)
127
- else
128
- # grab the items
129
- items = []
130
- item_nodes = location_node.css('div.menu-item'.freeze)
131
- item_nodes.each do |item_node|
132
- item_allergens, item_name = [], item_node.text
133
- item_name.strip!
134
- item_node.parent.css('div.allergen div.diet'.freeze).each do |allergen_node|
135
- # build the allergen key
136
- key = Rice::Dining.allergen_cleanup allergen_node['class'.freeze]
137
- if !allergens.include? key
138
- # find a unique value for the shortcode
139
- shortcode = key[0].to_sym
140
- if allergen_shortcodes.include? shortcode
141
- shortcode = shortcode.swapcase
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
- item_allergens << allergen
148
+ items << Rice::Dining::Item.new(item_name, *item_allergens.sort)
156
149
  end
157
150
 
158
- items << Rice::Dining::Item.new(item_name, *item_allergens.sort)
151
+ locations << Rice::Dining::Location.new(name, *items)
159
152
  end
153
+ end
160
154
 
161
- locations << Rice::Dining::Location.new(name, *items)
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
- locations.sort! do |a, b|
166
- if a.closed? and b.open?
167
- 1
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
- Rice::Dining::Manifest.new locations, allergens.values
176
- else
177
- # Problem with the response
178
- raise ManifestCreateError, "got HTTP #{res.code} from #{Rice::Dining::BASE}"
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.allergen_cleanup allergens
183
- ret = allergens.match(/\Adiet\s+(?<type>[a-z]+)/i)
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
@@ -1,7 +1,7 @@
1
1
  module Rice
2
2
  module Dining
3
3
  module Version
4
- VERSION = '0.2'.freeze
4
+ VERSION = '0.2.1'.freeze
5
5
  SHORT_NAME = Rice::Dining.to_s.freeze
6
6
  SHORT_IDENT = "#{SHORT_NAME} v#{VERSION}".freeze
7
7
  NAME = SHORT_NAME.freeze
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: '0.2'
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: