You've already forked Atomcms-edit
162 lines
4.7 KiB
PHP
Executable File
162 lines
4.7 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Miscellaneous\WebsiteSetting;
|
|
use App\Models\User;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Http\Client\ConnectionException;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
|
|
#[AsCommand(name: 'radio:check-dj')]
|
|
final class CheckDjConnection extends Command
|
|
{
|
|
#[\Override]
|
|
protected $signature = 'radio:check-dj {--force : Force check even if auto-detection is disabled}';
|
|
|
|
#[\Override]
|
|
protected $description = 'Check if a DJ is connected via Sambroadcaster or Virtual DJ';
|
|
|
|
private const string CACHE_KEY = 'website_settings';
|
|
|
|
private const string DJ_CHECK_RATE_LIMIT = 'dj-check';
|
|
|
|
public function handle(): int
|
|
{
|
|
$autoDetection = $this->getSetting('radio_auto_dj_detection', '0');
|
|
|
|
if ($autoDetection !== '1' && ! $this->option('force')) {
|
|
$this->info('Auto DJ detectie is uitgeschakeld. Gebruik --force om toch te controleren.');
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
if (RateLimiter::tooManyAttempts(self::DJ_CHECK_RATE_LIMIT, 10)) {
|
|
$this->info('Te veel pogingen. Wacht even.');
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
RateLimiter::hit(self::DJ_CHECK_RATE_LIMIT, 60);
|
|
|
|
$sambroadcasterUrl = $this->getSetting('radio_sambroadcaster_api_url', '');
|
|
$virtualDjUrl = $this->getSetting('radio_virtual_dj_url', '');
|
|
|
|
$detectedDj = $this->checkSambroadcaster($sambroadcasterUrl);
|
|
|
|
if ($detectedDj === null) {
|
|
$detectedDj = $this->checkVirtualDj($virtualDjUrl);
|
|
}
|
|
|
|
if ($detectedDj === null) {
|
|
$this->info('Geen DJ verbonden.');
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
$this->processDetectedDj($detectedDj);
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
private function getSetting(string $key, string $default = ''): string
|
|
{
|
|
/** @var WebsiteSetting|null $setting */
|
|
$setting = WebsiteSetting::where('key', $key)->first();
|
|
|
|
return $setting !== null && isset($setting->value) ? (string) $setting->value : $default;
|
|
}
|
|
|
|
private function checkSambroadcaster(string $url): ?string
|
|
{
|
|
if ($url === '' || $url === '0') {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
$response = Http::timeout(5)
|
|
->withQueryParameters(['format' => 'json'])
|
|
->get($url . '/dj');
|
|
|
|
if ($response->successful()) {
|
|
/** @var array<string, mixed> $data */
|
|
$data = $response->json();
|
|
|
|
$djName = $data['dj_name'] ?? $data['dj'] ?? $data['current_dj'] ?? $data['name'] ?? null;
|
|
|
|
return is_string($djName) ? $djName : null;
|
|
}
|
|
} catch (ConnectionException) {
|
|
return null;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function checkVirtualDj(string $url): ?string
|
|
{
|
|
if ($url === '' || $url === '0') {
|
|
return null;
|
|
}
|
|
|
|
$endpoints = ['/info', '/status', '/api/dj', '/api/info'];
|
|
|
|
foreach ($endpoints as $endpoint) {
|
|
try {
|
|
$response = Http::timeout(5)
|
|
->withQueryParameters(['format' => 'json'])
|
|
->get($url . $endpoint);
|
|
|
|
if ($response->successful()) {
|
|
/** @var array<string, mixed> $data */
|
|
$data = $response->json();
|
|
$djName = $data['djname'] ?? $data['DJName'] ?? $data['current_dj'] ?? $data['dj'] ?? $data['name'] ?? null;
|
|
|
|
if ($djName !== null && is_string($djName) && ! in_array(strtolower($djName), ['guest', ''])) {
|
|
return $djName;
|
|
}
|
|
}
|
|
} catch (ConnectionException) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function processDetectedDj(string $detectedDj): void
|
|
{
|
|
/** @var User|null $djUser */
|
|
$djUser = User::where('username', $detectedDj)->first();
|
|
|
|
if ($djUser === null) {
|
|
$this->warn("DJ {$detectedDj} gedetecteerd maar heeft geen account.");
|
|
|
|
return;
|
|
}
|
|
|
|
$currentDjId = $this->getSetting('radio_current_dj_id', '');
|
|
|
|
if ($currentDjId === (string) $djUser->id) {
|
|
$this->info("DJ is al actief: {$detectedDj}");
|
|
|
|
return;
|
|
}
|
|
|
|
WebsiteSetting::updateOrCreate(
|
|
['key' => 'radio_current_dj_id'],
|
|
['value' => (string) $djUser->id],
|
|
);
|
|
|
|
Cache::forget(self::CACHE_KEY);
|
|
|
|
$this->info("DJ gedetecteerd: {$detectedDj}");
|
|
$this->info('DJ ingesteld als actieve presentator.');
|
|
}
|
|
}
|