diff --git a/src/modules/api/yelp.cr b/src/modules/api/yelp.cr
index 494ce58..d6baa87 100644
--- a/src/modules/api/yelp.cr
+++ b/src/modules/api/yelp.cr
@@ -1,9 +1,73 @@
require "http/client"
require "io"
+require "json"
module Wince::Yelp
extend self
+ class SearchResponse
+ include JSON::Serializable
+ property businesses : Array(Business)?
+ property error : Error?
+ end
+
+ class Error
+ include JSON::Serializable
+ property code : String
+ property description : String
+ end
+
+ class Business
+ include JSON::Serializable
+ property id : String
+ property name : String
+ property rating : Float32
+ property distance : Float32
+ end
+
+ class DetailsResponse
+ include JSON::Serializable
+ property error : Error?
+ property name : String
+ property price : String?
+ property display_phone : String?
+ property location : Location
+ property coordinates : Coordinates
+ property url : String
+ property hours : Array(Hours)
+
+ def is_open
+ hours[0].is_open_now
+ end
+ end
+
+ class Coordinates
+ include JSON::Serializable
+ property latitude : Float32
+ property longitude : Float32
+ end
+
+ class Location
+ include JSON::Serializable
+ property display_address : Array(String)
+ end
+
+ class Hours
+ include JSON::Serializable
+ property open : Array(Open)
+ property is_open_now : Bool
+ end
+
+ class Open
+ include JSON::Serializable
+ property is_overnight : Bool
+ @[JSON::Field(key: "start")]
+ property open : String
+ @[JSON::Field(key: "end")]
+ property close : String
+ property day : Int32
+ end
+
@@token : String = {{ read_file("./api_key") }}
def search_businesses(search : String, location : String)
@@ -21,6 +85,8 @@ module Wince::Yelp
)
headers = HTTP::Headers{ "Authorization" => "Bearer " + @@token }
response = HTTP::Client.get(uri, headers)
+
+ {response.status_code, SearchResponse.from_json(response.body)}
end
def get_business_info(id : String)
@@ -32,6 +98,8 @@ module Wince::Yelp
)
headers = HTTP::Headers{ "Authorization" => "Bearer " + @@token }
response = HTTP::Client.get(uri, headers)
+
+ {response.status_code, DetailsResponse.from_json(response.body)}
end
end
diff --git a/src/modules/utils/utils.cr b/src/modules/utils/utils.cr
index 20cd7ac..069eeea 100644
--- a/src/modules/utils/utils.cr
+++ b/src/modules/utils/utils.cr
@@ -3,13 +3,12 @@ require "time" # yeah me too
module Wince::Utils
extend self
- def hours_for_day(hours_json : JSON::Any, day : Time::DayOfWeek, seperator : String)
- open = hours_json[0]["open"].as_a
+ def hours_for_day(hours : Yelp::Hours, day : Time::DayOfWeek, seperator : String)
day_number = day_of_week_to_int(day)
- formatted_hours = open.select { |hour| hour["day"].as_i == day_number }.map { |hour|
- start_hour = hour["start"].as_s
- end_hour = hour["end"].as_s
+ formatted_hours = hours.open.select { |hour| hour.day == day_number }.map { |hour|
+ start_hour = hour.open
+ end_hour = hour.close
"#{start_hour.insert(2, ":")}-#{end_hour.insert(2, ":")}"
}.join(seperator)
@@ -34,11 +33,7 @@ module Wince::Utils
end
end
- def format_address(display_address_json : JSON::Any)
- display_address_json.as_a.map { |line| line.as_s? || "" }.join("\n")
+ def format_address(display_address : Array(String))
+ display_address.join("\n")
end
-
- def load_url_to_image(url : String, image : Gtk::Image)
-
- end
-end
\ No newline at end of file
+end
diff --git a/src/modules/views/main.cr b/src/modules/views/main.cr
index 15ab635..1385834 100644
--- a/src/modules/views/main.cr
+++ b/src/modules/views/main.cr
@@ -1,4 +1,3 @@
-require "json"
require "time"
require "../templates/businessrow.cr"
@@ -71,17 +70,13 @@ module Wince
end
end
- def yelp_response_to_business_ids(response : JSON::Any)
- response["businesses"].as_a.map { |b| b["id"].as_s }
+ def yelp_response_to_business_ids(businesses : Array(Yelp::Business))
+ businesses.map { |b| b.id }
end
- def yelp_response_to_business_rows(response : JSON::Any)
- response["businesses"].as_a.map do |business|
- name = business["name"].as_s? || ""
- rating = business["rating"].as_f32
- distance = business["distance"].as_f32
-
- BusinessRow.new(name, rating, distance)
+ def yelp_response_to_business_rows(businesses : Array(Yelp::Business))
+ businesses.map do |business|
+ BusinessRow.new(business.name, business.rating, business.distance)
end
end
@@ -106,19 +101,23 @@ module Wince
LEAFLET.visible = true
POWERD_BY_TEXT.visible = false
- response = Yelp.search_businesses(search, location)
+ status_code, response = Yelp.search_businesses(search, location)
- if response.status_code != 200
+ if status_code != 200
puts "api call error"
- puts response.body
+ if response.error.is_a? Yelp::Error
+ puts response.error.as(Yelp::Error).description
+ end
return #TODO: show a toast here
end
- response_json = JSON.parse(response.body)
+ # this can technically fail if we get a weird case of a 200 response
+ # but a malformed response, but it's probably fine
+ businesses = response.businesses.as(Array(Yelp::Business))
clear_business_rows()
- @@business_ids = yelp_response_to_business_ids(response_json)
- @@business_rows = yelp_response_to_business_rows(response_json)
+ @@business_ids = yelp_response_to_business_ids(businesses)
+ @@business_rows = yelp_response_to_business_rows(businesses)
@@business_rows.each do |row|
BUSINESS_LIST.append(row)
end
@@ -128,37 +127,36 @@ module Wince
index = @@business_rows.index(BUSINESS_LIST.selected_row) || 0
id = @@business_ids[index]
- response = Yelp.get_business_info(id)
+ status_code, response = Yelp.get_business_info(id)
- if response.status_code != 200
+ if status_code != 200
puts "api call error"
- puts response.body
+ if response.error.is_a? Yelp::Error
+ puts response.error.as(Yelp::Error).description
+ end
return #TODO: show a toast here
end
- response_json = JSON.parse(response.body)
- DETAILS_TITLE.text = response_json["name"].as_s? || ""
+ DETAILS_TITLE.text = response.name || ""
- is_open = response_json["hours"][0]["is_open_now"].as_bool? || false
-
- if is_open
+ if response.is_open
DETAILS_IS_OPEN.markup = "open"
else
DETAILS_IS_OPEN.markup = "closed"
end
- DETAILS_CURRENT_HOURS.text = Utils.hours_for_day(response_json["hours"], Time.local.day_of_week, ", ")
- DETAILS_PRICING.text = response_json["price"].as_s? || ""
- DETAILS_ADDRESS.markup = Utils.format_address(response_json["location"]["display_address"])
- DETAILS_PHONE.text = response_json["display_phone"].as_s? || "no phone number"
- DETAILS_URL.uri = response_json["url"].as_s? || ""
+ DETAILS_CURRENT_HOURS.text = Utils.hours_for_day(response.hours[0], Time.local.day_of_week, ", ")
+ DETAILS_PRICING.text = response.price || ""
+ DETAILS_ADDRESS.markup = Utils.format_address(response.location.display_address)
+ DETAILS_PHONE.text = response.display_phone || "no phone number"
+ DETAILS_URL.uri = response.url || ""
clear_hour_rows()
- @@hour_rows = format_hours(response_json["hours"])
+ @@hour_rows = format_hours(response.hours[0])
@@hour_rows.each { |hour_row| DETAILS_HOURS_BOX.append(hour_row) }
- set_map_location(response_json["coordinates"])
+ set_map_location(response.coordinates)
# If we're in the small layout we want to show the back button
if LEAFLET.folded
@@ -171,21 +169,18 @@ module Wince
LEAFLET.visible_child = DETAILS_SCROLL
end
- def set_map_location(coordinates : JSON::Any)
- latitude = coordinates["latitude"].as_f
- longitude = coordinates["longitude"].as_f
-
+ def set_map_location(coordinates : Yelp::Coordinates)
viewport = DETAILS_MAP.viewport
- viewport.set_location(latitude, longitude)
+ viewport.set_location(coordinates.latitude, coordinates.longitude)
viewport.zoom_level = 16
- @@marker.try {|m| m.set_location(latitude, longitude) }
+ @@marker.try {|m| m.set_location(coordinates.latitude, coordinates.longitude) }
end
- def format_hours(hours_json : JSON::Any)
+ def format_hours(hours : Yelp::Hours)
Time::DayOfWeek.values.map do |day|
- hours = Utils.hours_for_day(hours_json, day, "\n")
- HourRow.new(day, hours)
+ hours_for_day = Utils.hours_for_day(hours, day, "\n")
+ HourRow.new(day, hours_for_day)
end
end