Skip to content

Commit

Permalink
v0.4.16: Added SeaWorld wait times and sesame places
Browse files Browse the repository at this point in the history
  • Loading branch information
timyboy12345 committed Jun 13, 2024
1 parent c18f27d commit c10fd73
Show file tree
Hide file tree
Showing 16 changed files with 321 additions and 12 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ In the table below you will find the parks that are currently supported and the
| 🇺🇸 Seaworld Orlando | 🎡 | True | True | True | True | False |
| 🇺🇸 Bush Gardens Tampa Bay | 🎡 | True | True | True | True | False |
| 🇺🇸 Bush Gardens Williamsburg | 🎡 | True | True | True | True | False |
| 🇺🇸 Sesame Place Philadelphia | 🎡 | True | True | True | True | False |
| 🇺🇸 Sesame Place San Diego | 🎡 | True | True | True | True | False |
| 🇺🇸 Universal Studios Orlando | 🎡 | True | True | True | True | False |
| 🇺🇸 Islands of Adventure | 🎡 | True | True | True | True | False |
| 🇺🇸 Universal Studios Hollywood | 🎡 | True | True | True | True | False |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "themeparks-node-api",
"version": "0.4.15",
"version": "0.4.16",
"description": "An API which can retrieve theme park wait times.",
"author": "Tim Arendsen",
"private": false,
Expand Down
3 changes: 2 additions & 1 deletion src/controllers/parks/parks.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CACHE_MANAGER, CacheInterceptor, Controller, Get, Inject, UseInterceptors } from '@nestjs/common';
import { CACHE_MANAGER, CacheInterceptor, Controller, Get, Header, Inject, UseInterceptors } from '@nestjs/common';
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { ParkDto } from '../../_dtos/park.dto';
import { ParksService } from '../../_services/parks/parks.service';
Expand All @@ -23,6 +23,7 @@ export class ParksController {
}

@Get('/readme')
@Header('content-type', 'text/plain')
@UseInterceptors(CacheInterceptor)
async getParksReadme() {
const parks = (await this.parksService.getParks()).map(park => park.getFullInfo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Poi } from '../../../../_interfaces/poi.interface';
import { PlopsalandDePanneDetailsResponseItemInterface } from '../interfaces/plopsaland-de-panne-details-response.interface';
import { PoiCategory } from '../../../../_interfaces/poi-categories.enum';
import { ShowTime } from '../../../../_interfaces/showtimes.interface';
import * as moment from 'moment';
import * as moment from 'moment-timezone';

@Injectable()
export class PlopsalandDePanneTransferService extends TransferService {
Expand Down
13 changes: 9 additions & 4 deletions src/parks/seaworld/interfaces/seaworld-base-item.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,14 @@ export interface SeaworldBaseItem {
'MobileOrderingStoreId': null,
'OnlineOrderingEnabled': boolean,
'OnlineOrderingUrl': string | null,
'StaticMenuUrl': string | null | "",
'RideType': "Coaster" | null,
'ShowType': null | "Show Type 1" | "",
'ShowTimes': [],
'StaticMenuUrl': string | null | '',
'RideType': 'Coaster' | null,
'ShowType': null | 'Show Type 1' | '',
'ShowTimes': {
'StartDateTime': string,
'EndDateTime': string,
'StartTime': string,
'EndTime': string
}[],
'SlideType': null
}
16 changes: 16 additions & 0 deletions src/parks/seaworld/interfaces/seaworld-wait-times.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export interface SeaworldWaitTimesInterface {
'WaitTimes': [],
'ShowTimes': {
'Id': string,
'ShowTimes': {
// 'StartDateTime': '2024-06-12T19:00:00Z',
// 'EndDateTime': '2024-06-12T19:30:00Z',
// 'StartTime': '2024-06-12T12:00:00',
// 'EndTime': '2024-06-12T12:30:00'
'StartDateTime': string,
'EndDateTime': string,
'StartTime': string,
'EndTime': string
}[]
}[]
}
23 changes: 20 additions & 3 deletions src/parks/seaworld/seaworld-base/seaworld-base.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ConfigService } from '@nestjs/config';
import { Poi } from '../../../_interfaces/poi.interface';
import { HttpService } from '@nestjs/axios';
import { SeaworldTransferService } from '../seaworld-transfer/seaworld-transfer.service';
import * as moment from 'moment';
import { SeaworldWaitTimesInterface } from '../interfaces/seaworld-wait-times.interface';

@Injectable()
export class SeaworldBaseService extends ThroughPoisThemeParkService {
Expand Down Expand Up @@ -33,17 +35,32 @@ export class SeaworldBaseService extends ThroughPoisThemeParkService {
supportsShops: true,
supportsShowTimes: false,
supportsShows: true,
supportsTranslations: false
}
supportsTranslations: false,
};
}

