Where-in-the-World-is-Ben/app/Http/Controllers/TrackerController.php

185 lines
6.5 KiB
PHP
Raw Normal View History

2022-11-01 00:50:43 +00:00
<?php
namespace App\Http\Controllers;
use DateTime;
use App\Mail\WeeklyDigest;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
class TrackerController extends Controller
{
/**
* Show the list of past trips.
* TODO: Get these from the Wayward API rather than hard-coding them.
*
* @return \Illuminate\View\View
*/
2022-11-30 18:47:09 +00:00
public function show_past_trips_list()
{
2022-11-01 00:50:43 +00:00
return view('past-trips');
}
/**
* Show a trip in tracker app.
*
* @param Request $request
* @param string? $tripId
* @return \Illuminate\View\View
*/
2022-11-30 18:47:09 +00:00
public function show_trip(Request $request, string $tripId = null)
{
$tripId = $tripId ?? config('app.current_trip_id');
2022-11-30 18:47:09 +00:00
if (!$tripId) {
return view('no-trip');
}
2022-11-01 00:50:43 +00:00
$viewMode = $request->input('show', null);
2022-11-10 02:16:12 +00:00
$fromCheckin = $request->input('from', null);
$toCheckin = $request->input('to', null);
2022-11-29 23:58:11 +00:00
$forceDownload = $request->input('force', false);
$tripData = $this->get_trip_data($tripId, $forceDownload);
2022-11-01 00:50:43 +00:00
2022-11-10 02:16:12 +00:00
if ($fromCheckin) {
2022-11-29 23:58:11 +00:00
$tripData->checkins = array_filter(
2022-11-30 18:47:09 +00:00
$tripData->checkins,
function ($key) use ($fromCheckin) {
return $key >= $fromCheckin;
},
2022-11-29 23:58:11 +00:00
ARRAY_FILTER_USE_KEY
);
2022-11-10 02:16:12 +00:00
}
if ($toCheckin) {
2022-11-29 23:58:11 +00:00
$tripData->checkins = array_filter(
2022-11-30 18:47:09 +00:00
$tripData->checkins,
function ($key) use ($toCheckin) {
return $key <= $toCheckin;
},
2022-11-29 23:58:11 +00:00
ARRAY_FILTER_USE_KEY
);
2022-11-10 02:16:12 +00:00
}
return view(
2022-11-30 18:47:09 +00:00
'tracker',
[
2022-11-30 18:47:09 +00:00
'trip' => $tripData,
2022-11-10 02:16:12 +00:00
'showAllCheckins' => ($viewMode === 'all'),
'fromCheckin' => $fromCheckin,
'toCheckin' => $toCheckin
]
);
}
/**
* Retrieves a trip from the local cache, or from the Wayward API.
*
* The retrieval algorithm is as follows:
* 1. If no local cache exists, download the trip data
* 2. If a local cache exists:
* 1. If the trip is inactive (i.e., finished), use the cache
* 2. If the trip is active:
* 1. If the trip was actively tracking at last check, use the
2022-11-30 18:47:09 +00:00
* cache if it's less than an hour old. Otherwise, download
* the new trip data.
* 2. If the trip was not actively tracking at lest check, use
* the cache if it's less than three hours old. Otherwise,
* download the new trip data.
* 3. If new trip data is downloaded, overwrite any cached data.
*
* @param string $tripId
2022-11-29 23:58:11 +00:00
* @param bool $forceDownload
* @return string
*/
2022-11-30 18:47:09 +00:00
public function get_trip_data(string $tripId, bool $forceDownload = false)
{
2022-11-01 00:50:43 +00:00
$tripFileName = ( $tripId ?? config('app.current_trip_id') ) . '.json';
// Returns the cached trip data if the trip is inactive (i.e., finished)
// or less than 13 hours old, depending on whether it was tracking
// at last check or not.
2022-11-29 23:58:11 +00:00
if (!$forceDownload && Storage::disk('local')->exists($tripFileName)) {
2022-11-01 00:50:43 +00:00
Log::debug("Cached trip file '{$tripFileName}' found...");
$cachedData = json_decode(Storage::disk('local')->get($tripFileName))->trip;
if ($cachedData->is_active) {
Log::debug("Cached trip file '{$tripFileName}' is for an active trip.");
$cachedDataUpdatedAt = new DateTime($cachedData->updated_at);
$now = new DateTime();
$cachingTimeout = ($cachedData->is_tracking) ? 1 : 3;
$cachedDataAge = intval(($now->getTimestamp() - $cachedDataUpdatedAt->getTimestamp()) / 3600);
if ($cachedDataAge <= $cachingTimeout) {
2022-11-30 18:47:09 +00:00
Log::debug(
"Cached trip file '" .
$tripFileName .
"' is younger than " .
$cachingTimeout .
" hours, showing from cache..."
);
return $cachedData;
2022-11-01 00:50:43 +00:00
}
} else {
2022-11-30 18:47:09 +00:00
Log::debug(
"Cached trip file '" .
$tripFileName .
"' is for an old trip, showing from cache..."
);
return $cachedData;
2022-11-01 00:50:43 +00:00
}
}
// Otherwise, download the trip data from the Wayward API.
2022-11-29 23:58:11 +00:00
if ($forceDownload) {
Log::debug("Forcing download for '{$tripFileName}'.");
} else {
Log::debug("No cached trip file found for '{$tripFileName}'.");
}
2022-11-01 00:50:43 +00:00
$client = new Client([
'base_uri' => 'https://app.wayward.travel/',
'timeout' => 3.0
]);
$response = $client->get('trip/'.($tripId ?? config('app.current_trip_id')).'/user/zmld8ko6qy7d9j3xvq10/json');
switch ($response->getStatusCode()) {
2022-11-30 18:47:09 +00:00
case 200:
$data = json_decode($response->getBody());
2022-11-01 00:50:43 +00:00
// Cache the downloaded file if it does not exist locally.
if (Storage::disk('local')->missing($tripFileName)) {
2022-11-30 18:47:09 +00:00
Log::debug("Caching new trip file '{$tripFileName}'.");
2022-11-01 00:50:43 +00:00
Storage::disk('local')->put($tripFileName, json_encode($data));
} else {
2022-11-30 18:47:09 +00:00
$cachedData = json_decode(Storage::disk('local')->get($tripFileName));
if ($data->trip->updated_at !== $cachedData->trip->updated_at) {
Log::debug(
"Cached trip file '" .
$tripFileName .
"' has different 'updated_at' time, updating cache..."
);
Storage::disk('local')->put($tripFileName, json_encode($data));
// TODO: Cache photos locally
} else {
Log::debug(
"Cached trip file '" .
$tripFileName .
"' has same 'updated_at' time, showing from cache..."
);
$data = $cachedData;
}
2022-11-01 00:50:43 +00:00
}
2022-11-30 18:47:09 +00:00
return $data->trip;
default:
// TODO: Add proper error handling.
return "Something went wrong";
2022-11-01 00:50:43 +00:00
}
}
}