Skip to content

Commit

Permalink
Added tube api calls
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-fletcher committed Oct 24, 2023
1 parent d671fa1 commit 2458d8a
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 87 deletions.
57 changes: 2 additions & 55 deletions BusDataAPI/DataSource/TflApi.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DepartureBoardCore;
using DepartureBoardCore.DataSource;
using Newtonsoft.Json;
using RestSharp;

namespace BusDataAPI.DataSource
{
public class TflApi : IBusDatasource
public class TflApi : TflBase, IBusDatasource
{
private readonly RestClient _client = new RestClient("https://api.tfl.gov.uk");
private static string AppKey => ConfigService.TflApiToken;

public List<BusDeparture> GetLiveDepartures(string code)
{
return GetDepartures(code);
Expand Down Expand Up @@ -41,54 +37,5 @@ private List<BusDeparture> GetDepartures(string code)
.OrderBy(a => a.AimedDeparture)
.ToList();
}

private int? GetConvertedTimeToStation(int? timeInSeconds)
{
if (!timeInSeconds.HasValue)
return null;

return Convert.ToInt32(Math.Ceiling(timeInSeconds.Value / 60m));
}

public List<StopPoint> GetAllStations()
{
var request = new RestRequest($"StopPoint/mode/tube", Method.Get);
RestResponse response = SendRequest(request);

var stations = JsonConvert.DeserializeObject<TflStopPointResponse>(response.Content);

return stations.StopPoints
.ToList();
}

private RestResponse SendRequest(RestRequest request)
{
request.AddQueryParameter("app_key", AppKey);
return _client.Execute(request);
}

public class TflStopPointResponse
{
public List<StopPoint> StopPoints { get; set; }
}

public class StopPoint
{
public string NaptanId { get; set; }
public string StationNaptan { get; set; }
public string CommonName { get; set; }
public string PlatformName { get; set; }
public List<dynamic> Lines { get; set; }
}

public class TflArrival
{
public string StationName { get; set; }
public string LineName { get; set; }
public string DestinationName { get; set; }
public DateTime ExpectedArrival { get; set; }
public string PlatformName { get; set; }
public int? TimeToStation { get; set; }
}
}
}
51 changes: 51 additions & 0 deletions DepartureBoardCore/DataSource/TflBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using RestSharp;

namespace DepartureBoardCore.DataSource;

public class TflBase
{
protected readonly RestClient _client = new RestClient("https://api.tfl.gov.uk");
protected static string AppKey => ConfigService.TflApiToken;
protected JsonSerializerOptions SerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
protected RestResponse SendRequest(RestRequest request)
{
request.AddQueryParameter("app_key", AppKey);
return _client.Execute(request);
}

protected int? GetConvertedTimeToStation(int? timeInSeconds)
{
if (!timeInSeconds.HasValue)
return null;

return Convert.ToInt32(Math.Ceiling(timeInSeconds.Value / 60m));
}

public class TflStopPointResponse
{
public List<StopPoint> StopPoints { get; set; }
}

public class StopPoint
{
public string NaptanId { get; set; }
public string StationNaptan { get; set; }
public string CommonName { get; set; }
public string PlatformName { get; set; }
public List<string> Modes { get; set; }
public List<dynamic> Lines { get; set; }
}

public class TflArrival
{
public string StationName { get; set; }
public string LineName { get; set; }
public string DestinationName { get; set; }
public DateTime ExpectedArrival { get; set; }
public string PlatformName { get; set; }
public int? TimeToStation { get; set; }
}
}
4 changes: 4 additions & 0 deletions DepartureBoardCore/DepartureBoardCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="RestSharp" Version="110.2.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1 class="led centre-text" *ngIf="departures?.length === 0">
<h1 class="led centre-text" *ngIf="departures?.length === 0 || noBoardsDisplay">
No Departures Found for {{stopName}}
</h1>
<div class="singleboard">
Expand All @@ -7,30 +7,30 @@ <h1 id="title" class="led centre-text" *ngIf="showStopName">
</h1>

<div class="row" *ngIf="firstDeparture">
<span class="led col-lg-1 col-1">1</span>
<span class="led col-auto">1</span>
<span class="led col">
{{ firstDeparture.destination }}
</span>
<span class="led col-lg-2 col-md-3 col-4 status">
{{firstDeparture.timeToStation}} mins
<span class="led col-auto">
{{firstDeparture.status}}
</span>
</div>

