Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Park Fixes #21

Merged
merged 12 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions .github/workflows/qodana_code_quality.yml

This file was deleted.

10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ In the table below you will find the parks that are currently supported and the
| 🇧🇪 Bellewaerde | 🎡 | True | True | True | True | False |
| 🇧🇪 Bobbejaanland | 🎡 | True | True | False | True | False |
| 🇧🇪 Plopsalande de Panne | 🎡 | True | True | True | True | False |
| 🇧🇪 Pairi Daiza | 🦁 | False | True | True | True | False |
| 🇨🇦 La Ronde, Montreal | 🎡 | True | True | True | True | False |
| 🇩🇪 Phantasialand | 🎡 | True | True | True | True | False |
| 🇩🇪 Holiday Park | 🎡 | True | True | True | True | False |
| 🇩🇪 LegoLand Deutschland | 🎡 | False | False | False | False | False |
| 🇩🇪 LegoLand Deutschland | 🎡 | True | True | True | True | False |
| 🇩🇪 Hansa Park | 🎡 | True | True | True | True | False |
| 🇩🇪 Movie Park Germany | 🎡 | True | True | True | True | True |
| 🇩🇪 Heidi Park | 🎡 | True | True | True | True | False |
| 🇩🇰 Tivoli | 🎡 | True | True | True | False | False |
| 🇪🇸 Portaventura | 🎡 | True | True | True | True | False |
| 🇪🇸 Ferrari Land | 🎡 | True | True | True | True | False |
Expand All @@ -42,15 +44,15 @@ In the table below you will find the parks that are currently supported and the
| 🇮🇹 Mirabilandia | 🎡 | True | True | False | True | False |
| 🇳🇱 Efteling | 🎡 | True | True | True | True | False |
| 🇳🇱 Toverland | 🎡 | True | True | True | False | True |
| 🇳🇱 Walibi Holland | 🎡 | True | True | False | True | False |
| 🇳🇱 Walibi Holland | 🎡 | True | True | True | True | True |
| 🇳🇱 DippieDoe | 🎡 | True | False | False | False | False |
| 🇳🇱 Hellendoorn | 🎡 | True | True | True | True | False |
| 🇳🇱 Ouwehands Dierenpark | 🦁 | False | False | False | False | False |
| 🇳🇱 Wildlands | 🦁 | False | False | False | False | False |
| 🇳🇱 Blijdorp | 🦁 | False | False | True | False | False |
| 🇳🇱 Apenheul | 🦁 | False | False | False | False | False |
| 🇳🇱 Safaripark Beekse Bergen | 🦁 | False | True | False | False | False |
| 🇳🇱 Speelland Beekse Bergen | 🎡 | True | False | False | False | False |
| 🇳🇱 Safaripark Beekse Bergen | 🦁 | True | True | False | True | False |
| 🇳🇱 Speelland Beekse Bergen | 🎡 | True | True | False | True | False |
| 🇵🇱 Energylandia | 🎡 | True | False | True | False | False |
| 🇸🇪 Liseberg | 🎡 | True | True | False | True | False |
| 🇸🇪 Grona Lund | 🎡 | True | False | False | False | False |
Expand Down
10 changes: 8 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "themeparks-node-api",
"version": "0.5.1",
"version": "0.6.0",
"description": "An API which can retrieve theme park wait times.",
"author": "Tim Arendsen",
"private": false,
Expand Down Expand Up @@ -53,6 +53,7 @@
"reflect-metadata": "^0.2.2",
"rimraf": "^5.0.7",
"rxjs": "^7.8.1",
"sluggo": "^1.0.0",
"swagger-ui-express": "^5.0.1",
"typeorm": "^0.3.20",
"unzipper": "^0.12.1",
Expand Down
6 changes: 6 additions & 0 deletions src/_interfaces/event.category.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum EventCategory {
HALLOWEEN = 'HALLOWEEN',
WINTER = 'WINTER',
EASTER = 'EASTER',
OTHER = 'OTHER',
}
15 changes: 15 additions & 0 deletions src/_interfaces/park-event.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { EventCategory } from './event.category';
import { Poi } from './poi.interface';