getParkId(): string {
throw new NotImplementedException('Seaworld Park ID not set');
}

async getPois(): Promise<Poi[]> {
return this.http.get(`${this._apiUrl}/park/${this.getParkId()}/poi`)
const rides = await this.http.get(`${this._apiUrl}/park/${this.getParkId()}/poi`)
.toPromise()
.then((res) => this.transfer.transferPoisToPois(res.data));

// TODO: Actually implement seaworld wait time
const waitTimes = this.getWaitTimes();
return rides.map((r) => {
r.currentWaitTime = 0;
return r;
})
}

async getWaitTimes(): Promise<SeaworldWaitTimesInterface> {
const date = moment().format('YYYY-MM-DD');

return this.http.get<SeaworldWaitTimesInterface>(`${this._apiUrl}/park/${this.getParkId()}/availability?searchDate=${date}`)
.toPromise()
.then((res) => res.data);
}
}
13 changes: 13 additions & 0 deletions src/parks/seaworld/seaworld-parks.curl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
curl 'https://public.api.seaworld.com/v1/park' \
-H 'Host: public.api.seaworld.com' \
-H 'x-datadog-parent-id: 4428742480944239379' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..eFtqROn6cku64r7wfLzAOQ.NRsZK3WaMjVPBGH2ndJvMjRa-uM3lRHV5BUSuJPxmFgrEtNRr4kqq0vw5oS3-JuXf3Yq4z-NDcylpt9ykcBeXrittDox0edVGZhWeXD5fN56RD9XGj9yePZq37cQy2iINh-nftpoB2O9u1QdenLwxaC_nXCPad9b5CBIUyljauuAJSuYr8-ctv6-EpebUhnSqrMvgnYdKGqK10efI08hz2ZQVOKVvZ86XBhdAoyknBh2QafI5rMMF69w5GNMup8SB0mjs4FhMv7DoI4lsNXjxSmGFjceUUva_qJ6Ke1BEgo.h7eyGsE0GPuNVdc1QzWGPg' \
-H 'x-datadog-sampling-priority: 1' \
-H 'app_version: ios-7.1.222.330' \
-H 'x-datadog-trace-id: 7563024135700404135' \
-H 'Accept-Language: nl-NL,nl;q=0.9' \
-H 'User-Agent: SeaWorld/330 CFNetwork/1496.0.7 Darwin/23.5.0' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
--proxy http://localhost:9090
98 changes: 98 additions & 0 deletions src/parks/seaworld/seaworld-parks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
[
{
"UriId": "tampa",
"Name": "Adventure Island Tampa",
"Brand": "Adventure Island",
"Id": "770E691C-E6DA-4264-AF27-863189380D0B",
"ParkId": 2,
"park_id": 2
},
{
"UriId": "orlando",
"Name": "Aquatica Orlando",
"Brand": "Aquatica",
"Id": "4B040706-968A-41B4-9967-D93C7814E665",
"ParkId": 3,
"park_id": 3
},
{
"UriId": "san-antonio",
"Name": "Aquatica San Antonio",
"Brand": "Aquatica",
"Id": "04668F50-A57E-4DE6-8E70-D4567D9B46B5",
"ParkId": 15,
"park_id": 15
},
{
"UriId": "tampa",
"Name": "Busch Gardens Tampa",
"Brand": "Busch Gardens",
"Id": "C001866B-555D-4E92-B48E-CC67E195DE96",
"ParkId": 8,
"park_id": 8
},
{
"UriId": "williamsburg",
"Name": "Busch Gardens Williamsburg",
"Brand": "Busch Gardens",
"Id": "45FE1F31-D4E4-4B1E-90E0-5255111070F2",
"ParkId": 9,
"park_id": 9
},
{
"UriId": "orlando",
"Name": "Discovery Cove Orlando",
"Brand": "Discovery Cove",
"Id": "1FB04DFC-B6C0-4918-BE36-EE6DD14FE741",
"ParkId": 12,
"park_id": 12
},
{
"UriId": "orlando",
"Name": "SeaWorld Orlando",
"Brand": "SeaWorld",
"Id": "AC3AF402-3C62-4893-8B05-822F19B9D2BC",
"ParkId": 4,
"park_id": 4
},
{
"UriId": "san-antonio",
"Name": "SeaWorld San Antonio",
"Brand": "SeaWorld",
"Id": "F4040D22-8B8D-4394-AEC7-D05FA5DEA945",
"ParkId": 5,
"park_id": 5
},
{
"UriId": "san-diego",
"Name": "SeaWorld San Diego",
"Brand": "SeaWorld",
"Id": "4325312F-FDF1-41FF-ABF4-361A4FF03443",
"ParkId": 1,
"park_id": 1
},
{
"UriId": "langhorne",
"Name": "Sesame Place Langhorne",
"Brand": "Sesame Place",
"Id": "F7408854-28CB-4B1E-98E5-4449FE600E85",
"ParkId": 7,
"park_id": 7
},
{
"UriId": "san-diego",
"Name": "Sesame Place San Diego",
"Brand": "Sesame Place",
"Id": "A988F4CE-6A81-4527-9535-DDB378689E52",
"ParkId": 34,
"park_id": 34
},
{
"UriId": "williamsburg",
"Name": "Water Country USA",
"Brand": "Water Country",
"Id": "66480532-A73C-4617-9B2D-EDC4430CAB86",
"ParkId": 11,
"park_id": 11
}
]
29 changes: 29 additions & 0 deletions src/parks/seaworld/seaworld-transfer/seaworld-transfer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { TransferService } from '../../../_services/transfer/transfer.service';
import { Poi } from '../../../_interfaces/poi.interface';
import { SeaworldBaseItem } from '../interfaces/seaworld-base-item.interface';
import { PoiCategory } from '../../../_interfaces/poi-categories.enum';
import { ShowTime } from '../../../_interfaces/showtimes.interface';
import * as moment from 'moment-timezone';

