ldbws 1.0.0

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.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +14 -0
  3. data/.envrc +1 -0
  4. data/.gitignore +8 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +79 -0
  7. data/LICENSE +21 -0
  8. data/Makefile +8 -0
  9. data/README.md +47 -0
  10. data/doc/LICENSE.html +93 -0
  11. data/doc/Ldbws/Request/GetDeparturesBoard.html +114 -0
  12. data/doc/Ldbws/Request/GetDeparturesBoardWithDetails.html +116 -0
  13. data/doc/Ldbws/Request/GetServiceDetails.html +105 -0
  14. data/doc/Ldbws/Request/GetStationBoard.html +120 -0
  15. data/doc/Ldbws/Request/GetStationBoardWithDetails.html +120 -0
  16. data/doc/Ldbws/Request.html +91 -0
  17. data/doc/Ldbws/ResponseTypes/BaseStationBoard.html +108 -0
  18. data/doc/Ldbws/ResponseTypes/CallingPoint.html +129 -0
  19. data/doc/Ldbws/ResponseTypes/Coach.html +114 -0
  20. data/doc/Ldbws/ResponseTypes/DepartureItem.html +108 -0
  21. data/doc/Ldbws/ResponseTypes/DepartureItemWithDetails.html +108 -0
  22. data/doc/Ldbws/ResponseTypes/DeparturesBoard.html +105 -0
  23. data/doc/Ldbws/ResponseTypes/DeparturesBoardWithDetails.html +105 -0
  24. data/doc/Ldbws/ResponseTypes/Formation.html +108 -0
  25. data/doc/Ldbws/ResponseTypes/LoadingCategory.html +105 -0
  26. data/doc/Ldbws/ResponseTypes/Location.html +105 -0
  27. data/doc/Ldbws/ResponseTypes/ServiceDetails.html +143 -0
  28. data/doc/Ldbws/ResponseTypes/ServiceItem.html +132 -0
  29. data/doc/Ldbws/ResponseTypes/ServiceItemWithCallingPoints.html +106 -0
  30. data/doc/Ldbws/ResponseTypes/StationBoard.html +107 -0
  31. data/doc/Ldbws/ResponseTypes/StationBoardWithDetails.html +107 -0
  32. data/doc/Ldbws/ResponseTypes/ToiletAvailability.html +108 -0
  33. data/doc/Ldbws/ResponseTypes.html +91 -0
  34. data/doc/Ldbws/Service.html +538 -0
  35. data/doc/Ldbws.html +149 -0
  36. data/doc/README_md.html +159 -0
  37. data/doc/created.rid +19 -0
  38. data/doc/css/fonts.css +167 -0
  39. data/doc/css/rdoc.css +662 -0
  40. data/doc/fonts/Lato-Light.ttf +0 -0
  41. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  42. data/doc/fonts/Lato-Regular.ttf +0 -0
  43. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  44. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  45. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  46. data/doc/images/add.png +0 -0
  47. data/doc/images/arrow_up.png +0 -0
  48. data/doc/images/brick.png +0 -0
  49. data/doc/images/brick_link.png +0 -0
  50. data/doc/images/bug.png +0 -0
  51. data/doc/images/bullet_black.png +0 -0
  52. data/doc/images/bullet_toggle_minus.png +0 -0
  53. data/doc/images/bullet_toggle_plus.png +0 -0
  54. data/doc/images/date.png +0 -0
  55. data/doc/images/delete.png +0 -0
  56. data/doc/images/find.png +0 -0
  57. data/doc/images/loadingAnimation.gif +0 -0
  58. data/doc/images/macFFBgHack.png +0 -0
  59. data/doc/images/package.png +0 -0
  60. data/doc/images/page_green.png +0 -0
  61. data/doc/images/page_white_text.png +0 -0
  62. data/doc/images/page_white_width.png +0 -0
  63. data/doc/images/plugin.png +0 -0
  64. data/doc/images/ruby.png +0 -0
  65. data/doc/images/tag_blue.png +0 -0
  66. data/doc/images/tag_green.png +0 -0
  67. data/doc/images/transparent.png +0 -0
  68. data/doc/images/wrench.png +0 -0
  69. data/doc/images/wrench_orange.png +0 -0
  70. data/doc/images/zoom.png +0 -0
  71. data/doc/index.html +165 -0
  72. data/doc/js/darkfish.js +84 -0
  73. data/doc/js/navigation.js +105 -0
  74. data/doc/js/navigation.js.gz +0 -0
  75. data/doc/js/search.js +110 -0
  76. data/doc/js/search_index.js +1 -0
  77. data/doc/js/search_index.js.gz +0 -0
  78. data/doc/js/searcher.js +229 -0
  79. data/doc/js/searcher.js.gz +0 -0
  80. data/doc/table_of_contents.html +299 -0
  81. data/ldbws.gemspec +25 -0
  82. data/lib/ldbws/request/base.rb +69 -0
  83. data/lib/ldbws/request/get_departures_board.rb +54 -0
  84. data/lib/ldbws/request/get_service_details.rb +29 -0
  85. data/lib/ldbws/request/get_station_board.rb +60 -0
  86. data/lib/ldbws/response_types/base.rb +34 -0
  87. data/lib/ldbws/response_types/calling_point.rb +40 -0
  88. data/lib/ldbws/response_types/departures_board.rb +39 -0
  89. data/lib/ldbws/response_types/formation.rb +49 -0
  90. data/lib/ldbws/response_types/parsing_functions.rb +177 -0
  91. data/lib/ldbws/response_types/service_details.rb +69 -0
  92. data/lib/ldbws/response_types/service_item.rb +77 -0
  93. data/lib/ldbws/response_types/station_board.rb +50 -0
  94. data/lib/ldbws/service.rb +218 -0
  95. data/lib/ldbws/utils.rb +60 -0
  96. data/lib/ldbws/version.rb +4 -0
  97. data/lib/ldbws.rb +13 -0
  98. data/spec/response_types/parsing_spec.rb +46 -0
  99. data/spec/spec_helper.rb +4 -0
  100. metadata +224 -0