export interface ThemeParkEvent {
fromDate?: string;
toDate?: string;
dates?: string[];
type: EventCategory;
slug: string;
name?: string;
subTitle?: string;
description?: string;
image?: string,
pois?: Poi[];
}
6 changes: 4 additions & 2 deletions src/_interfaces/park-supports.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ export interface ThemeParkSupports {
supportsTranslations: boolean;

/**
* @description Whether or not a park supports returning Halloween related items, such as scare zones and experiences
* @description Whether or not a park supports returning special event related items, such as Halloween scare zones and experiences or Christmas experiences
*/
supportsHalloween: boolean;
supportsEvents: boolean;

textType: "UNDEFINED" | "HTML" | "MARKDOWN";
}
2 changes: 2 additions & 0 deletions src/_interfaces/park.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ export enum Company {
SEAWORLD = 'SEAWORLD',
UNIVERSAL = 'UNIVERSAL',
PARQUES_REUNIDOS = 'PARQUES_REUNIDOS',
LIBEMA = 'LIBEMA',
MERLIN_ENTERTAINMENTS = 'MERLIN_ENTERTAINMENTS'
}
1 change: 1 addition & 0 deletions src/_interfaces/poi-categories.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum PoiCategory {
GUEST_SERVICES = 'GUEST_SERVICES',
PLAYGROUND = 'PLAYGROUND',
PARKING = 'PARKING',
ENTRANCE = 'ENTRANCE',
HALLOWEEN_WALKTROUGH = 'HALLOWEEN_WALKTROUGH',
HALLOWEEN_EVENT = 'HALLOWEEN_EVENT',
HALLOWEEN_HOUSE = 'HALLOWEEN_HOUSE',
Expand Down
11 changes: 11 additions & 0 deletions src/_interfaces/poi-fact.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ export interface PoiFact {
| 'capacity'
| 'inversion_count'
| 'passengers_per_car'
| 'animal_height'
| 'animal_width'
| 'animal_weight'
| 'animal_longevity'
| 'animal_diet'
| 'animal_class'
| 'animal_habitat'
| 'animal_iucn'
| 'animal_gestation'
| 'animal_offspring'
| 'animal_bigFive'
| string;
description?: string;
content?: string;
Expand Down
1 change: 1 addition & 0 deletions src/_interfaces/poi-video.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export interface PoiVideo {
platform: 'YOUTUBE' | 'VIMEO' | 'FACEBOOK' | 'URL' | 'OTHER',
embed_id?: string,
full_url?: string,
thumbnail?: string,
}
6 changes: 6 additions & 0 deletions src/_interfaces/poi.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Translation } from './translation.interface';
import { PoiMenuItemInterface } from './poi-menu-item.interface';
import { PoiFact } from './poi-fact.interface';
import { PoiVideo } from './poi-video.interface';
import { EventCategory } from './event.category';

export interface Poi {
/**
Expand All @@ -31,6 +32,11 @@ export interface Poi {
*/
original_category?: string;

/**
* The type of event this poi relates to, if available
*/
eventCategory?: EventCategory;

/**
* The name of the POI
*/
Expand Down
10 changes: 9 additions & 1 deletion src/_services/aio/aio-themepark.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class AioThemeparkService extends ThroughPoisThemeParkService {

private _tempToken: string;

// TODO: Some AIO parks offer localizations
constructor(protected readonly httpService: HttpService,
protected readonly configService: ConfigService,
private readonly transferService: AioTransferServiceService) {
Expand All @@ -44,7 +45,8 @@ export class AioThemeparkService extends ThroughPoisThemeParkService {
supportsRideWaitTimesHistory: false,
supportsPois: true,
supportsTranslations: false,
supportsHalloween: false,
textType: "UNDEFINED",
supportsEvents: false,
};
}

Expand Down Expand Up @@ -80,6 +82,8 @@ export class AioThemeparkService extends ThroughPoisThemeParkService {
'Content-Type': settings.contentType,
};

console.debug(" - AIO: Fetching Token");

const config: AxiosRequestConfig = { headers: headers };

return await this.httpService
Expand All @@ -90,6 +94,7 @@ export class AioThemeparkService extends ThroughPoisThemeParkService {
)
.toPromise()
.then(value => {
console.debug(` - AIO: API Key is ${value.data.token}`)
this._tempToken = value.data.token;
return this._tempToken;
})
Expand All @@ -110,6 +115,7 @@ export class AioThemeparkService extends ThroughPoisThemeParkService {
const headers = {
'Authorization': `Attractions-Io api-key="${this.getApiKey()}", installation-token="${token}"`,
'Date': settings.latestUpdate,
'Occasio-Data-Version': settings.latestUpdate,
'User-Agent': settings.userAgent,
};

Expand All @@ -121,6 +127,8 @@ export class AioThemeparkService extends ThroughPoisThemeParkService {
maxRedirects: 0,
};

console.debug(` - AIO: Fetching Data Package URL for ${settings.latestUpdate}`);

return new Promise((resolve, reject) => {
this.httpService
.get(
Expand Down
6 changes: 6 additions & 0 deletions src/_services/parks/parks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ import { MirabilandiaService } from '../../parks/parques-reunidos/mirabilandia/m
import {
MarinelandCoteDazurService
} from '../../parks/parques-reunidos/marineland-cote-dazur/marineland-cote-dazur.service';
import { MerlinEntertainmentsService } from '../../parks/merlin-entertainments/merlin-entertainments.service';
import { PairiDaizaService } from '../../parks/pairi-daiza/pairi-daiza.service';

@Injectable()
export class ParksService {
Expand Down Expand Up @@ -120,6 +122,8 @@ export class ParksService {
private readonly _gardaland: GardalandService,
private readonly _mirabilandia: MirabilandiaService,
private readonly _marineLandCoteDazur: MarinelandCoteDazurService,
private readonly _merlinEntertainmentsService: MerlinEntertainmentsService,
private readonly _pairiDaizaService: PairiDaizaService,
) {
this._parks = [];
this._parks.push(_eftelingService);
Expand Down Expand Up @@ -168,12 +172,14 @@ export class ParksService {
this._parks.push(_gardaland)
this._parks.push(_mirabilandia)
this._parks.push(_marineLandCoteDazur)
this._parks.push(_pairiDaizaService)

this._companies = [];
this._companies.push(_sixflagsService);
this._companies.push(_cedarFairService);
this._companies.push(_seaworldCompanyService);
this._companies.push(_universalService);
this._companies.push(_merlinEntertainmentsService);
}

public async getParks(): Promise<ThemeParkService[]> {
Expand Down
5 changes: 5 additions & 0 deletions src/_services/themepark/theme-park.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ThemePark } from '../../_interfaces/park.interface';
import { Poi } from '../../_interfaces/poi.interface';
import { ThemeParkSupports } from '../../_interfaces/park-supports.interface';
import { ThemeParkOpeningTimes } from '../../_interfaces/park-openingtimes.interface';
import { ThemeParkEvent } from '../../_interfaces/park-event.interface';

@Injectable()
export class ThemeParkService {
Expand Down Expand Up @@ -93,4 +94,8 @@ export class ThemeParkService {
async getOpeningTimes(): Promise<ThemeParkOpeningTimes[]> {
throw new NotImplementedException("Could not get opening times");
}

async getEvents(): Promise<ThemeParkEvent[]> {
throw new NotImplementedException("Could not get events");
}
}
1 change: 1 addition & 0 deletions src/controllers/blog-posts/blog-posts.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class BlogPostsController {
return this.blogPostService.getAll(this.localeService.getLocale());
}

// TODO: Should more information be cached?
@ApiOkResponse({
type: BlogPost,
isArray: true,
Expand Down
30 changes: 29 additions & 1 deletion src/controllers/park/park.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { LanguageInterceptor } from '../../_interceptors/language.interceptor';
import { ThemeParkOpeningTimes } from '../../_interfaces/park-openingtimes.interface';
import { ThemeParkOpeningHourDto } from '../../_dtos/theme-park-opening-hour.dto';
import { CACHE_MANAGER, CacheInterceptor } from '@nestjs/cache-manager';
import { ThemeParkEvent } from '../../_interfaces/park-event.interface';

@ApiTags('Themeparks')
@Controller('parks/:id')
Expand Down Expand Up @@ -265,7 +266,7 @@ export class ParkController {
async getParkHalloweenRelatedItems(@Param() params, @Query() query): Promise<Poi[]> {
const park = await this.parksService.findPark(params.id, true);

if (!park.getFullInfo().supports.supportsHalloween) {
if (!park.getFullInfo().supports.supportsEvents) {
throw new BadRequestException('This park does not support halloween related items');
}

Expand Down Expand Up @@ -306,4 +307,31 @@ export class ParkController {

return await park.getOpeningTimes();
}

@Get('events')
@UseInterceptors(CacheInterceptor, LanguageInterceptor)
@ApiParam({
name: 'id',
type: 'string',
description: 'The park id',
})
@ApiResponse({
status: 200,
description: 'All events of a specific park, with all available data',
isArray: true,
type: ThemeParkOpeningHourDto,
})
@ApiResponse({
status: 404,
description: 'The requested park could not be found',
})
async getParkEvents(@Param() params): Promise<ThemeParkEvent[]> {
const park = await this.parksService.findPark(params.id, true);

if (!park.getFullInfo().supports.supportsEvents) {
throw new BadRequestException('This park does not support events');
}

return await park.getEvents();
}
}
Loading
Loading