@Injectable()
export class SeaworldTransferService extends TransferService {
Expand Down Expand Up @@ -64,6 +66,33 @@ export class SeaworldTransferService extends TransferService {
}
}

if (poi.ShowTimes) {
// "StartDateTime": "2024-06-10T18:30:00Z",
// "EndDateTime": "2024-06-10T19:00:00Z",
// "StartTime": "2024-06-10T13:30:00",
// "EndTime": "2024-06-10T14:00:00"
const showTimes = poi.ShowTimes.map((s): ShowTime => {
const start = moment(s.StartTime).tz('America/Los_Angeles', false);

return {
from: start.format(),
fromTime: moment(s.StartTime).format('HH:mm:ss'),
to: moment(s.StartTime).tz('America/Los_Angeles', false).format(),
isPassed: moment().tz('America/Los_Angeles', false).isAfter(start),
}
})

const d = new Date();
p.showTimes = {
currentDate: moment().tz('America/Los_Angeles').format(),
allShowTimes: showTimes,
futureShowTimes: showTimes.filter(s => moment(s.from).isSame(d, 'day') && !s.isPassed),
pastShowTimes: showTimes.filter(s => moment(s.from).isSame(d, 'day') && s.isPassed),
todayShowTimes: showTimes.filter(s => moment(s.from).isSame(d, 'day')),
otherDateShowTimes: showTimes.filter(s => !moment(s.from).isSame(d, 'day')),
};
}

if (poi.MinimumHeight > 0) {
p.minSizeWithEscort = Math.round(poi.MinimumHeight * 2.54)
}
Expand Down
4 changes: 3 additions & 1 deletion src/parks/seaworld/seaworld.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { SeaworldOrlandoService } from './seaworld-orlando/seaworld-orlando.serv
import { SeaworldSanDiegoService } from './seaworld-san-diego/seaworld-san-diego.service';
import { BushGardensWilliamsburgService } from './bush-gardens-williamsburg/bush-gardens-williamsburg.service';
import { BushGardensTampaBayService } from './bush-gardens-tampa-bay/bush-gardens-tampa-bay.service';
import { SesamePlaceSanDiegoService } from './sesame-place-san-diego/sesame-place-san-diego.service';
import { SesamePlaceLanghorneService } from './sesame-place-langhorne/sesame-place-langhorne.service';

