class Rice::Dining::ManifestFetcher
Public Class Methods
new()
click to toggle source
# File lib/rice/dining.rb, line 101 def initialize @allergen_map = {} @allergen_shortcodes = Set.new end
Public Instance Methods
fetch()
click to toggle source
# File lib/rice/dining.rb, line 106 def fetch @allergen_map.clear @allergen_shortcodes.clear # Make the request req = Net::HTTP::Get.new Rice::Dining::BASE req['User-Agent'.freeze] = Rice::Dining::IDENT res = Net::HTTP.start(Rice::Dining::BASE.hostname, Rice::Dining::BASE.port, use_ssl: Rice::Dining::BASE.scheme == 'https'.freeze) {|h| h.request(req)} if res.is_a? Net::HTTPSuccess doc = Nokogiri::HTML(res.body) # find the title title_nodes = doc.css('div.alpha h1:contains("Your")'.freeze) unless title_nodes.empty? title_stuff = title_nodes.first.text title_stuff.strip! title_match = title_stuff.match /\Ayour\s+(?<title>[a-z]+)/i if title_match title = title_match[:title] else title = nil end else title = nil end # stash allergen references in the "key" section doc.css('div#key div.diet'.freeze).each do |allergen_node| allergen_reference allergen_node['class'.freeze] end # build each location locations = [] location_nodes = doc.css('div.item'.freeze) raise CreateError, "couldn't find locations".freeze if location_nodes.empty? location_nodes.each do |location_node| # get the servery name name_nodes = location_node.css('div.servery-title h1'.freeze) next if name_nodes.empty? name = name_nodes.first.text name.strip! # might be closed closed = !location_node.css('div.nothere'.freeze).empty? if closed locations << Rice::Dining::Location.new(name) else # grab the items items = [] item_nodes = location_node.css('div.menu-item'.freeze) item_nodes.each do |item_node| item_allergens, item_name = [], item_node.text item_name.strip! item_node.parent.css('div.allergen div.diet'.freeze).each do |allergen_node| allergen = allergen_reference allergen_node['class'.freeze] item_allergens << allergen if allergen end items << Rice::Dining::Item.new(item_name, *item_allergens.sort) end locations << Rice::Dining::Location.new(name, *items) end end locations.sort! do |a, b| if a.closed? and b.open? 1 elsif a.open? and b.closed? -1 else a.name <=> b.name end end Rice::Dining::Manifest.new title, locations, @allergen_map.values else # Problem with the response raise CreateError, "got HTTP #{res.code} from #{Rice::Dining::BASE}" end end
Private Instance Methods
allergen_cleanup(allergens)
click to toggle source
# File lib/rice/dining.rb, line 216 def allergen_cleanup allergens ret = allergens.match(/\Adiet\s+(?<type>[a-z]+)/i) return nil if ret.nil? ret[:type].downcase.to_sym end
allergen_reference(allergen_class)
click to toggle source
# File lib/rice/dining.rb, line 192 def allergen_reference allergen_class # build the allergen key key = allergen_cleanup allergen_class return nil if key.nil? if !@allergen_map.include? key # find a unique value for the shortcode shortcode = key[0].to_sym if @allergen_shortcodes.include? shortcode shortcode = shortcode.swapcase while @allergen_shortcodes.include? shortcode shortcode = shortcode.downcase.succ end end # create the allergen allergen = @allergen_map[key] = Rice::Dining::Allergen.new(key, shortcode) @allergen_shortcodes << shortcode else allergen = @allergen_map[key] end end