@@ -0,0 +1,229 @@
1
+ Searcher = function(data) {
2
+ this.data = data;
3
+ this.handlers = [];
4
+ }
5
+
6
+ Searcher.prototype = new function() {
7
+ // search is performed in chunks of 1000 for non-blocking user input
8
+ var CHUNK_SIZE = 1000;
9
+ // do not try to find more than 100 results
10
+ var MAX_RESULTS = 100;
11
+ var huid = 1;
12
+ var suid = 1;
13
+ var runs = 0;
14
+
15
+ this.find = function(query) {
16
+ var queries = splitQuery(query);
17
+ var regexps = buildRegexps(queries);
18
+ var highlighters = buildHilighters(queries);
19
+ var state = { from: 0, pass: 0, limit: MAX_RESULTS, n: suid++};
20
+ var _this = this;
21
+
22
+ this.currentSuid = state.n;
23
+
24
+ if (!query) return;
25
+
26
+ var run = function() {
27
+ // stop current search thread if new search started
28
+ if (state.n != _this.currentSuid) return;
29
+
30
+ var results =
31
+ performSearch(_this.data, regexps, queries, highlighters, state);
32
+ var hasMore = (state.limit > 0 && state.pass < 4);
33
+
34
+ triggerResults.call(_this, results, !hasMore);
35
+ if (hasMore) {
36
+ setTimeout(run, 2);
37
+ }
38
+ runs++;
39
+ };
40
+ runs = 0;
41
+
42
+ // start search thread
43
+ run();
44
+ }
45
+
46
+ /* ----- Events ------ */
47
+ this.ready = function(fn) {
48
+ fn.huid = huid;
49
+ this.handlers.push(fn);
50
+ }
51
+
52
+ /* ----- Utilities ------ */
53
+ function splitQuery(query) {
54
+ return query.split(/(\s+|::?|\(\)?)/).filter(function(string) {
55
+ return string.match(/\S/);
56
+ });
57
+ }
58
+
59
+ function buildRegexps(queries) {
60
+ return queries.map(function(query) {
61
+ return new RegExp(query.replace(/(.)/g, '([$1])([^$1]*?)'), 'i');
62
+ });
63
+ }
64
+
65
+ function buildHilighters(queries) {
66
+ return queries.map(function(query) {
67
+ return query.split('').map(function(l, i) {
68
+ return '\u0001$' + (i*2+1) + '\u0002$' + (i*2+2);
69
+ }).join('');
70
+ });
71
+ }
72
+
73
+ // function longMatchRegexp(index, longIndex, regexps) {
74
+ // for (var i = regexps.length - 1; i >= 0; i--){
75
+ // if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false;
76
+ // };
77
+ // return true;
78
+ // }
79
+
80
+
81
+ /* ----- Mathchers ------ */
82
+
83
+ /*
84
+ * This record matches if the index starts with queries[0] and the record
85
+ * matches all of the regexps
86
+ */
87
+ function matchPassBeginning(index, longIndex, queries, regexps) {
88
+ if (index.indexOf(queries[0]) != 0) return false;
89
+ for (var i=1, l = regexps.length; i < l; i++) {
90
+ if (!index.match(regexps[i]) && !longIndex.match(regexps[i]))
91
+ return false;
92
+ };
93
+ return true;
94
+ }
95
+
96
+ /*
97
+ * This record matches if the longIndex starts with queries[0] and the
98
+ * longIndex matches all of the regexps
99
+ */
100
+ function matchPassLongIndex(index, longIndex, queries, regexps) {
101
+ if (longIndex.indexOf(queries[0]) != 0) return false;
102
+ for (var i=1, l = regexps.length; i < l; i++) {
103
+ if (!longIndex.match(regexps[i]))
104
+ return false;
105
+ };
106
+ return true;
107
+ }
108
+
109
+ /*
110
+ * This record matches if the index contains queries[0] and the record
111
+ * matches all of the regexps
112
+ */
113
+ function matchPassContains(index, longIndex, queries, regexps) {
114
+ if (index.indexOf(queries[0]) == -1) return false;
115
+ for (var i=1, l = regexps.length; i < l; i++) {
116
+ if (!index.match(regexps[i]) && !longIndex.match(regexps[i]))
117
+ return false;
118
+ };
119
+ return true;
120
+ }
121
+
122
+ /*
123
+ * This record matches if regexps[0] matches the index and the record
124
+ * matches all of the regexps
125
+ */
126
+ function matchPassRegexp(index, longIndex, queries, regexps) {
127
+ if (!index.match(regexps[0])) return false;
128
+ for (var i=1, l = regexps.length; i < l; i++) {
129
+ if (!index.match(regexps[i]) && !longIndex.match(regexps[i]))
130
+ return false;
131
+ };
132
+ return true;
133
+ }
134
+
135
+
136
+ /* ----- Highlighters ------ */
137
+ function highlightRegexp(info, queries, regexps, highlighters) {
138
+ var result = createResult(info);
139
+ for (var i=0, l = regexps.length; i < l; i++) {
140
+ result.title = result.title.replace(regexps[i], highlighters[i]);
141
+ result.namespace = result.namespace.replace(regexps[i], highlighters[i]);
142
+ };
143
+ return result;
144
+ }
145
+
146
+ function hltSubstring(string, pos, length) {
147
+ return string.substring(0, pos) + '\u0001' + string.substring(pos, pos + length) + '\u0002' + string.substring(pos + length);
148
+ }
149
+
150
+ function highlightQuery(info, queries, regexps, highlighters) {
151
+ var result = createResult(info);
152
+ var pos = 0;
153
+ var lcTitle = result.title.toLowerCase();
154
+
155
+ pos = lcTitle.indexOf(queries[0]);
156
+ if (pos != -1) {
157
+ result.title = hltSubstring(result.title, pos, queries[0].length);
158
+ }
159
+
160
+ result.namespace = result.namespace.replace(regexps[0], highlighters[0]);
161
+ for (var i=1, l = regexps.length; i < l; i++) {
162
+ result.title = result.title.replace(regexps[i], highlighters[i]);
163
+ result.namespace = result.namespace.replace(regexps[i], highlighters[i]);
164
+ };
165
+ return result;
166
+ }
167
+
168
+ function createResult(info) {
169
+ var result = {};
170
+ result.title = info[0];
171
+ result.namespace = info[1];
172
+ result.path = info[2];
173
+ result.params = info[3];
174
+ result.snippet = info[4];
175
+ result.badge = info[6];
176
+ return result;
177
+ }
178
+
179
+ /* ----- Searching ------ */
180
+ function performSearch(data, regexps, queries, highlighters, state) {
181
+ var searchIndex = data.searchIndex;
182
+ var longSearchIndex = data.longSearchIndex;
183
+ var info = data.info;
184
+ var result = [];
185
+ var i = state.from;
186
+ var l = searchIndex.length;
187
+ var togo = CHUNK_SIZE;
188
+ var matchFunc, hltFunc;
189
+
190
+ while (state.pass < 4 && state.limit > 0 && togo > 0) {
191
+ if (state.pass == 0) {
192
+ matchFunc = matchPassBeginning;
193
+ hltFunc = highlightQuery;
194
+ } else if (state.pass == 1) {
195
+ matchFunc = matchPassLongIndex;
196
+ hltFunc = highlightQuery;
197
+ } else if (state.pass == 2) {
198
+ matchFunc = matchPassContains;
199
+ hltFunc = highlightQuery;
200
+ } else if (state.pass == 3) {
201
+ matchFunc = matchPassRegexp;
202
+ hltFunc = highlightRegexp;
203
+ }
204
+
205
+ for (; togo > 0 && i < l && state.limit > 0; i++, togo--) {
206
+ if (info[i].n == state.n) continue;
207
+ if (matchFunc(searchIndex[i], longSearchIndex[i], queries, regexps)) {
208
+ info[i].n = state.n;
209
+ result.push(hltFunc(info[i], queries, regexps, highlighters));
210
+ state.limit--;
211
+ }
212
+ };
213
+ if (searchIndex.length <= i) {
214
+ state.pass++;
215
+ i = state.from = 0;
216
+ } else {
217
+ state.from = i;
218
+ }
219
+ }
220
+ return result;
221
+ }
222
+
223
+ function triggerResults(results, isLast) {
224
+ this.handlers.forEach(function(fn) {
225
+ fn.call(this, results, isLast)
226
+ });
227
+ }
228
+ }
229
+
Binary file
@@ -0,0 +1,299 @@
1
+ <!DOCTYPE html>
2
+
3
+ <html>
4
+ <head>
5
+ <meta charset="UTF-8">
6
+
7
+ <title>Table of Contents - RDoc Documentation</title>
8
+
9
+ <script type="text/javascript">
10
+ var rdoc_rel_prefix = "./";
11
+ var index_rel_prefix = "./";
12
+ </script>
13
+
14
+ <script src="./js/navigation.js" defer></script>
15
+ <script src="./js/search.js" defer></script>
16
+ <script src="./js/search_index.js" defer></script>
17
+ <script src="./js/searcher.js" defer></script>
18
+ <script src="./js/darkfish.js" defer></script>
19
+
20
+ <link href="./css/fonts.css" rel="stylesheet">
21
+ <link href="./css/rdoc.css" rel="stylesheet">
22
+
23
+
24
+ <body id="top" class="table-of-contents">
25
+ <main role="main">
26
+ <h1 class="class">Table of Contents - RDoc Documentation</h1>
27
+
28
+ <h2 id="pages">Pages</h2>
29
+ <ul>
30
+ <li class="file">
31
+ <a href="LICENSE.html">LICENSE</a>
32
+ </li>
33
+ <li class="file">
34
+ <a href="README_md.html">README</a>
35
+
36
+ <ul>
37
+ <li><a href="README_md.html#label-ldbws-ruby">ldbws-ruby</a>
38
+ <li><a href="README_md.html#label-HOWTO">HOWTO</a>
39
+ <li><a href="README_md.html#label-A+note+about+rate+limiting">A note about rate limiting</a>
40
+ <li><a href="README_md.html#label-Caveats">Caveats</a>
41
+ </ul>
42
+ </li>
43
+ </ul>
44
+
45
+ <h2 id="classes">Classes and Modules</h2>
46
+ <ul>
47
+ <li class="module">
48
+ <a href="Ldbws.html">Ldbws</a>
49
+ </li>
50
+ <li class="module">
51
+ <a href="Ldbws/Request.html">Ldbws::Request</a>
52
+ </li>
53
+ <li class="class">
54
+ <a href="Ldbws/Request/GetDeparturesBoard.html">Ldbws::Request::GetDeparturesBoard</a>
55
+
56
+ <ul>
57
+ <li><a href="Ldbws/Request/GetDeparturesBoard.html#label-Parameters">Parameters</a>
58
+ </ul>
59
+ </li>
60
+ <li class="class">
61
+ <a href="Ldbws/Request/GetDeparturesBoardWithDetails.html">Ldbws::Request::GetDeparturesBoardWithDetails</a>
62
+
63
+ <ul>
64
+ <li><a href="Ldbws/Request/GetDeparturesBoardWithDetails.html#label-Parameters">Parameters</a>
65
+ </ul>
66
+ </li>
67
+ <li class="class">
68
+ <a href="Ldbws/Request/GetServiceDetails.html">Ldbws::Request::GetServiceDetails</a>
69
+
70
+ <ul>
71
+ <li><a href="Ldbws/Request/GetServiceDetails.html#label-Parameters">Parameters</a>
72
+ </ul>
73
+ </li>
74
+ <li class="class">
75
+ <a href="Ldbws/Request/GetStationBoard.html">Ldbws::Request::GetStationBoard</a>
76
+
77
+ <ul>
78
+ <li><a href="Ldbws/Request/GetStationBoard.html#label-Parameters">Parameters</a>
79
+ </ul>
80
+ </li>
81
+ <li class="class">
82
+ <a href="Ldbws/Request/GetStationBoardWithDetails.html">Ldbws::Request::GetStationBoardWithDetails</a>
83
+
84
+ <ul>
85
+ <li><a href="Ldbws/Request/GetStationBoardWithDetails.html#label-Parameters">Parameters</a>
86
+ </ul>
87
+ </li>
88
+ <li class="module">
89
+ <a href="Ldbws/ResponseTypes.html">Ldbws::ResponseTypes</a>
90
+ </li>
91
+ <li class="class">
92
+ <a href="Ldbws/ResponseTypes/BaseStationBoard.html">Ldbws::ResponseTypes::BaseStationBoard</a>
93
+
94
+ <ul>
95
+ <li><a href="Ldbws/ResponseTypes/BaseStationBoard.html#label-Properties">Properties</a>
96
+ </ul>
97
+ </li>
98
+ <li class="class">
99
+ <a href="Ldbws/ResponseTypes/CallingPoint.html">Ldbws::ResponseTypes::CallingPoint</a>
100
+
101
+ <ul>
102
+ <li><a href="Ldbws/ResponseTypes/CallingPoint.html#label-Properties">Properties</a>
103
+ </ul>
104
+ </li>
105
+ <li class="class">
106
+ <a href="Ldbws/ResponseTypes/Coach.html">Ldbws::ResponseTypes::Coach</a>
107
+
108
+ <ul>
109
+ <li><a href="Ldbws/ResponseTypes/Coach.html#label-Properties">Properties</a>
110
+ </ul>
111
+ </li>
112
+ <li class="class">
113
+ <a href="Ldbws/ResponseTypes/DepartureItem.html">Ldbws::ResponseTypes::DepartureItem</a>
114
+
115
+ <ul>
116
+ <li><a href="Ldbws/ResponseTypes/DepartureItem.html#label-Properties">Properties</a>
117
+ </ul>
118
+ </li>
119
+ <li class="class">
120
+ <a href="Ldbws/ResponseTypes/DepartureItemWithDetails.html">Ldbws::ResponseTypes::DepartureItemWithDetails</a>
121
+
122
+ <ul>
123
+ <li><a href="Ldbws/ResponseTypes/DepartureItemWithDetails.html#label-Properties">Properties</a>
124
+ </ul>
125
+ </li>
126
+ <li class="class">
127
+ <a href="Ldbws/ResponseTypes/DeparturesBoard.html">Ldbws::ResponseTypes::DeparturesBoard</a>
128
+
129
+ <ul>
130
+ <li><a href="Ldbws/ResponseTypes/DeparturesBoard.html#label-Properties">Properties</a>
131
+ </ul>
132
+ </li>
133
+ <li class="class">
134
+ <a href="Ldbws/ResponseTypes/DeparturesBoardWithDetails.html">Ldbws::ResponseTypes::DeparturesBoardWithDetails</a>
135
+
136
+ <ul>
137
+ <li><a href="Ldbws/ResponseTypes/DeparturesBoardWithDetails.html#label-Properties">Properties</a>
138
+ </ul>
139
+ </li>
140
+ <li class="class">
141
+ <a href="Ldbws/ResponseTypes/Formation.html">Ldbws::ResponseTypes::Formation</a>
142
+
143
+ <ul>
144
+ <li><a href="Ldbws/ResponseTypes/Formation.html#label-Properties">Properties</a>
145
+ </ul>
146
+ </li>
147
+ <li class="class">
148
+ <a href="Ldbws/ResponseTypes/LoadingCategory.html">Ldbws::ResponseTypes::LoadingCategory</a>
149
+
150
+ <ul>
151
+ <li><a href="Ldbws/ResponseTypes/LoadingCategory.html#label-Properties">Properties</a>
152
+ </ul>
153
+ </li>
154
+ <li class="class">
155
+ <a href="Ldbws/ResponseTypes/Location.html">Ldbws::ResponseTypes::Location</a>
156
+
157
+ <ul>
158
+ <li><a href="Ldbws/ResponseTypes/Location.html#label-Properties">Properties</a>
159
+ </ul>
160
+ </li>
161
+ <li class="class">
162
+ <a href="Ldbws/ResponseTypes/ServiceDetails.html">Ldbws::ResponseTypes::ServiceDetails</a>
163
+
164
+ <ul>
165
+ <li><a href="Ldbws/ResponseTypes/ServiceDetails.html#label-Properties">Properties</a>
166
+ </ul>
167
+ </li>
168
+ <li class="class">
169
+ <a href="Ldbws/ResponseTypes/ServiceItem.html">Ldbws::ResponseTypes::ServiceItem</a>
170
+
171
+ <ul>
172
+ <li><a href="Ldbws/ResponseTypes/ServiceItem.html#label-Properties">Properties</a>
173
+ </ul>
174
+ </li>
175
+ <li class="class">
176
+ <a href="Ldbws/ResponseTypes/ServiceItemWithCallingPoints.html">Ldbws::ResponseTypes::ServiceItemWithCallingPoints</a>
177
+
178
+ <ul>
179
+ <li><a href="Ldbws/ResponseTypes/ServiceItemWithCallingPoints.html#label-Properties">Properties</a>
180
+ </ul>
181
+ </li>
182
+ <li class="class">
183
+ <a href="Ldbws/ResponseTypes/StationBoard.html">Ldbws::ResponseTypes::StationBoard</a>
184
+
185
+ <ul>
186
+ <li><a href="Ldbws/ResponseTypes/StationBoard.html#label-Properties">Properties</a>
187
+ </ul>
188
+ </li>
189
+ <li class="class">
190
+ <a href="Ldbws/ResponseTypes/StationBoardWithDetails.html">Ldbws::ResponseTypes::StationBoardWithDetails</a>
191
+
192
+ <ul>
193
+ <li><a href="Ldbws/ResponseTypes/StationBoardWithDetails.html#label-Properties">Properties</a>
194
+ </ul>
195
+ </li>
196
+ <li class="class">
197
+ <a href="Ldbws/ResponseTypes/ToiletAvailability.html">Ldbws::ResponseTypes::ToiletAvailability</a>
198
+
199
+ <ul>
200
+ <li><a href="Ldbws/ResponseTypes/ToiletAvailability.html#label-Properties">Properties</a>
201
+ </ul>
202
+ </li>
203
+ <li class="class">
204
+ <a href="Ldbws/Service.html">Ldbws::Service</a>
205
+
206
+ <ul>
207
+ <li><a href="Ldbws/Service.html#label-Usage+example">Usage example</a>
208
+ <li><a href="Ldbws/Service.html#label-Side+note">Side note</a>
209
+ </ul>
210
+ </li>
211
+ </ul>
212
+
213
+ <h2 id="methods">Methods</h2>
214
+ <ul>
215
+
216
+ <li class="method">
217
+ <a href="Ldbws/Service.html#method-c-new">::new</a>
218
+ &mdash;
219
+ <span class="container">Ldbws::Service</span>
220
+
221
+ <li class="method">
222
+ <a href="Ldbws.html#method-c-service">::service</a>
223
+ &mdash;
224
+ <span class="container">Ldbws</span>
225
+
226
+ <li class="method">
227
+ <a href="Ldbws/Service.html#method-i-get_arr_board_with_details">#get_arr_board_with_details</a>
228
+ &mdash;
229
+ <span class="container">Ldbws::Service</span>
230
+
231
+ <li class="method">
232
+ <a href="Ldbws/Service.html#method-i-get_arr_dep_board_with_details">#get_arr_dep_board_with_details</a>
233
+ &mdash;
234
+ <span class="container">Ldbws::Service</span>
235
+
236
+ <li class="method">
237
+ <a href="Ldbws/Service.html#method-i-get_arrival_board">#get_arrival_board</a>
238
+ &mdash;
239
+ <span class="container">Ldbws::Service</span>
240
+
241
+ <li class="method">
242
+ <a href="Ldbws/Service.html#method-i-get_arrival_board_with_details">#get_arrival_board_with_details</a>
243
+ &mdash;
244
+ <span class="container">Ldbws::Service</span>
245
+
246
+ <li class="method">
247
+ <a href="Ldbws/Service.html#method-i-get_arrival_departure_board">#get_arrival_departure_board</a>
248
+ &mdash;
249
+ <span class="container">Ldbws::Service</span>
250
+
251
+ <li class="method">
252
+ <a href="Ldbws/Service.html#method-i-get_arrival_departure_board_with_details">#get_arrival_departure_board_with_details</a>
253
+ &mdash;
254
+ <span class="container">Ldbws::Service</span>
255
+
256
+ <li class="method">
257
+ <a href="Ldbws/Service.html#method-i-get_dep_board_with_details">#get_dep_board_with_details</a>
258
+ &mdash;
259
+ <span class="container">Ldbws::Service</span>
260
+
261
+ <li class="method">
262
+ <a href="Ldbws/Service.html#method-i-get_departure_board">#get_departure_board</a>
263
+ &mdash;
264
+ <span class="container">Ldbws::Service</span>
265
+
266
+ <li class="method">
267
+ <a href="Ldbws/Service.html#method-i-get_departure_board_with_details">#get_departure_board_with_details</a>
268
+ &mdash;
269
+ <span class="container">Ldbws::Service</span>
270
+
271
+ <li class="method">
272
+ <a href="Ldbws/Service.html#method-i-get_fastest_departures_with_details">#get_fastest_departures_with_details</a>
273
+ &mdash;
274
+ <span class="container">Ldbws::Service</span>
275
+
276
+ <li class="method">
277
+ <a href="Ldbws/Service.html#method-i-get_next_departures">#get_next_departures</a>
278
+ &mdash;
279
+ <span class="container">Ldbws::Service</span>
280
+
281
+ <li class="method">
282
+ <a href="Ldbws/Service.html#method-i-get_next_departures_with_details">#get_next_departures_with_details</a>
283
+ &mdash;
284
+ <span class="container">Ldbws::Service</span>
285
+
286
+ <li class="method">
287
+ <a href="Ldbws/Service.html#method-i-get_service_details">#get_service_details</a>
288
+ &mdash;
289
+ <span class="container">Ldbws::Service</span>
290
+ </ul>
291
+ </main>
292
+
293
+
294
+ <footer id="validator-badges" role="contentinfo">
295
+ <p><a href="https://validator.w3.org/check/referer">Validate</a>
296
+ <p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.5.0.
297
+ <p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
298
+ </footer>
299
+
data/ldbws.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require "ldbws/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ldbws"
8
+ spec.summary = "Interface to the Network Rail OpenLDBS web service"
9
+ spec.license = "MIT"
10
+
11
+ spec.authors = "Jon Pearse"
12
+ spec.email = "hello@jonpearse.net"
13
+ spec.homepage = "https://github.com/jonpearse/ldbws-ruby"
14
+
15
+ spec.version = Ldbws::VERSION
16
+ spec.files = `git ls-files`.split($\)
17
+
18
+ spec.add_dependency "dry-schema", "~> 1.13"
19
+ spec.add_dependency "faraday", "~> 2.7"
20
+ spec.add_dependency "nokogiri", "~> 1.14"
21
+
22
+ spec.add_development_dependency "rdoc", "~> 6.5.0"
23
+ spec.add_development_dependency "rspec", "~> 3.11"
24
+ spec.add_development_dependency "rufo", "~> 0.13.0"
25
+ end
@@ -0,0 +1,69 @@
1
+ require "dry-schema"
2
+ require "nokogiri"
3
+
4
+ require "ldbws/utils"
5
+
6
+ # This module defines specific request types that map 1:1 with corresponding types in the LDBWS service schema. Sadly
7
+ # these are not especially well-documented.
8
+ module Ldbws::Request # :nodoc:
9
+ # Common schema types for use when validating.
10
+ module Types # :nodoc:
11
+ include Dry.Types()
12
+
13
+ # A CRS code (eg ‘WAT’ for London Waterloo). These are not exhaustively validated.
14
+ Crs = String.constrained(size: 3)
15
+
16
+ # A specific type used when filtering by CRS.
17
+ FilterType = String.enum("to", "from")
18
+ end
19
+
20
+ # \Base request type used whem querying LDBWS: provides basic functionality that can be overridden on a per-subclass
21
+ # basis.
22
+ class Base # :nodoc:
23
+ # Creates a Request object given the specified arguments. This performs validation accordng to the request’s schema,
24
+ # and throws ParamValidationError on failure.
25
+ #
26
+ # === Parameters
27
+ #
28
+ # args:: a {Hash} cotaining the request’s parameters
29
+ def initialize(args)
30
+ params = self.class::SCHEMA.(args)
31
+ raise ParamValidationError.new(params.errors) if params.errors.any?
32
+
33
+ @params = params.to_h
34
+ end
35
+
36
+ # Builds a SOAP request corresponding to the current request.
37
+ #
38
+ # === Parameters
39
+ # xml:: the {Nokogiri Builder}[rdoc-ref:Nokogiri::XML::Builder] object to append XML to.
40
+ def to_soap(xml)
41
+ Ldbws::Utils.deep_to_soap(xml, to_soap_params)
42
+ end
43
+
44
+ # Parses the returned SOAP response and converts it into the corresponding {response type}[rdoc-ref:ResponseTypes],
45
+ # defined in `RESULT_TYPE`.
46
+ #
47
+ # === Parameters
48
+ # xml:: the {XML node}[rdoc-ref:Nokogiri::XML::Node] that should contain the response to this request.
49
+ def from_soap(xml)
50
+ result_node = xml.xpath(self.class::RESULT_XPATH).first
51
+ raise "Oh no" unless result_node
52
+
53
+ self.class::RESULT_TYPE.from_xml(result_node)
54
+ end
55
+
56
+ protected
57
+
58
+ # Converts the inbound request parameters into something that can be serialised to SOAP, allow per-subclass to
59
+ # provide specific functionality.
60
+ #
61
+ # :yield: a [Hash] of parameters for serialisation to SOAP.
62
+ def to_soap_params
63
+ @params
64
+ end
65
+ end
66
+
67
+ # Represents an error that occurs when request parameters cannot be validated.
68
+ class ParamValidationError < RuntimeError; end # :nodoc:
69
+ end
@@ -0,0 +1,54 @@
1
+ require "ldbws/request/base"
2
+
3
+ require "ldbws/response_types/departures_board"
4
+
5
+ module Ldbws::Request
6
+ # Requests a departure board for a station, filtered by departures to one or many other stations. Corresponds to
7
+ # +GetDeparturesBoardRequest+ in the LDBWS schema.
8
+ #
9
+ # === Parameters
10
+ # crs:: the CRS code of the station you wish to get departures for (required).
11
+ # filter_list:: a list of CRS codes to filter departures (required).
12
+ # time_offset:: the offset from the current time—in minutes—to return departure information (optional).
13
+ # time_window:: how far into the future—relative to +:time_offset+—to return service information for (optional).
14
+ class GetDeparturesBoard < Base
15
+ # :nodoc:
16
+ SCHEMA = Dry::Schema.Params do
17
+ required(:crs).filled(Types::Crs)
18
+ required(:filter_list).array(Types::Crs, min_size?: 1)
19
+ optional(:time_offset).filled(:integer)
20
+ optional(:time_window).filled(:integer)
21
+ end
22
+
23
+ # :nodoc:
24
+ RESULT_XPATH = "DeparturesBoard"
25
+
26
+ # :nodoc:
27
+ RESULT_TYPE = Ldbws::ResponseTypes::DeparturesBoard
28
+
29
+ # :nodoc:
30
+ def to_soap_params
31
+ @params.tap do |params|
32
+ params[:crs].upcase!
33
+ params[:filter_list].map! do |value|
34
+ { crs: value.upcase }
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ # Requests a departure board for a statuion, filtered by departures to one or more other stations. This returns more
41
+ # information than GetDepartureBoard.
42
+ #
43
+ # This corresponds to +GetDeparturesBoardWithDetailsRequest+ in the LDBWS schema.
44
+ #
45
+ # === Parameters
46
+ # crs:: the CRS code of the station you wish to get departures for (required).
47
+ # filter_list:: a list of CRS codes to filter departures (required).
48
+ # time_offset:: the offset from the current time—in minutes—to return departure information (optional).
49
+ # time_window:: how far into the future—relative to +:time_offset+—to return service information for (optional).
50
+ class GetDeparturesBoardWithDetails < GetDeparturesBoard
51
+ # :nodoc:
52
+ RESULT_TYPE = Ldbws::ResponseTypes::DeparturesBoardWithDetails
53
+ end
54
+ end