module RedRoosterStores
Public Instance Methods
Source
# File lib/red_rooster_stores.rb, line 58 def component_value(components, key) value = components.dig(key, "value") text = value.to_s.strip text.empty? ? nil : text end
Source
# File lib/red_rooster_stores.rb, line 64 def find_store(location, stores:) query = normalize_query(location) return nil if query.empty? scored = stores.filter_map do |store| score = score_store(store, query) score.positive? ? [store, score] : nil end scored.max_by { |(_store, score)| score }&.first end
Source
# File lib/red_rooster_stores.rb, line 76 def normalize_query(location) location.to_s.downcase.gsub(/[^a-z0-9\s]/, " ").squeeze(" ").strip end
Source
# File lib/red_rooster_stores.rb, line 12 def parse_location(text) value = text.to_s.strip return { error: usage_message } if value.empty? if value.match?(%r{\A["']}) unless (match = value.match(%r{\A["'](.+?)["']\z})) return { error: usage_message } end location = match[1].strip return { error: usage_message } if location.empty? return { location: location } end { location: value } end
Source
# File lib/red_rooster_stores.rb, line 37 def parse_store(entry) attrs = entry["attributes"] || {} return nil unless attrs["isEnabled"] slug = entry.dig("relationships", "slug", "data", "attributes", "slug").to_s.strip address = entry.dig("relationships", "storeAddress", "data", "attributes", "addressComponents") || {} { id: entry["id"], name: attrs["storeName"].to_s.strip, slug: slug, suburb: component_value(address, "suburb"), state: component_value(address, "state"), postcode: component_value(address, "postcode"), latitude: component_value(address, "latitude")&.to_f, longitude: component_value(address, "longitude")&.to_f } rescue StandardError nil end
Source
# File lib/red_rooster_stores.rb, line 30 def parse_stores(payload) data = payload.is_a?(String) ? JSON.parse(payload) : payload Array(data["data"]).filter_map { |entry| parse_store(entry) } rescue StandardError [] end
Source
# File lib/red_rooster_stores.rb, line 80 def score_store(store, query) score = 0 tokens = query.split suburb = store[:suburb].to_s.downcase slug = store[:slug].to_s.downcase name = store[:name].to_s.downcase postcode = store[:postcode].to_s state = store[:state].to_s.downcase return 1000 if query == suburb return 950 if query == slug return 900 if query == postcode return 850 if query == name score += 500 if suburb == query || slug == query score += 450 if suburb.start_with?(query) || slug.start_with?(query) score += 400 if query.include?(suburb) && !suburb.empty? score += 380 if query.include?(slug) && !slug.empty? score += 300 if tokens.all? { |token| [suburb, slug, name, state].any? { |field| field.include?(token) } } score += 250 if tokens.any? { |token| postcode == token } score += 200 if tokens.any? { |token| token.length >= 3 && suburb.include?(token) } score += 180 if tokens.any? { |token| token.length >= 3 && slug.include?(token) } score += 150 if tokens.any? { |token| token.length >= 3 && name.include?(token) } score end
Source
# File lib/red_rooster_stores.rb, line 8 def usage_message 'Usage: !redrooster <location> — quote multi-word locations, e.g. !redrooster "mount isa qld"' end