first commit

This commit is contained in:
Uther
2024-08-20 21:08:23 +02:00
commit a46fcb28b0
80 changed files with 13840 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
<?php
namespace App\Http\Controllers;
abstract class Controller
{
//
}

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers;
use App\Http\Services\PhantasialandApi;
use App\Models\ThemeParkUser;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Foundation\Application;
class ThemeParkController extends Controller
{
function __construct(readonly PhantasialandApi $api, readonly ThemeParkUser $user)
{
}
public function index(): Factory|View|Application
{
$pois = $this->api->getPointsOfInterest();
$queueTimes = $this->api->getLiveQueueTimes();
$queueTimes = $queueTimes->mapWithKeys(function ($queueTime) {
return [$queueTime["poiId"] => $queueTime];
});
$pois = $pois->filter(function ($poi) use ($queueTimes) {
return $queueTimes->has($poi->id);
})->map(function ($poi) use ($queueTimes) {
$poi->setInfo($queueTimes[$poi->id]);
return $poi;
});
return view('theme-park', [
'pois' => $pois
]);
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace App\Http\Services;
use App\Data\PointOfInterest;
use App\Models\ThemeParkUser;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use Psr\Http\Message\RequestInterface;
class PhantasialandApi
{
private readonly string $uri;
private readonly PendingRequest $client;
function __construct()
{
$this->uri = 'https://api.phlsys.de/api/';
$this->client = Http::baseUrl($this->uri)->withRequestMiddleware(function (RequestInterface $request) {
$user = app(ThemeParkUser::class);
$uri = $request->getUri();
$uri = $uri->withQuery($uri->getQuery().'&access_token='.$user->access_token);
return $request->withUri($uri);
});
}
public function getPointsOfInterest(): Collection
{
$response = $this->client->get('pois');
$pois = collect($response->json());
// NOTE: Either poiNumber or poiNumberWinter is always null
// TODO: Use a generic field name and fill in the one that is not null
// TODO: Add a type if the poi is winter only
// NOTE: we filter everything out that is not a ATTRACTIONS
// NOTE: we filter everything out that is adminOnly = true
$pois = $pois->filter(function ($poi) {
return $poi['category'] === 'ATTRACTIONS' && $poi['adminOnly'] === false &&
$poi['poiNumber'] !== null;
});
// sort by parkMonitorReferenceName
$pois = $pois->sortBy('parkMonitorReferenceName');
return $pois->transform(function ($poi) {
return new PointOfInterest(
id: $poi['id'],
poiNumber: $poi['poiNumber'],
poiNumberWinter: $poi['poiNumberWinter'],
category: $poi['category'],
tags: $poi['tags'],
area: $poi['area'],
seasons: $poi['seasons'],
title: $poi['_title']['de'],
description: $poi['_description']['de'],
entrance: $poi['_entrance']['world'],
titleImage: key_exists('titleImage', $poi) ? $poi['titleImage']['url'] : null,
);
});
}
public function getLiveQueueTimes(): Collection
{
[
'longitude' => $longitude,
'latitude' => $latitude
] = $this->getRandomLocation();
$latitude = number_format($latitude, 14);
$longitude = number_format($longitude, 14);
$response = $this->client->get('signage-snapshots', [
'loc' => "$latitude,$longitude",
]);
return collect($response->json());
}
public function createUser(): array
{
$username = uuid_create().'@android.com';
$password = uuid_create();
$response = $this->client->post('app-users', [
'email' => $username,
'password' => $password,
'language' => 'en',
'platform' => 'android',
]);
return [
...$response->json(),
'password' => $password,
];
}
public function getAccessToken(ThemeParkUser $user): string
{
$response = $this->client->post('app-users/login', [
'email' => $user->username,
'password' => $user->password,
'ttl' => now()->diffInSeconds(now()->addYear()),
]);
return $response->json()['id'];
}
private function getRandomLocation(): array
{
// TODO: Its not random right now
// $rnd = mt_rand() / mt_getrandmax();
return [
'longitude' => 6.878342628,
'latitude' => 50.800659529,
];
}
}