@@ -22,14 +22,18 @@ You should have received a copy of the GNU Affero General Public License
2222using System . Collections . Generic ;
2323using System . Globalization ;
2424using System . Linq ;
25- using System . ServiceModel ;
2625using System . Threading . Tasks ;
2726using System . Web . Http ;
2827using Huxley . Models ;
2928using Huxley . ldbServiceReference ;
3029
3130namespace Huxley . Controllers {
32- public class DelaysController : BaseController {
31+ public class DelaysController : LdbController {
32+
33+ public DelaysController ( ILdbClient client )
34+ : base ( client ) {
35+ }
36+
3337 // GET /delays/{crs}/{filtertype}/{filtercrs}/{numrows}/{stds}?accessToken=[your token]
3438 public async Task < DelaysResponse > Get ( [ FromUri ] StationBoardRequest request ) {
3539
@@ -61,121 +65,81 @@ public async Task<DelaysResponse> Get([FromUri] StationBoardRequest request) {
6165 }
6266 }
6367
64- // https://en.wikipedia.org/wiki/London_station_group
65- // Farringdon [ZFD] is not a London Terminal but it probably should be (maybe when Crossrail opens it will be)
66- var londonTerminals = new List < string > {
67- "BFR" , // Blackfriars
68- "CST" , // Cannon Street
69- "CHX" , // Charing Cross
70- "CTX" , // City Thameslink
71- "EUS" , // Euston
72- "FST" , // Fenchurch Street
73- "KGX" , // King's Cross
74- "LST" , // Liverpool Street
75- "LBG" , // London Bridge
76- "MYB" , // Marylebone
77- "MOG" , // Moorgate
78- "OLD" , // Old Street
79- "PAD" , // Paddington
80- "STP" , // St. Pancras
81- "VXH" , // Vauxhall
82- "VIC" , // Victoria
83- "WAT" , // Waterloo
84- "WAE" , // Waterloo East
85- } ;
86-
87- var client = new LDBServiceSoapClient ( ) ;
68+ var totalDelayMinutes = 0 ;
69+ var delayedTrains = new List < ServiceItem > ( ) ;
8870
89- // Avoiding Problems with the Using Statement in WCF clients
90- // https://msdn.microsoft.com/en-us/library/aa355056.aspx
91- try {
92- var totalDelayMinutes = 0 ;
93- var delayedTrains = new List < ServiceItem > ( ) ;
71+ var token = MakeAccessToken ( request . AccessToken ) ;
9472
95- var token = MakeAccessToken ( request . AccessToken ) ;
73+ var filterCrs = request . FilterCrs ;
74+ if ( request . FilterCrs . Equals ( "LON" , StringComparison . InvariantCultureIgnoreCase ) ||
75+ request . FilterCrs . Equals ( "London" , StringComparison . InvariantCultureIgnoreCase ) ) {
76+ filterCrs = null ;
77+ }
9678
97- var filterCrs = request . FilterCrs ;
98- if ( request . FilterCrs . Equals ( "LON" , StringComparison . InvariantCultureIgnoreCase ) ||
99- request . FilterCrs . Equals ( "London" , StringComparison . InvariantCultureIgnoreCase ) ) {
100- filterCrs = null ;
101- }
102-
103- var board = await client . GetDepartureBoardAsync ( token , request . NumRows , request . Crs , filterCrs , request . FilterType , 0 , 0 ) ;
104-
105- var response = board . GetStationBoardResult ;
106- var filterLocationName = response . filterLocationName ;
107-
108- var trainServices = response . trainServices ?? new ServiceItem [ 0 ] ;
109- var railReplacement = null != response . busServices && ! trainServices . Any ( ) && response . busServices . Any ( ) ;
110- var messagesPresent = null != response . nrccMessages && response . nrccMessages . Any ( ) ;
111-
112- if ( null == filterCrs ) {
113- // This only finds trains terminating at London terminals. BFR/STP etc. won't be picked up if called at en-route.
114- // Could query for every terminal or get service for every train and check calling points. Very chatty either way.
115- switch ( request . FilterType ) {
116- case FilterType . to :
117- trainServices = trainServices . Where ( ts => ts . destination . Any ( d => londonTerminals . Contains ( d . crs . ToUpperInvariant ( ) ) ) ) . ToArray ( ) ;
118- break ;
119- case FilterType . from :
120- trainServices = trainServices . Where ( ts => ts . origin . Any ( d => londonTerminals . Contains ( d . crs . ToUpperInvariant ( ) ) ) ) . ToArray ( ) ;
121- break ;
122- default :
123- throw new ArgumentOutOfRangeException ( ) ;
124- }
125- filterCrs = "LON" ;
126- filterLocationName = "London" ;
79+ var board = await Client . GetDepartureBoardAsync ( token , request . NumRows , request . Crs , filterCrs , request . FilterType , 0 , 0 ) ;
80+
81+ var response = board . GetStationBoardResult ;
82+ var filterLocationName = response . filterLocationName ;
83+
84+ var trainServices = response . trainServices ?? new ServiceItem [ 0 ] ;
85+ var railReplacement = null != response . busServices && ! trainServices . Any ( ) && response . busServices . Any ( ) ;
86+ var messagesPresent = null != response . nrccMessages && response . nrccMessages . Any ( ) ;
87+
88+ if ( null == filterCrs ) {
89+ // This only finds trains terminating at London terminals. BFR/STP etc. won't be picked up if called at en-route.
90+ // Could query for every terminal or get service for every train and check calling points. Very chatty either way.
91+ switch ( request . FilterType ) {
92+ case FilterType . to :
93+ trainServices = trainServices . Where ( ts => ts . destination . Any ( d => HuxleyApi . LondonTerminals . Any ( lt => lt . CrsCode == d . crs . ToUpperInvariant ( ) ) ) ) . ToArray ( ) ;
94+ break ;
95+ case FilterType . from :
96+ trainServices = trainServices . Where ( ts => ts . origin . Any ( o => HuxleyApi . LondonTerminals . Any ( lt => lt . CrsCode == o . crs . ToUpperInvariant ( ) ) ) ) . ToArray ( ) ;
97+ break ;
98+ default :
99+ throw new ArgumentOutOfRangeException ( ) ;
127100 }
101+ filterCrs = "LON" ;
102+ filterLocationName = "London" ;
103+ }
128104
129- // If STDs are provided then select only the train(s) matching them
130- if ( stds . Count > 0 ) {
131- trainServices = trainServices . Where ( ts => stds . Contains ( ts . std . Replace ( ":" , "" ) ) ) . ToArray ( ) ;
132- }
105+ // If STDs are provided then select only the train(s) matching them
106+ if ( stds . Count > 0 ) {
107+ trainServices = trainServices . Where ( ts => stds . Contains ( ts . std . Replace ( ":" , "" ) ) ) . ToArray ( ) ;
108+ }
133109
134- // Parse the response from the web service.
135- foreach ( var si in trainServices . Where ( si => ! si . etd . Equals ( "On time" , StringComparison . InvariantCultureIgnoreCase ) ) ) {
136- if ( si . etd . Equals ( "Delayed" , StringComparison . InvariantCultureIgnoreCase ) ||
137- si . etd . Equals ( "Cancelled" , StringComparison . InvariantCultureIgnoreCase ) ) {
138- delayedTrains . Add ( si ) ;
139- } else {
140- DateTime etd ;
141- // Could be "Starts Here", "No Report" or contain a * (report overdue)
142- if ( DateTime . TryParse ( si . etd . Replace ( "*" , "" ) , out etd ) ) {
143- DateTime std ;
144- if ( DateTime . TryParse ( si . std , out std ) ) {
145- var late = etd . Subtract ( std ) ;
146- totalDelayMinutes += ( int ) late . TotalMinutes ;
147- if ( late . TotalMinutes > HuxleyApi . Settings . DelayMinutesThreshold ) {
148- delayedTrains . Add ( si ) ;
149- }
110+ // Parse the response from the web service.
111+ foreach ( var si in trainServices . Where ( si => ! si . etd . Equals ( "On time" , StringComparison . InvariantCultureIgnoreCase ) ) ) {
112+ if ( si . etd . Equals ( "Delayed" , StringComparison . InvariantCultureIgnoreCase ) ||
113+ si . etd . Equals ( "Cancelled" , StringComparison . InvariantCultureIgnoreCase ) ) {
114+ delayedTrains . Add ( si ) ;
115+ } else {
116+ DateTime etd ;
117+ // Could be "Starts Here", "No Report" or contain a * (report overdue)
118+ if ( DateTime . TryParse ( si . etd . Replace ( "*" , "" ) , out etd ) ) {
119+ DateTime std ;
120+ if ( DateTime . TryParse ( si . std , out std ) ) {
121+ var late = etd . Subtract ( std ) ;
122+ totalDelayMinutes += ( int ) late . TotalMinutes ;
123+ if ( late . TotalMinutes > HuxleyApi . Settings . DelayMinutesThreshold ) {
124+ delayedTrains . Add ( si ) ;
150125 }
151126 }
152127 }
153128 }
154-
155- return new DelaysResponse {
156- GeneratedAt = response . generatedAt ,
157- Crs = response . crs ,
158- LocationName = response . locationName ,
159- Filtercrs = filterCrs ,
160- FilterLocationName = filterLocationName ,
161- Delays = delayedTrains . Count > 0 || railReplacement || messagesPresent ,
162- TotalTrainsDelayed = delayedTrains . Count ,
163- TotalDelayMinutes = totalDelayMinutes ,
164- TotalTrains = trainServices . Length ,
165- DelayedTrains = delayedTrains ,
166- } ;
167-
168- } catch ( CommunicationException ) {
169- client . Abort ( ) ;
170- } catch ( TimeoutException ) {
171- client . Abort ( ) ;
172- } catch ( Exception ) {
173- client . Abort ( ) ;
174- throw ;
175- } finally {
176- client . Close ( ) ;
177129 }
178- return new DelaysResponse ( ) ;
130+
131+ return new DelaysResponse {
132+ GeneratedAt = response . generatedAt ,
133+ Crs = response . crs ,
134+ LocationName = response . locationName ,
135+ Filtercrs = filterCrs ,
136+ FilterLocationName = filterLocationName ,
137+ Delays = delayedTrains . Count > 0 || railReplacement || messagesPresent ,
138+ TotalTrainsDelayed = delayedTrains . Count ,
139+ TotalDelayMinutes = totalDelayMinutes ,
140+ TotalTrains = trainServices . Length ,
141+ DelayedTrains = delayedTrains ,
142+ } ;
179143 }
180144 }
181145}
0 commit comments