@Module({
imports: [
Expand All @@ -19,7 +21,7 @@ import { BushGardensTampaBayService } from './bush-gardens-tampa-bay/bush-garden
ignoreEnvFile: false,
}),
],
providers: [SeaworldBaseService, SeaworldSanAntonioService, SeaworldService, SeaworldTransferService, SeaworldOrlandoService, SeaworldSanDiegoService, BushGardensWilliamsburgService, BushGardensTampaBayService],
providers: [SeaworldBaseService, SeaworldSanAntonioService, SeaworldService, SeaworldTransferService, SeaworldOrlandoService, SeaworldSanDiegoService, BushGardensWilliamsburgService, BushGardensTampaBayService, SesamePlaceSanDiegoService, SesamePlaceLanghorneService],
exports: [SeaworldService],
})
export class SeaworldModule {}
8 changes: 7 additions & 1 deletion src/parks/seaworld/seaworld.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { SeaworldSanDiegoService } from './seaworld-san-diego/seaworld-san-diego
import { SeaworldOrlandoService } from './seaworld-orlando/seaworld-orlando.service';
import { BushGardensTampaBayService } from './bush-gardens-tampa-bay/bush-gardens-tampa-bay.service';
import { BushGardensWilliamsburgService } from './bush-gardens-williamsburg/bush-gardens-williamsburg.service';
import { SesamePlaceLanghorneService } from './sesame-place-langhorne/sesame-place-langhorne.service';
import { SesamePlaceSanDiegoService } from './sesame-place-san-diego/sesame-place-san-diego.service';

@Injectable()
export class SeaworldService extends CompanyService {
Expand All @@ -15,6 +17,8 @@ export class SeaworldService extends CompanyService {
private readonly seaworldOrlando: SeaworldOrlandoService,
private readonly bushGardensTampaBay: BushGardensTampaBayService,
private readonly bushGardensWilliamsburg: BushGardensWilliamsburgService,
private readonly sesameplaceLanghorne: SesamePlaceLanghorneService,
private readonly sesameplaceSanDiego: SesamePlaceSanDiegoService,
) {
super();
}
Expand All @@ -25,7 +29,9 @@ export class SeaworldService extends CompanyService {
this.seaworldSanDiego,
this.seaworldOrlando,
this.bushGardensTampaBay,
this.bushGardensWilliamsburg
this.bushGardensWilliamsburg,
this.sesameplaceLanghorne,
this.sesameplaceSanDiego,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SesamePlaceLanghorneService } from './sesame-place-langhorne.service';
import { SeaworldTransferService } from '../seaworld-transfer/seaworld-transfer.service';
import { HttpModule } from '@nestjs/axios';
import { ConfigModule } from '@nestjs/config';

describe('SesamePlaceLanghorneService', () => {
let service: SesamePlaceLanghorneService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [SesamePlaceLanghorneService, SeaworldTransferService],
imports: [
HttpModule,
ConfigModule.forRoot()
]
}).compile();

service = module.get<SesamePlaceLanghorneService>(SesamePlaceLanghorneService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});

it('should return info', () => {
expect(service.getInfo().id).toBeDefined();
});

it('should return a list of POIs', async () => {
const data = await service.getPois();
expect(data).toBeInstanceOf(Array);
}, 1000 * 60);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Injectable } from '@nestjs/common';
import { SeaworldBaseService } from '../seaworld-base/seaworld-base.service';
import { Company, ParkType, ThemePark } from '../../../_interfaces/park.interface';

@Injectable()
export class SesamePlaceLanghorneService extends SeaworldBaseService {
getInfo(): ThemePark {
return {
countryCode: 'us',
description: 'Sesame Place Philadelphia is een kinderthemapark en waterpark gebaseerd op het educatieve kindertelevisieprogramma Sesamstraat',
id: 'sesame-place-philadelphia-langhorne',
image: 'https://sesameplace.com/philadelphia/-/media/migrated-media/sesame-place-langhorne/images/scope/1900x700/1900x700_frontgate2.jpg?h=700&w=1900&la=en&hash=28BEF8C86BE23964B53D2450B858C938',
name: 'Sesame Place Philadelphia',
parkType: ParkType.THEMEPARK,
company: Company.SEAWORLD,
location: {
lat: 40.185808,
lng: -74.871976,
},
};
}

getParkId(): string {
return 'F7408854-28CB-4B1E-98E5-4449FE600E85';
}
}
Loading

0 comments on commit c10fd73

Please sign in to comment.