ratis 2.5.2.1

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.
@@ -0,0 +1,22 @@
1
+ module Ratis
2
+
3
+ class LandmarkCategory
4
+
5
+ attr_accessor :type, :description
6
+
7
+ def self.all
8
+
9
+ response = Request.get 'Getcategories'
10
+ return [] unless response.success?
11
+
12
+ response.to_array(:getcategories_response, :types, :typeinfo).map do |typeinfo|
13
+ atis_landmark_category = LandmarkCategory.new
14
+ atis_landmark_category.type = typeinfo[:type]
15
+ atis_landmark_category.description = typeinfo[:description]
16
+ atis_landmark_category
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,71 @@
1
+ module Ratis
2
+
3
+ class Location
4
+
5
+ attr_accessor :name, :area, :response, :areacode, :latitude, :longitude, :landmark_id, :address, :startaddr, :endaddr, :address_string
6
+
7
+ def self.where(conditions)
8
+ location = conditions.delete :location
9
+ media = (conditions.delete(:media) || :w).to_s.upcase
10
+ max_answers = conditions.delete(:max_answers) || 20
11
+
12
+ raise ArgumentError.new('You must provide a location') unless location
13
+ raise ArgumentError.new('You must provide media of A|W|I') unless ['A','W','I'].include? media
14
+ raise ArgumentError.new('You must provide a numeric max_answers') unless (Integer max_answers rescue false)
15
+ Ratis.all_conditions_used? conditions
16
+
17
+ response = Request.get 'Locate', {'Location' => location, 'Media' => media, 'Maxanswers' => max_answers}
18
+ return [] unless response.success?
19
+
20
+ meta = response.to_hash[:locate_response]
21
+ locations = response.to_array :locate_response, :location
22
+
23
+ locations.map do |location_hash|
24
+ location = Ratis::Location.new
25
+ location.name = location_hash[:name]
26
+ location.area = location_hash[:area]
27
+ location.response = meta[:responsecode]
28
+ location.areacode = location_hash[:areacode]
29
+ location.latitude = location_hash[:latitude]
30
+ location.longitude = location_hash[:longitude]
31
+ location.landmark_id = location_hash[:landmarkid] || 0
32
+ location.address = location_hash[:address] || ''
33
+ location.startaddr = location_hash[:startaddr] || ''
34
+ location.endaddr = location_hash[:endaddr] || ''
35
+ location.address_string = build_address_string location_hash
36
+ location
37
+ end
38
+ end
39
+
40
+ def to_a
41
+ [latitude, longitude, name, landmark_id]
42
+ end
43
+
44
+ def to_hash
45
+ keys = [:latitude, :longitude, :name, :area, :address, :startaddr, :endaddr, :address_string, :landmark_id]
46
+ Hash[keys.map { |k| [k, send(k)] }]
47
+ end
48
+
49
+ private
50
+
51
+ def self.build_address_string(location_hash)
52
+ address_string = ''
53
+ address = location_hash[:address]
54
+ name = location_hash[:name]
55
+ area = location_hash[:area]
56
+
57
+ if !address.blank?
58
+ address_string << "#{address} #{name} (in #{area})"
59
+ else
60
+ startaddr = location_hash[:startaddr]
61
+ if !startaddr.blank?
62
+ endaddr = location_hash[:endaddr]
63
+ address_string << "#{startaddr} - #{endaddr} #{name} (in #{area})"
64
+ else
65
+ address_string << "#{name} (in #{area})"
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,93 @@
1
+ module Ratis
2
+
3
+ class NextBus
4
+
5
+ attr_accessor :stops, :runs
6
+
7
+ # Initializes a NextBus object with stops and runs.
8
+ # @return [NextBus]
9
+ #
10
+ # == Parameters:
11
+ #
12
+ # [stops] <em>Optional</em> -
13
+ # An array of stops. Defaults to empty array.
14
+ # [runs] <em>Optional</em> -
15
+ # An array of runs. Defaults to empty array.
16
+
17
+ def initialize(_stops = [], _runs = [])
18
+ @stops, @runs = _stops, _runs
19
+ end
20
+
21
+ # Returns results of NextBus query containing arrays of stops and runs.
22
+ # @return [NextBus] containing next buses.
23
+ #
24
+ # == Parameters:
25
+ #
26
+ # Takes hash of conditions
27
+ #
28
+ # [option1] <b>Required</b> -
29
+ # Description of required param
30
+ # [option2] <em>Optional</em> -
31
+ # Description of optional param
32
+ # [option3] <em>Optional</em> -
33
+ # Description of optional param
34
+ # [option4] <em>Optional</em> -
35
+ # Description of optional param
36
+
37
+ def self.where(conditions)
38
+ stop_id = conditions.delete :stop_id
39
+ app_id = conditions.delete(:app_id) || 'na'
40
+
41
+ raise ArgumentError.new('You must provide a stop ID') unless stop_id
42
+ Ratis.all_conditions_used? conditions
43
+
44
+ response = Request.get 'Nextbus2', { 'Stopid' => stop_id, 'Appid' => app_id }
45
+ return [] unless response.success?
46
+
47
+ stops = response.to_array :nextbus2_response, :stops, :stop
48
+ runs = response.to_array :nextbus2_response, :runs, :run
49
+
50
+ NextBus.new stops, runs
51
+ end
52
+
53
+ # Gets description of first stop
54
+ # @return [String] Description of first stop or nil.
55
+
56
+ def first_stop_description
57
+ stops.first ? stops.first[:description] : nil
58
+ end
59
+
60
+ # Details of NextBus instance in a hash.
61
+ # @return [Hash] NextBus details in a hash.
62
+
63
+ def to_hash
64
+ { :stopname => first_stop_description,
65
+ :signs => runs.map { |run| run[:sign] }.uniq,
66
+ :runs => runs.map do |run|
67
+ { :time => run[:estimatedtime],
68
+ :sign => run[:sign],
69
+ :adherence => run[:adherence],
70
+ :route => run[:route]
71
+ }
72
+ end
73
+ }
74
+ end
75
+
76
+ # Details of NextBus instance in a hash to be transformed to xml
77
+ # @private
78
+
79
+ def to_hash_for_xml
80
+ { :stopname => first_stop_description,
81
+ :runs => runs.map do |run|
82
+ { :time => run[:estimatedtime],
83
+ :scheduled_time => run[:triptime],
84
+ :sign => run[:sign],
85
+ :adherence => run[:adherence],
86
+ :route => run[:route]
87
+ }
88
+ end
89
+ }
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,112 @@
1
+ module Ratis
2
+
3
+ class Point2Point
4
+
5
+ def self.where(conditions)
6
+ routes_only = conditions.delete(:routes_only)
7
+
8
+ origin_lat = conditions.delete(:origin_lat).to_f
9
+ origin_long = conditions.delete(:origin_long).to_f
10
+ destination_lat = conditions.delete(:destination_lat).to_f
11
+ destination_long = conditions.delete(:destination_long).to_f
12
+
13
+ date = conditions.delete :date
14
+ start_time = conditions.delete :start_time
15
+ end_time = conditions.delete :end_time
16
+
17
+ raise ArgumentError.new("You must specify routes only with true, false, 'y' or 'n'") unless routes_only.y_or_n rescue false
18
+
19
+ raise ArgumentError.new('You must provide an origin latitude') unless Ratis.valid_latitude? origin_lat
20
+ raise ArgumentError.new('You must provide an origin longitude') unless Ratis.valid_longitude? origin_long
21
+ raise ArgumentError.new('You must provide an destination latitude') unless Ratis.valid_latitude? destination_lat
22
+ raise ArgumentError.new('You must provide an destination longitude') unless Ratis.valid_longitude? destination_long
23
+
24
+ raise ArgumentError.new('You must provide a date DD/MM/YYYY') unless DateTime.strptime(date, '%d/%m/%Y') rescue false
25
+ raise ArgumentError.new('You must provide a start time as 24-hour HHMM') unless DateTime.strptime(start_time, '%H%M') rescue false
26
+ raise ArgumentError.new('You must provide an end time as 24-hour HHMM') unless DateTime.strptime(end_time, '%H%M') rescue false
27
+
28
+ Ratis.all_conditions_used? conditions
29
+
30
+ response = Request.get 'Point2point', 'Routesonly' => routes_only.y_or_n.upcase,
31
+ 'Originlat' => origin_lat, 'Originlong' => origin_long,
32
+ 'Destinationlat' => destination_lat, 'Destinationlong' => destination_long,
33
+ 'Date' => date, 'Starttime' => start_time, 'Endtime' => end_time
34
+
35
+ return nil unless response.success?
36
+
37
+ return parse_routes_only_yes response if routes_only.y_or_n.downcase == 'y'
38
+ return parse_routes_only_no response if routes_only.y_or_n.downcase == 'n'
39
+
40
+ nil
41
+ end
42
+
43
+ private
44
+
45
+ def self.parse_routes_only_yes(response)
46
+ response.to_array(:point2point_response, :routes, :service).map do |service|
47
+ atis_service = Service.new
48
+ atis_service.route = service[:route]
49
+ atis_service.direction = service[:direction]
50
+ atis_service.service_type = service[:servicetype]
51
+ atis_service.signage = service[:signage]
52
+ atis_service.route_type = service[:routetype]
53
+ atis_service
54
+ end
55
+ end
56
+
57
+ def self.parse_routes_only_no(response)
58
+ return nil unless response.success?
59
+
60
+ atis_schedule = Schedule.new
61
+ atis_schedule.groups = response.to_array(:point2point_response, :groups, :group).map do |group|
62
+ atis_schedule_group = ScheduleGroup.new
63
+
64
+ # Point2point 1.3 uses inconsistent tag naming, thus: <onstop> <onwalk...>, but <offstop> <offstopwalk...>
65
+ # this docs says this is fixed in 1.4, so watch out
66
+ atis_schedule_group.on_stop = atis_stop_from_hash 'on', group[:onstop]
67
+ atis_schedule_group.off_stop = atis_stop_from_hash 'offstop', group[:offstop]
68
+
69
+ atis_schedule_group.trips = group.to_array(:trips, :trip).map do |trip|
70
+ atis_trip = ScheduleTrip.new
71
+ atis_trip.on_time = trip[:ontime]
72
+ atis_trip.off_time = trip[:offtime]
73
+
74
+ atis_trip.service = trip.to_array(:service).map do |service|
75
+ atis_service = Service.new
76
+
77
+ atis_service.route = service[:route]
78
+ atis_service.direction = service[:direction]
79
+ atis_service.service_type = service[:servicetype]
80
+ atis_service.signage = service[:signage]
81
+ atis_service.route_type = service[:routetype]
82
+ atis_service.exception = service[:exception]
83
+ atis_service
84
+ end.first
85
+
86
+ atis_trip
87
+ end
88
+
89
+ atis_schedule_group
90
+ end
91
+
92
+ atis_schedule
93
+ end
94
+
95
+ def self.atis_stop_from_hash(prefix, stop)
96
+ return nil if stop.blank?
97
+
98
+ atis_stop = Stop.new
99
+ atis_stop.description = stop[:description]
100
+ atis_stop.atis_stop_id = stop[:atisstopid].to_i
101
+ atis_stop.latitude = stop[:lat].to_f
102
+ atis_stop.longitude = stop[:long].to_f
103
+
104
+ # It appears that both *walk and *walkdist are used for the walk distance, covering both here
105
+ atis_stop.walk_dist = (stop["#{prefix}walk".to_sym] || stop["#{prefix}walkdist".to_sym]).to_f
106
+ atis_stop.walk_dir = stop["#{prefix}walkdir".to_sym]
107
+ atis_stop.walk_hint = stop["#{prefix}walkhint".to_sym]
108
+ atis_stop
109
+ end
110
+ end
111
+
112
+ end
@@ -0,0 +1,39 @@
1
+ module Ratis
2
+
3
+ class Request
4
+
5
+ extend Savon::Model
6
+
7
+ def initialize(config = nil)
8
+ config = Ratis.config if config.nil?
9
+ raise Errors::ConfigError('It appears that Ratis.configure has not been called') unless config.valid?
10
+ self.class.client do
11
+ wsdl.endpoint = Ratis.config.endpoint
12
+ wsdl.namespace = Ratis.config.namespace
13
+ http.proxy = Ratis.config.proxy unless Ratis.config.proxy.blank?
14
+ http.open_timeout = Ratis.config.timeout unless Ratis.config.timeout.blank?
15
+ end
16
+ rescue ArgumentError => e
17
+ raise ArgumentError.new 'Invalid ATIS SOAP server configuration: ' + e.message
18
+ end
19
+
20
+ def self.get(action, params = {})
21
+ begin
22
+ req = new Ratis.config
23
+ response = client.request action, :soap_action => "#{Ratis.config.namespace}##{action}", :xmlns => Ratis.config.namespace do
24
+ soap.body = params unless params.blank?
25
+ end
26
+
27
+ version = response.to_hash["#{action.downcase}_response".to_sym][:version]
28
+
29
+ response
30
+ rescue Errno::ECONNREFUSED => e
31
+ raise Errno::ECONNREFUSED.new 'Refused request to ATIS SOAP server'
32
+ rescue Savon::SOAP::Fault => e
33
+ raise Errors::SoapError.new e
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,31 @@
1
+ module Ratis
2
+
3
+ class Route
4
+
5
+ attr_accessor :short_name, :directions
6
+
7
+ def self.all
8
+ response = Request.get 'Allroutes'
9
+ return [] unless response.success?
10
+
11
+ routes = response.to_hash[:allroutes_response][:routes].split(/\n/)
12
+ atis_routes = routes.map do |r|
13
+ r.strip!
14
+ next if r.blank?
15
+ r = r.split(/, /)
16
+ Route.new r[0].strip, r[1..-1].map(&:strip)
17
+ end
18
+ atis_routes.compact
19
+ end
20
+
21
+ def initialize(short_name, directions)
22
+ self.short_name = short_name
23
+ self.directions = directions
24
+ end
25
+
26
+ def timetable(conditions)
27
+ Timetable.where conditions.merge :route_short_name => short_name
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,40 @@
1
+ module Ratis
2
+
3
+ ################################# EXAMPLE ############################################
4
+ #
5
+ # Ratis::RouteStops.all :route => 8, :direction => 'S', :order => 'S'
6
+ #
7
+ ######################################################################################
8
+
9
+ class RouteStops
10
+
11
+ def self.all(conditions)
12
+ route = conditions.delete :route
13
+ direction = conditions.delete(:direction).to_s.upcase
14
+ order = conditions.delete(:order).to_s.upcase
15
+
16
+ raise ArgumentError.new('You must provide a route') unless route
17
+ raise ArgumentError.new('You must provide a direction') unless direction
18
+
19
+ Ratis.all_conditions_used? conditions
20
+
21
+ request_params = {'Route' => route, 'Direction' => direction }
22
+ request_params.merge! order ? { 'Order' => order } : {}
23
+ response = Request.get 'Routestops', request_params
24
+
25
+ return [] unless response.success?
26
+
27
+ response.to_hash[:routestops_response][:stops][:stop].map do |s|
28
+ stop = Stop.new
29
+ stop.description = s[:description]
30
+ stop.area = s[:area]
31
+ stop.atis_stop_id = s[:atisstopid]
32
+ stop.stop_seq = s[:stopseq]
33
+ stop.latitude, stop.longitude = s[:point].split ','
34
+ stop
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,7 @@
1
+ module Ratis
2
+
3
+ class Schedule < Struct.new(:groups)
4
+
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ module Ratis
2
+
3
+ class ScheduleGroup < Struct.new(:on_stop, :off_stop, :trips)
4
+
5
+ end
6
+
7
+ end
@@ -0,0 +1,79 @@
1
+ module Ratis
2
+
3
+ class ScheduleNearby
4
+
5
+ attr_accessor :atstops
6
+
7
+ def self.where(conditions)
8
+ latitude = conditions.delete :latitude
9
+ longitude = conditions.delete :longitude
10
+ date = conditions.delete :date
11
+ time = conditions.delete :time
12
+ window = conditions.delete :window
13
+ walk_distance = conditions.delete :walk_distance
14
+ landmark_id = conditions.delete :landmark_id
15
+ stop_id = conditions.delete(:stop_id) || ''
16
+ app_id = conditions.delete(:app_id) || 'na'
17
+
18
+ raise ArgumentError.new('You must provide latitude') unless latitude
19
+ raise ArgumentError.new('You must provide longitude') unless longitude
20
+ raise ArgumentError.new('You must provide date') unless date
21
+ raise ArgumentError.new('You must provide time') unless time
22
+ raise ArgumentError.new('You must provide window') unless window
23
+ raise ArgumentError.new('You must provide walk_distance') unless walk_distance
24
+ raise ArgumentError.new('You must provide landmark_id') unless landmark_id
25
+ Ratis.all_conditions_used? conditions
26
+
27
+ response = Request.get 'Schedulenearby',
28
+ {'Locationlat' => latitude, 'Locationlong' => longitude,
29
+ 'Date' => date, 'Time' => time, 'Window' => window, 'Walkdist' => walk_distance,
30
+ 'Landmarkid' => landmark_id, 'Stopid' => stop_id, 'Appid' => app_id
31
+ }
32
+
33
+ return [] unless response.success?
34
+
35
+ atstops = response.to_array :schedulenearby_response, :atstop
36
+ atstops.map do |atstop|
37
+ atstop[:services] = atstop.to_array :service
38
+
39
+ atstop[:services].map do |service|
40
+ service[:tripinfos] = service.to_array :tripinfo
41
+ end
42
+ end
43
+
44
+ schedule_nearby = ScheduleNearby.new
45
+ schedule_nearby.atstops = atstops
46
+
47
+ schedule_nearby
48
+ end
49
+
50
+ def to_hash
51
+ {
52
+ :atstops => atstops.map do |atstop|
53
+ {
54
+ :description => atstop[:description],
55
+ :walkdist => atstop[:walkdist],
56
+ :walkdir => atstop[:walkdir],
57
+ :stopid => atstop[:stopid],
58
+ :lat => atstop[:lat],
59
+ :long => atstop[:long],
60
+ :services => atstop[:services].map do |service|
61
+ {
62
+ :route => service[:route],
63
+ :routetype => service[:routetype],
64
+ :operator => service[:operator],
65
+ :sign => service[:sign],
66
+ :times => service[:times],
67
+ :trips => service[:tripinfos].map do |tripinfo|
68
+ { :triptime => tripinfo[:triptime] }
69
+ end
70
+ }
71
+ end
72
+ }
73
+ end
74
+ }
75
+ end
76
+
77
+ end
78
+
79
+ end