mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
Add update lookup and telemetry, Add version and build to app config
This commit is contained in:
committed by
Gregor Vostrak
parent
f147fb9725
commit
2372ee0622
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands\SelfHost;
|
||||
|
||||
use App\Service\ApiService;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class SelfHostCheckForUpdateCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'self-host:check-for-update';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$apiService = app(ApiService::class);
|
||||
|
||||
$latestVersion = $apiService->checkForUpdate();
|
||||
if ($latestVersion === null) {
|
||||
$this->error('Failed to check for update, check the logs for more information.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
// Note: Cache for 13 hours, because the command runs twice daily (every 12 hours).
|
||||
Cache::put('latest_version', $latestVersion, 60 * 60 * 12);
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
44
app/Console/Commands/SelfHost/SelfHostTelemetryCommand.php
Normal file
44
app/Console/Commands/SelfHost/SelfHostTelemetryCommand.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands\SelfHost;
|
||||
|
||||
use App\Service\ApiService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SelfHostTelemetryCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'self-host:telemetry';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$apiService = app(ApiService::class);
|
||||
|
||||
$success = $apiService->telemetry();
|
||||
|
||||
if (! $success) {
|
||||
$this->error('Failed to send telemetry data, check the logs for more information.');
|
||||
|
||||
return self::FAILURE;
|
||||
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,14 @@ class Kernel extends ConsoleKernel
|
||||
$schedule->command('time-entry:send-still-running-mails')
|
||||
->when(fn (): bool => config('scheduling.tasks.time_entry_send_still_running_mails'))
|
||||
->everyTenMinutes();
|
||||
|
||||
$schedule->command('self-hosting:check-for-update')
|
||||
->when(fn (): bool => config('scheduling.tasks.self_hosting_check_for_update'))
|
||||
->twiceDaily();
|
||||
|
||||
$schedule->command('self-hosting:telemetry')
|
||||
->when(fn (): bool => config('scheduling.tasks.self_hosting_telemetry'))
|
||||
->twiceDaily();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
34
app/Filament/Widgets/ServerOverview.php
Normal file
34
app/Filament/Widgets/ServerOverview.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use Filament\Widgets\Widget;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ServerOverview extends Widget
|
||||
{
|
||||
protected static string $view = 'filament.widgets.server-overview';
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function getViewData(): array
|
||||
{
|
||||
$currentVersion = Cache::get('latest_version', null);
|
||||
|
||||
$needsUpdate = false;
|
||||
if ($currentVersion !== null && version_compare($currentVersion, config('app.version')) > 0) {
|
||||
$needsUpdate = true;
|
||||
}
|
||||
|
||||
return [
|
||||
'version' => config('app.version'),
|
||||
'build' => config('app.build'),
|
||||
'environment' => config('app.env'),
|
||||
'currentVersion' => $currentVersion,
|
||||
'needsUpdate' => $needsUpdate,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Providers\Filament;
|
||||
|
||||
use App\Filament\Widgets\ActiveUserOverview;
|
||||
use App\Filament\Widgets\ServerOverview;
|
||||
use App\Filament\Widgets\TimeEntriesCreated;
|
||||
use App\Filament\Widgets\TimeEntriesImported;
|
||||
use App\Filament\Widgets\UserRegistrations;
|
||||
@@ -44,11 +45,13 @@ class AdminPanelProvider extends PanelProvider
|
||||
])
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
|
||||
->widgets([
|
||||
ServerOverview::class,
|
||||
ActiveUserOverview::class,
|
||||
UserRegistrations::class,
|
||||
TimeEntriesCreated::class,
|
||||
TimeEntriesImported::class,
|
||||
])
|
||||
->viteTheme('resources/css/filament/admin/theme.css')
|
||||
->plugins([
|
||||
EnvironmentIndicatorPlugin::make()
|
||||
->color(fn () => match (App::environment()) {
|
||||
|
||||
93
app/Service/ApiService.php
Normal file
93
app/Service/ApiService.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Models\Audit;
|
||||
use App\Models\Client;
|
||||
use App\Models\Organization;
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectMember;
|
||||
use App\Models\Task;
|
||||
use App\Models\TimeEntry;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Log;
|
||||
|
||||
class ApiService
|
||||
{
|
||||
private const string API_URL = 'https://app.solidtime.io/api';
|
||||
|
||||
public function checkForUpdate(): ?string
|
||||
{
|
||||
try {
|
||||
$response = Http::asJson()
|
||||
->timeout(3)
|
||||
->connectTimeout(2)
|
||||
->post(self::API_URL.'/check-for-update', [
|
||||
'version' => config('app.version'),
|
||||
'build' => config('app.build'),
|
||||
'url' => config('app.url'),
|
||||
]);
|
||||
|
||||
if ($response->status() === 200 && isset($response->json()['version']) && is_string($response->json()['version'])) {
|
||||
return $response->json()['version'];
|
||||
} else {
|
||||
Log::warning('Failed to check for update', [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body(),
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('Failed to check for update', [
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function telemetry(): bool
|
||||
{
|
||||
try {
|
||||
$response = Http::asJson()
|
||||
->timeout(3)
|
||||
->connectTimeout(2)
|
||||
->post(self::API_URL.'/telemetry', [
|
||||
'version' => config('app.version'),
|
||||
'build' => config('app.build'),
|
||||
'url' => config('app.url'),
|
||||
// telemetry data
|
||||
'user_count' => User::count(),
|
||||
'organization_count' => Organization::count(),
|
||||
'audit_count' => Audit::count(),
|
||||
'project_count' => Project::count(),
|
||||
'project_member_count' => ProjectMember::count(),
|
||||
'client_count' => Client::count(),
|
||||
'task_count' => Task::count(),
|
||||
'time_entry_count' => TimeEntry::count(),
|
||||
]);
|
||||
|
||||
if ($response->status() === 200) {
|
||||
return true;
|
||||
} else {
|
||||
Log::warning('Failed send telemetry data', [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body(),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::warning('Failed send telemetry data', [
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user