touringplans 0.1.0 → 0.2.6
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/.rspec +3 -0
- data/.rubocop.yml +17 -2
- data/.version +1 -1
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +11 -5
- data/Rakefile +3 -7
- data/bin/console +4 -4
- data/lib/routes.yml +802 -0
- data/lib/touringplans/version.rb +1 -1
- data/lib/touringplans.rb +618 -16
- metadata +100 -9
- data/Gemfile.lock +0 -51
- data/touringplans.gemspec +0 -38
data/lib/touringplans/version.rb
CHANGED
data/lib/touringplans.rb
CHANGED
@@ -2,32 +2,634 @@
|
|
2
2
|
|
3
3
|
require_relative "touringplans/version"
|
4
4
|
require "httparty"
|
5
|
+
require "dry-struct"
|
6
|
+
|
7
|
+
# list and show attractions and eateries at Walt Disney World
|
5
8
|
module Touringplans
|
6
9
|
class Error < StandardError; end
|
7
|
-
|
10
|
+
|
11
|
+
module Types
|
12
|
+
include Dry.Types()
|
13
|
+
end
|
14
|
+
|
8
15
|
include HTTParty
|
9
|
-
|
16
|
+
# currently Touring Plans has no verision in its API
|
17
|
+
DEFAULT_API_VERSION = "1"
|
18
|
+
DEFAULT_BASE_URI = "https://touringplans.com/"
|
19
|
+
DEFAULT_QUERY = {}
|
20
|
+
|
21
|
+
base_uri DEFAULT_BASE_URI
|
22
|
+
|
23
|
+
ROUTES = {
|
24
|
+
magic_kingdom_dining: {
|
25
|
+
method: "get",
|
26
|
+
path: "/magic-kingdom/dining.json"
|
27
|
+
},
|
28
|
+
magic_kingdom_attractions: {
|
29
|
+
method: "get",
|
30
|
+
path: "/magic-kingdom/attractions.json"
|
31
|
+
},
|
32
|
+
animal_kingdom_dining: {
|
33
|
+
method: "get",
|
34
|
+
path: "/animal-kingdom/dining.json"
|
35
|
+
},
|
36
|
+
animal_kingdom_attractions: {
|
37
|
+
method: "get",
|
38
|
+
path: "/animal-kingdom/attractions.json"
|
39
|
+
},
|
40
|
+
epcot_dining: {
|
41
|
+
method: "get",
|
42
|
+
path: "/epcot/dining.json"
|
43
|
+
},
|
44
|
+
epcot_attractions: {
|
45
|
+
method: "get",
|
46
|
+
path: "/epcot/attractions.json"
|
47
|
+
},
|
48
|
+
hollywood_studios_dining: {
|
49
|
+
method: "get",
|
50
|
+
path: "/hollywood-studios/dining.json"
|
51
|
+
},
|
52
|
+
hollywood_studios_attractions: {
|
53
|
+
method: "get",
|
54
|
+
path: "/hollywood-studios/attractions.json"
|
55
|
+
},
|
56
|
+
walt_disney_world_hotels: {
|
57
|
+
method: "get",
|
58
|
+
path: "/walt-disney-world/hotels.json"
|
59
|
+
},
|
60
|
+
walt_disney_world_campground: {
|
61
|
+
method: "get",
|
62
|
+
path: "/walt-disney-world/hotels.json"
|
63
|
+
},
|
64
|
+
walt_disney_world_deluxe_hotels: {
|
65
|
+
method: "get",
|
66
|
+
path: "/walt-disney-world/hotels.json"
|
67
|
+
},
|
68
|
+
walt_disney_world_deluxe_villas: {
|
69
|
+
method: "get",
|
70
|
+
path: "/walt-disney-world/hotels.json"
|
71
|
+
},
|
72
|
+
walt_disney_world_moderate_hotels: {
|
73
|
+
method: "get",
|
74
|
+
path: "/walt-disney-world/hotels.json"
|
75
|
+
},
|
76
|
+
walt_disney_world_value_hotels: {
|
77
|
+
method: "get",
|
78
|
+
path: "/walt-disney-world/hotels.json"
|
79
|
+
},
|
80
|
+
walt_disney_world_disney_springs_resorts: {
|
81
|
+
method: "get",
|
82
|
+
path: "/walt-disney-world/hotels.json"
|
83
|
+
},
|
84
|
+
}
|
85
|
+
|
86
|
+
def self.routes
|
87
|
+
ROUTES
|
88
|
+
end
|
89
|
+
|
90
|
+
# deals solely with how to create access to the resource, the lock of "lock & key"
|
91
|
+
class Connection
|
92
|
+
# concerned only on where it gets the info it needs
|
93
|
+
# and maybe a version number
|
94
|
+
|
95
|
+
include HTTParty
|
96
|
+
# currently Touring Plans has no verision in its API
|
97
|
+
DEFAULT_API_VERSION = "1"
|
98
|
+
DEFAULT_BASE_URI = "https://touringplans.com/"
|
99
|
+
DEFAULT_QUERY = {}
|
100
|
+
|
101
|
+
base_uri DEFAULT_BASE_URI
|
102
|
+
|
103
|
+
def initialize(options = {})
|
104
|
+
@api_version = options.fetch(:api_version, DEFAULT_API_VERSION)
|
105
|
+
@query = options.fetch(:query, DEFAULT_QUERY)
|
106
|
+
@connection = self.class
|
107
|
+
end
|
108
|
+
|
109
|
+
def query(params = {})
|
110
|
+
@query.update(params)
|
111
|
+
end
|
112
|
+
|
113
|
+
def get(relative_path, query = {})
|
114
|
+
# relative_path = add_api_version(relative_path)
|
115
|
+
connection.get relative_path, query: @query.merge(query)
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
attr_reader :connection
|
121
|
+
# currently Touring Plans has no verision in its API
|
122
|
+
|
123
|
+
# def add_api_version(relative_path)
|
124
|
+
# "/#{api_version_path}#{relative_path}"
|
125
|
+
# end
|
126
|
+
|
127
|
+
# def api_version_path
|
128
|
+
# "v" + @api_version.to_s
|
129
|
+
# end
|
130
|
+
end
|
131
|
+
|
132
|
+
# deals solely with how to manage the connection, the key of "lock & key"
|
133
|
+
class Client
|
134
|
+
def initialize(connection:, routes:)
|
135
|
+
@connection = connection
|
136
|
+
@routes = routes
|
137
|
+
end
|
138
|
+
|
139
|
+
def method_missing(method, *request_arguments)
|
140
|
+
# retrieve the route map
|
141
|
+
route_map = routes.fetch(method)
|
142
|
+
|
143
|
+
# make request via the connection
|
144
|
+
response_from_route(route_map, request_arguments)
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
attr_reader :connection, :routes
|
10
150
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
151
|
+
def response_from_route(route_map, request_arguments)
|
152
|
+
# gather the routes required parameters
|
153
|
+
http_method = route_map.fetch(:method)
|
154
|
+
relative_path = route_map.fetch(:path)
|
155
|
+
|
156
|
+
# call the connection for records
|
157
|
+
connection.send(http_method, relative_path, *request_arguments)
|
158
|
+
end
|
15
159
|
end
|
16
160
|
|
17
|
-
|
18
|
-
|
19
|
-
|
161
|
+
class RoutesTable
|
162
|
+
require 'fileutils'
|
163
|
+
def initialize(filename: "routes_table.yml")
|
164
|
+
@filename = filename
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.original_routes
|
168
|
+
# this method exists so that we can create a yaml file of routes
|
169
|
+
tpr = Touringplans.routes
|
170
|
+
# convert symbols back to strings
|
171
|
+
stringify_keys(tpr)
|
172
|
+
# rt_keys = tpr.keys
|
173
|
+
# rt_values = tpr.values
|
174
|
+
# string_keys = []
|
175
|
+
|
176
|
+
# rt_keys.each {|k| string_keys << k.to_s}
|
177
|
+
# # create new hash with string keys
|
178
|
+
# string_keys.zip(rt_values).to_h
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.symbolize_keys(hash)
|
182
|
+
hash.inject({}){|result, (key, value)|
|
183
|
+
new_key = case key
|
184
|
+
when String then key.to_sym
|
185
|
+
else key
|
186
|
+
end
|
187
|
+
new_value = case value
|
188
|
+
when Hash then symbolize_keys(value)
|
189
|
+
else value
|
190
|
+
end
|
191
|
+
result[new_key] = new_value
|
192
|
+
result
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.stringify_keys(hash)
|
197
|
+
# inspired by https://avdi.codes/recursively-symbolize-keys/
|
198
|
+
hash.inject({}){|result, (key, value)|
|
199
|
+
new_key = case key
|
200
|
+
when Symbol then key.to_s
|
201
|
+
else key
|
202
|
+
end
|
203
|
+
new_value = case value
|
204
|
+
when Hash then stringify_keys(value)
|
205
|
+
else value
|
206
|
+
end
|
207
|
+
result[new_key] = new_value
|
208
|
+
result
|
209
|
+
}
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.load_routes_file(relative_file_path: "/lib/routes.yml")
|
213
|
+
routes_file = FileUtils.getwd() + relative_file_path
|
214
|
+
YAML.load(File.read(routes_file))
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
def self.update_file
|
219
|
+
# gather info into hashes
|
220
|
+
attractions_routes = _generate_interest_routes_hash("attractions")
|
221
|
+
dining_routes = _generate_interest_routes_hash("dining")
|
222
|
+
hotels_routes = {} #_generate_interest_routes_hash("hotels")
|
223
|
+
updated_routes = original_routes.merge(attractions_routes, dining_routes, hotels_routes)
|
224
|
+
|
225
|
+
updated_routes_yaml = _convert_hash_to_yaml(updated_routes)
|
226
|
+
|
227
|
+
file = _initialize_file
|
228
|
+
_save_content_to_file(file, updated_routes_yaml)
|
229
|
+
end
|
230
|
+
|
231
|
+
def self._initialize_file
|
232
|
+
# delete old file if it exits
|
233
|
+
lib_dir = FileUtils.getwd() + "/lib"
|
234
|
+
routes_file = "#{lib_dir}/routes.yml"
|
235
|
+
|
236
|
+
# ensure the file exists
|
237
|
+
touched_routes_file_array = FileUtils.touch(routes_file)
|
238
|
+
touched_routes_file = touched_routes_file_array.first
|
239
|
+
end
|
240
|
+
|
241
|
+
def self._generate_interest_routes_hash(interest)
|
242
|
+
interest_venues = Touringplans.list_all(interest)
|
243
|
+
interest_routes = {}
|
244
|
+
|
245
|
+
interest_venues.each do |iv|
|
246
|
+
new_route = self._generate_interest_route(iv.venue_permalink, interest, iv.permalink)
|
247
|
+
key = new_route.keys.first
|
248
|
+
values = new_route[key]
|
249
|
+
interest_routes[key] = values
|
250
|
+
end
|
251
|
+
|
252
|
+
interest_routes
|
253
|
+
end
|
254
|
+
|
255
|
+
def self._generate_interest_route(venue_permalink, interest_permalink, place_permalink)
|
256
|
+
# {magic_kingdom_attractions_haunted_mansion: {
|
257
|
+
# method: "get",
|
258
|
+
# path: "/magic-kingdom/attractions/haunted-mansion.json"
|
259
|
+
# }
|
260
|
+
# }
|
261
|
+
path = "/#{venue_permalink}/#{interest_permalink}/#{place_permalink}"
|
262
|
+
key = path.to_s.downcase.gsub("/", " ").gsub("-", " ").strip
|
263
|
+
key = key.gsub(" ", "_")
|
264
|
+
method = "get"
|
265
|
+
format = "json"
|
266
|
+
|
267
|
+
hash = { key => { "method".to_s => "get",
|
268
|
+
"path".to_s => "#{path}.#{format}"
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
hash
|
273
|
+
end
|
274
|
+
|
275
|
+
def self._convert_hash_to_yaml(hash)
|
276
|
+
hash.to_yaml
|
277
|
+
end
|
278
|
+
|
279
|
+
def self._save_content_to_file(file, content)
|
280
|
+
new_file = File.open(file, "w")
|
281
|
+
new_file.write(content)
|
282
|
+
new_file.close
|
283
|
+
end
|
284
|
+
|
285
|
+
def self._read_file_to_terminal(file)
|
286
|
+
new_file = File.open(file, "r")
|
287
|
+
new_file.close
|
288
|
+
end
|
289
|
+
|
20
290
|
end
|
291
|
+
# model with the attributes
|
292
|
+
class CounterServiceLocation < Dry::Struct
|
293
|
+
transform_keys(&:to_sym)
|
21
294
|
|
22
|
-
|
23
|
-
|
24
|
-
|
295
|
+
attribute :id, Types::Integer
|
296
|
+
attribute :land_id, Types::Integer
|
297
|
+
attribute :name, Types::String
|
298
|
+
attribute :permalink, Types::String
|
299
|
+
attribute :category_code, Types::String
|
300
|
+
attribute :portion_size, Types::String.optional
|
301
|
+
attribute :cost_code, Types::String.optional
|
302
|
+
attribute :cuisine, Types::String
|
303
|
+
attribute :phone_number, Types::String.optional
|
304
|
+
attribute :entree_range, Types::String.optional
|
305
|
+
attribute :when_to_go, Types::String.optional
|
306
|
+
attribute :parking, Types::String.optional
|
307
|
+
attribute :bar, Types::String.optional
|
308
|
+
attribute :wine_list, Types::String.optional
|
309
|
+
attribute :dress, Types::String.optional
|
310
|
+
attribute :awards, Types::String.optional
|
311
|
+
attribute :breakfast_hours, Types::String.optional
|
312
|
+
attribute :lunch_hours, Types::String.optional
|
313
|
+
attribute :dinner_hours, Types::String.optional
|
314
|
+
attribute :selection, Types::String.optional
|
315
|
+
attribute :setting_atmosphere, Types::String.optional
|
316
|
+
attribute :other_recommendations, Types::String.optional
|
317
|
+
attribute :summary, Types::String.optional
|
318
|
+
attribute :house_specialties, Types::String.optional
|
319
|
+
attribute :counter_quality_rating, Types::String.optional
|
320
|
+
attribute :counter_value_rating, Types::String.optional
|
321
|
+
attribute :table_quality_rating, Types::String.optional
|
322
|
+
attribute :table_value_rating, Types::String.optional
|
323
|
+
attribute :overall_rating, Types::Float.optional
|
324
|
+
attribute :service_rating, Types::String.optional
|
325
|
+
attribute :friendliness_rating, Types::String.optional
|
326
|
+
attribute :adult_breakfast_menu_url, Types::String.optional
|
327
|
+
attribute :adult_lunch_menu_url, Types::String.optional
|
328
|
+
attribute :adult_dinner_menu_url, Types::String.optional
|
329
|
+
attribute :child_breakfast_menu_url, Types::String.optional
|
330
|
+
attribute :child_lunch_menu_url, Types::String.optional
|
331
|
+
attribute :child_dinner_menu_url, Types::String.optional
|
332
|
+
attribute :requires_credit_card, Types::Params::Bool
|
333
|
+
attribute :requires_pre_payment, Types::Params::Bool
|
334
|
+
attribute :created_at, Types::Params::DateTime
|
335
|
+
attribute :updated_at, Types::Params::DateTime
|
336
|
+
attribute :plan_x_coord, Types::Coercible::Integer.optional
|
337
|
+
attribute :plan_y_coord, Types::Coercible::Integer.optional
|
338
|
+
attribute :old_park_id, Types::Params::Integer.optional
|
339
|
+
attribute :old_attraction_id, Types::Params::Integer.optional
|
340
|
+
attribute :plan_name, Types::String.optional
|
341
|
+
attribute :extinct_on, Types::Params::DateTime.optional
|
342
|
+
attribute :opened_on, Types::Params::DateTime.optional
|
343
|
+
attribute :disney_permalink, Types::String.optional
|
344
|
+
attribute :code, Types::String.optional
|
345
|
+
attribute :short_name, Types::String.optional
|
346
|
+
attribute :accepts_reservations, Types::Params::Bool
|
347
|
+
attribute :kosher_available, Types::Params::Bool
|
348
|
+
attribute :dinable_id, Types::Params::Integer
|
349
|
+
attribute :dinable_type, Types::String.optional
|
350
|
+
attribute :venue_permalink, Types::String.optional
|
25
351
|
end
|
26
352
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
353
|
+
# model with the attributes
|
354
|
+
class TableServiceLocation < Dry::Struct
|
355
|
+
transform_keys(&:to_sym)
|
356
|
+
|
357
|
+
attribute :id, Types::Integer
|
358
|
+
attribute :land_id, Types::Integer
|
359
|
+
attribute :name, Types::String
|
360
|
+
attribute :permalink, Types::String
|
361
|
+
attribute :category_code, Types::String
|
362
|
+
attribute :portion_size, Types::String.optional
|
363
|
+
attribute :cost_code, Types::String.optional
|
364
|
+
attribute :cuisine, Types::String
|
365
|
+
attribute :phone_number, Types::String.optional
|
366
|
+
attribute :entree_range, Types::String.optional
|
367
|
+
attribute :when_to_go, Types::String.optional
|
368
|
+
attribute :parking, Types::String.optional
|
369
|
+
attribute :bar, Types::String.optional
|
370
|
+
attribute :wine_list, Types::String.optional
|
371
|
+
attribute :dress, Types::String.optional
|
372
|
+
attribute :awards, Types::String.optional
|
373
|
+
attribute :breakfast_hours, Types::String.optional
|
374
|
+
attribute :lunch_hours, Types::String.optional
|
375
|
+
attribute :dinner_hours, Types::String.optional
|
376
|
+
attribute :selection, Types::String.optional
|
377
|
+
attribute :setting_atmosphere, Types::String.optional
|
378
|
+
attribute :other_recommendations, Types::String.optional
|
379
|
+
attribute :summary, Types::String.optional
|
380
|
+
attribute :house_specialties, Types::String.optional
|
381
|
+
attribute :counter_quality_rating, Types::String.optional
|
382
|
+
attribute :counter_value_rating, Types::String.optional
|
383
|
+
attribute :table_quality_rating, Types::Params::Decimal.optional
|
384
|
+
attribute :table_value_rating, Types::Params::Decimal.optional
|
385
|
+
attribute :overall_rating, Types::Params::Decimal.optional
|
386
|
+
attribute :service_rating, Types::Params::Decimal.optional
|
387
|
+
attribute :friendliness_rating, Types::Params::Decimal.optional
|
388
|
+
attribute :adult_breakfast_menu_url, Types::String.optional
|
389
|
+
attribute :adult_lunch_menu_url, Types::String.optional
|
390
|
+
attribute :adult_dinner_menu_url, Types::String.optional
|
391
|
+
attribute :child_breakfast_menu_url, Types::String.optional
|
392
|
+
attribute :child_lunch_menu_url, Types::String.optional
|
393
|
+
attribute :child_dinner_menu_url, Types::String.optional
|
394
|
+
attribute :requires_credit_card, Types::Params::Bool
|
395
|
+
attribute :requires_pre_payment, Types::Params::Bool
|
396
|
+
attribute :created_at, Types::Params::DateTime
|
397
|
+
attribute :updated_at, Types::Params::DateTime
|
398
|
+
attribute :plan_x_coord, Types::Params::Integer.optional
|
399
|
+
attribute :plan_y_coord, Types::Params::Integer.optional
|
400
|
+
attribute :old_park_id, Types::Params::Integer.optional
|
401
|
+
attribute :old_attraction_id, Types::Params::Integer.optional
|
402
|
+
attribute :plan_name, Types::String.optional
|
403
|
+
attribute :extinct_on, Types::Params::DateTime.optional
|
404
|
+
attribute :opened_on, Types::Params::DateTime.optional
|
405
|
+
attribute :disney_permalink, Types::String.optional
|
406
|
+
attribute :code, Types::String.optional
|
407
|
+
attribute :short_name, Types::String.optional
|
408
|
+
attribute :accepts_reservations, Types::Params::Bool
|
409
|
+
attribute :kosher_available, Types::Params::Bool
|
410
|
+
attribute :dinable_id, Types::Params::Integer
|
411
|
+
attribute :dinable_type, Types::String.optional
|
412
|
+
attribute :venue_permalink, Types::String.optional
|
31
413
|
end
|
32
414
|
|
415
|
+
# model with the attributes
|
416
|
+
class ParkAttraction < Dry::Struct
|
417
|
+
transform_keys(&:to_sym)
|
418
|
+
|
419
|
+
attribute :name, Types::String
|
420
|
+
attribute :short_name, Types::String
|
421
|
+
attribute :permalink, Types::String
|
422
|
+
attribute :venue_permalink, Types::String
|
423
|
+
|
424
|
+
end
|
425
|
+
|
426
|
+
# model with the attributes
|
427
|
+
class Hotel < Dry::Struct
|
428
|
+
transform_keys(&:to_sym)
|
429
|
+
|
430
|
+
attribute :name, Types::String
|
431
|
+
attribute :sort_name, Types::String
|
432
|
+
attribute :permalink, Types::String
|
433
|
+
attribute :category_code, Types::String.optional
|
434
|
+
attribute :venue_permalink, Types::String.optional
|
435
|
+
end
|
436
|
+
|
437
|
+
PLACE_KEYS = %i[magic_kingdom
|
438
|
+
animal_kingdom
|
439
|
+
epcot
|
440
|
+
hollywood_studios
|
441
|
+
walt_disney_world
|
442
|
+
].freeze
|
443
|
+
# {interest:"interest_type"}
|
444
|
+
INTERESTS = %i[counter_services
|
445
|
+
table_services
|
446
|
+
attractions
|
447
|
+
hotels
|
448
|
+
campground
|
449
|
+
deluxe_hotels
|
450
|
+
deluxe_villas
|
451
|
+
moderate_hotels
|
452
|
+
value_hotels
|
453
|
+
disney_springs_resorts
|
454
|
+
].freeze
|
455
|
+
HOTEL_CATEGORIES = %i[campground
|
456
|
+
deluxe_hotels
|
457
|
+
deluxe_villas
|
458
|
+
moderate_hotels
|
459
|
+
value_hotels
|
460
|
+
disney_springs_resorts]
|
461
|
+
|
462
|
+
# list interest at location
|
463
|
+
# current interest are "counter service" "table service", and "attractions"
|
464
|
+
# current locations are the four parks
|
465
|
+
def self.list(interest, location)
|
466
|
+
return "The location is not on Disney property" unless PLACE_KEYS.include? _symbolize(location)
|
467
|
+
return "The interest is not valid" unless INTERESTS.include? _symbolize(interest)
|
468
|
+
|
469
|
+
client = _setup_client
|
470
|
+
listings = []
|
471
|
+
interest_type = _determine_interest_type(interest)
|
472
|
+
route = _assemble_route(location, interest_type)
|
473
|
+
response = client.send(route).parsed_response
|
474
|
+
listing_hashes = _collect_listing_hashes_from_response(interest, response)
|
475
|
+
listing_hashes.each do |item|
|
476
|
+
item["venue_permalink"] = location.to_s.downcase.gsub(" ", "-")
|
477
|
+
end
|
478
|
+
|
479
|
+
listing_hashes
|
480
|
+
listing_hashes.each do |hash|
|
481
|
+
listing = _set_model_from_hash(interest, hash)
|
482
|
+
listings << listing
|
483
|
+
end
|
484
|
+
|
485
|
+
listings = list_hotels_of_a_category(listings, interest) if HOTEL_CATEGORIES.include? _symbolize(interest)
|
486
|
+
|
487
|
+
listings
|
488
|
+
end
|
489
|
+
|
490
|
+
def self.list_all(interest_type)
|
491
|
+
return "The interest_type is not valid" unless %i[dining attractions hotels].include? _symbolize(interest_type)
|
492
|
+
|
493
|
+
parks = ["Magic Kingdom", "Animal Kingdom", "Epcot", "Hollywood Studios"]
|
494
|
+
places = []
|
495
|
+
|
496
|
+
if interest_type == "attractions"
|
497
|
+
parks.each do |park|
|
498
|
+
list = Touringplans.list("attractions", park)
|
499
|
+
places << list
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
if interest_type == "dining"
|
504
|
+
parks.each do |park|
|
505
|
+
list = Touringplans.list("counter services", park)
|
506
|
+
places << list
|
507
|
+
list = Touringplans.list("table services", park)
|
508
|
+
places << list
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
if interest_type == "hotels"
|
513
|
+
HOTEL_CATEGORIES.each do |category|
|
514
|
+
list = Touringplans.list(category.to_s, "walt_disney_world")
|
515
|
+
places << list
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
places.flatten
|
520
|
+
end
|
521
|
+
|
522
|
+
def self.show(interest_type, short_name)
|
523
|
+
return "The interest_type is not valid" unless %i[dining attractions hotels].include? _symbolize(interest_type)
|
524
|
+
|
525
|
+
# get a list of every model of one kind of interest_type (dining, attractions, hotels)
|
526
|
+
places = list_all(interest_type)
|
527
|
+
|
528
|
+
# filter by short_name
|
529
|
+
places.find { |place| place.short_name == short_name }
|
530
|
+
end
|
531
|
+
|
532
|
+
def self._setup_client
|
533
|
+
connection = Connection.new
|
534
|
+
connection.query(key: "HowdyLen")
|
535
|
+
routes = Touringplans::RoutesTable.symbolize_keys(Touringplans::RoutesTable.load_routes_file)
|
536
|
+
Client.new(connection: connection, routes: routes)
|
537
|
+
|
538
|
+
end
|
539
|
+
|
540
|
+
def self._format_location_name(location_name)
|
541
|
+
location_name.to_s.downcase.gsub(" ", "-")
|
542
|
+
end
|
543
|
+
|
544
|
+
def self._determine_interest_type(interest)
|
545
|
+
interest_type = interest
|
546
|
+
|
547
|
+
interest_type = "dining" if interest == "counter services"
|
548
|
+
interest_type = "dining" if interest == "table services"
|
549
|
+
interest_type = "hotels" if %i[campground deluxe_hotels deluxe_villas moderate_hotels value_hotels disney_springs_resorts
|
550
|
+
].include? _symbolize(interest)
|
551
|
+
|
552
|
+
interest_type
|
553
|
+
end
|
554
|
+
|
555
|
+
def self._symbolize(item)
|
556
|
+
## turn a Stringinto a symbol, like comparing to PLACE_KEYS
|
557
|
+
# if item is a path or name we need to turn it into a phrase of words
|
558
|
+
str = item.to_s.downcase.gsub("/", " ").gsub("-", " ").strip
|
559
|
+
# turn item into a symbol
|
560
|
+
str = str.gsub(" ", "_")
|
561
|
+
str.to_sym
|
562
|
+
end
|
563
|
+
|
564
|
+
|
565
|
+
def self._assemble_route(location, interest_type)
|
566
|
+
formatted_location = location.to_s.downcase.gsub(" ", "_")
|
567
|
+
formatted_interest_type = interest_type.to_s.downcase.gsub(" ", "_")
|
568
|
+
"#{formatted_location}_#{formatted_interest_type}"
|
569
|
+
end
|
570
|
+
|
571
|
+
def self._collect_listing_hashes_from_response(interest, response)
|
572
|
+
hotel_categories = %i[campground deluxe_hotels deluxe_villas moderate_hotels value_hotels disney_springs_resorts]
|
573
|
+
|
574
|
+
listing_hashes = response if interest == "attractions"
|
575
|
+
listing_hashes = response if interest == "dining"
|
576
|
+
listing_hashes = response[0] if interest == "counter services"
|
577
|
+
listing_hashes = response[1] if interest == "table services"
|
578
|
+
|
579
|
+
listing_hashes = list_all_hotels(response) if interest == "hotels"
|
580
|
+
listing_hashes = list_all_hotels(response) if hotel_categories.include? _symbolize(interest)
|
581
|
+
|
582
|
+
listing_hashes
|
583
|
+
end
|
584
|
+
|
585
|
+
def self.list_all_hotels(response_from_touringplans_hotels_url)
|
586
|
+
listing_hashes = []
|
587
|
+
|
588
|
+
response_from_touringplans_hotels_url.each do |child|
|
589
|
+
child.each do |grandchild|
|
590
|
+
if "#{grandchild.class}" == "Array"
|
591
|
+
listing_hashes << grandchild
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
listing_hashes.flatten
|
597
|
+
end
|
598
|
+
|
599
|
+
# search for hotels of a category_code
|
600
|
+
def self.list_hotels_of_a_category(hotels, interest)
|
601
|
+
hotel_categories = {campground:"campground", deluxe_hotels:"deluxe",
|
602
|
+
deluxe_villas:"deluxe_villa", moderate_hotels:"moderate",
|
603
|
+
value_hotels:"value", disney_springs_resorts: NilClass}
|
604
|
+
# get a list of every hotel model
|
605
|
+
|
606
|
+
# filter by category_code
|
607
|
+
# disney springs category code is null. We need to find a rule for finding those that don't have any of the values of
|
608
|
+
# hotel categories
|
609
|
+
if interest == "disney springs resorts"
|
610
|
+
target_hotels = hotels.find_all { |hotel| hotel.category_code.class == NilClass }
|
611
|
+
|
612
|
+
else
|
613
|
+
target_hotels = hotels.find_all { |hotel| hotel.category_code == hotel_categories[_symbolize(interest)] }
|
614
|
+
|
615
|
+
end
|
616
|
+
|
617
|
+
target_hotels
|
618
|
+
end
|
619
|
+
|
620
|
+
def generate_route_table
|
621
|
+
# initial_routes = ROUTES
|
622
|
+
|
623
|
+
end
|
624
|
+
|
625
|
+
|
626
|
+
def self._set_model_from_hash(interest, hash)
|
627
|
+
hotel_categories = %i[campground deluxe_hotels deluxe_villas moderate_hotels value_hotels disney_springs_resorts hotels]
|
628
|
+
|
629
|
+
listing = CounterServiceLocation.new(hash) if interest == "counter services"
|
630
|
+
listing = TableServiceLocation.new(hash) if interest == "table services"
|
631
|
+
listing = ParkAttraction.new(hash) if interest == "attractions"
|
632
|
+
listing = Hotel.new(hash) if hotel_categories.include? _symbolize(interest)
|
633
|
+
listing
|
634
|
+
end
|
33
635
|
end
|