<!-- <div class="row">-->
<!-- <div-->
<!-- id="singleboard-information"-->
<!-- class="led info col-12"-->
<!-- style="height: 48px"-->
<!-- ></div>-->
<!-- </div>-->
<!-- <div class="row">-->
<!-- <div-->
<!-- id="singleboard-information"-->
<!-- class="led info col-12"-->
<!-- style="height: 48px"-->
<!-- ></div>-->
<!-- </div>-->

<div class="row" *ngFor="let departure of otherDepartures; index as i">
<span class="led col-lg-1 col-1">{{i + 2}}</span>
<span class="led col-auto">{{i + 2}}</span>
<span class="led col">
{{ departure.destination }}
</span>
<span class="led col-lg-2 col-md-3 col-4 status">
{{departure.timeToStation}} mins
<span class="led col-auto">
{{departure.status}}
</span>
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Marquee} from "dynamic-marquee";
import {LondonTubeService} from "../../../Services/london-tube.service";
import {ActivatedRoute} from "@angular/router";

@Component({
selector: 'app-london-tube-singleboard',
Expand All @@ -10,24 +11,43 @@ import {LondonTubeService} from "../../../Services/london-tube.service";
export class LondonTubeSingleboardComponent implements OnInit, OnDestroy {
showStopName: boolean = true;
showClock: boolean = true;
stopName: string = "Baker Street";
stopName: string = "";
scrollSpeed = 200;
departures;

departures?: any[];
stationCode: string;

noBoardsDisplay: boolean;
departureCount: number = 4;
time = new Date();
timeInterval: NodeJS.Timer;
fetchInterval: NodeJS.Timer;
marquee: Marquee;

constructor(private tubeService: LondonTubeService) {
constructor(private tubeService: LondonTubeService, private route: ActivatedRoute) {
}

ngOnInit(): void {
this.timeInterval = setInterval(() => {
this.time = new Date();
}, 1000);

this.route.paramMap.subscribe(params => {
this.stationCode = params.get('station');
if (!this.stationCode) {
this.noBoardsDisplay = true;
return;
}

if (params.has('count')) {
this.departureCount = parseInt(params.get('count'));
}

this.setStationInfo();
this.getDepartures();
this.fetchInterval = setInterval(() => this.getDepartures(), 35000);
});

// this.marquee = new Marquee(
// document.getElementById("singleboard-information"),
// {
Expand All @@ -44,8 +64,6 @@ export class LondonTubeSingleboardComponent implements OnInit, OnDestroy {
//
// this.marquee.appendItem("Calling at Bob");
//
this.getDepartures();
this.fetchInterval = setInterval(() => this.getDepartures(), 35000);
}

ngOnDestroy(): void {
Expand All @@ -54,14 +72,38 @@ export class LondonTubeSingleboardComponent implements OnInit, OnDestroy {
}

getDepartures() {
this.tubeService.getDepartures("940GZZLUBST").subscribe({
this.tubeService.getDepartures(this.stationCode, this.departureCount).subscribe({
next: (dep) => {
console.log(dep);
this.departures = (dep as any[])
this.departures = (dep as any[]).map(d => ({
...d,
status: this.getDepartureStatus(d),
}))
}
})
}

getDepartureStatus(d: any) {
const timeTillArrive = parseInt(d.timeToStation ?? 0);
let text = `${timeTillArrive} min`;

if (timeTillArrive >= 2) {
text += "s";
}
else {
text += " ";
}

return text;
}

setStationInfo() {
this.tubeService.getStationInfo(this.stationCode).subscribe({
next: (info) => {
this.stopName = info.name;
}
});
}

get firstDeparture() {
if (!this.departures || this.departures.length === 0) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LondonTubeSingleboardComponent } from './london-tube-singleboard/london

const routes: Routes = [
{ path: ":station", component: LondonTubeSingleboardComponent },
{ path: ":station/:count", component: LondonTubeSingleboardComponent },
];

@NgModule({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,14 @@ export class LondonTubeService {
params: params,
});
}

getStationInfo(stopCode: string): Observable<StationInfo> {
return this.http.get<StationInfo>(environment.apiBaseUrl + `/api/TubeDepartures/station/${stopCode}`);
}

}

export interface StationInfo {
name: string;
code: string;
}
Loading

0 comments on commit 2458d8a

Please sign in to comment.