diff --git a/.dockerignore b/.dockerignore index d89ac53be..1a8d61ec4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,7 +16,6 @@ _ide_helper.php .env.backup .phpstorm.meta.php .phpunit.result.cache -config.yml auth.json docker-compose.yml Homestead.json diff --git a/.gitignore b/.gitignore index 554ebe677..f185879f4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ /public/storage /storage/*.key /vendor -config.yml + .env .env.backup .phpunit.result.cache diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php index cdad6ebb5..2932c8632 100644 --- a/.phpstorm.meta.php +++ b/.phpstorm.meta.php @@ -11,6 +11,8 @@ */ override(new \Illuminate\Contracts\Container\Container, map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -148,6 +150,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -198,6 +204,8 @@ ])); override(\Illuminate\Container\Container::makeWith(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -335,6 +343,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -385,6 +397,8 @@ ])); override(\Illuminate\Contracts\Container\Container::get(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -522,6 +536,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -572,6 +590,8 @@ ])); override(\Illuminate\Contracts\Container\Container::make(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -709,6 +729,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -759,6 +783,8 @@ ])); override(\Illuminate\Contracts\Container\Container::makeWith(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -896,6 +922,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -946,6 +976,8 @@ ])); override(\App::get(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -1083,6 +1115,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -1133,6 +1169,8 @@ ])); override(\App::make(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -1270,6 +1308,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -1320,6 +1362,8 @@ ])); override(\App::makeWith(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -1457,6 +1501,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -1507,6 +1555,8 @@ ])); override(\app(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -1644,6 +1694,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -1694,6 +1748,8 @@ ])); override(\resolve(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -1831,6 +1887,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, @@ -1881,6 +1941,8 @@ ])); override(\Psr\Container\ContainerInterface::get(0), map([ '' => '@', + 'App\Settings\GeneralSettings' => \App\Settings\GeneralSettings::class, + 'App\Settings\InfluxDbSettings' => \App\Settings\InfluxDbSettings::class, 'BladeUI\Icons\Factory' => \BladeUI\Icons\Factory::class, 'BladeUI\Icons\IconsManifest' => \BladeUI\Icons\IconsManifest::class, 'Filament\Http\Responses\Auth\Contracts\LoginResponse' => \Filament\Http\Responses\Auth\LoginResponse::class, @@ -2018,6 +2080,10 @@ 'Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder' => \Spatie\LaravelIgnition\Recorders\LogRecorder\LogRecorder::class, 'Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder' => \Spatie\LaravelIgnition\Recorders\QueryRecorder\QueryRecorder::class, 'Spatie\LaravelIgnition\Support\SentReports' => \Spatie\LaravelIgnition\Support\SentReports::class, + 'Spatie\LaravelSettings\SettingsCache' => \Spatie\LaravelSettings\SettingsCache::class, + 'Spatie\LaravelSettings\SettingsMapper' => \Spatie\LaravelSettings\SettingsMapper::class, + 'Spatie\LaravelSettings\SettingsRepositories\SettingsRepository' => \Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'Squire\RepositoryManager' => \Squire\RepositoryManager::class, 'Whoops\Handler\HandlerInterface' => \Spatie\LaravelIgnition\Renderers\IgnitionWhoopsHandler::class, 'auth' => \Illuminate\Auth\AuthManager::class, 'auth.password' => \Illuminate\Auth\Passwords\PasswordBrokerManager::class, diff --git a/app/Console/Commands/TestInfluxDB.php b/app/Console/Commands/TestInfluxDB.php index f89bbd06f..752a16b37 100644 --- a/app/Console/Commands/TestInfluxDB.php +++ b/app/Console/Commands/TestInfluxDB.php @@ -3,9 +3,8 @@ namespace App\Console\Commands; use App\Models\Result; +use App\Settings\InfluxDbSettings; use Illuminate\Console\Command; -use Illuminate\Support\Facades\File; -use Symfony\Component\Yaml\Yaml; class TestInfluxDB extends Command { @@ -28,19 +27,15 @@ class TestInfluxDB extends Command * * @return int */ - public function handle() + public function handle(InfluxDbSettings $settings) { - if (File::exists(base_path().'/config.yml')) { - $config = Yaml::parseFile( - base_path().'/config.yml' - ); - } - - if (File::exists('/app/config.yml')) { - $config = Yaml::parseFile('/app/config.yml'); - } - - $influxdb = $config['influxdb']; + $influxdb = [ + 'enabled' => $settings->v2_enabled, + 'url' => optional($settings)->v2_url, + 'org' => optional($settings)->v2_org, + 'bucket' => optional($settings)->v2_bucket, + 'token' => optional($settings)->v2_token, + ]; if ($influxdb['enabled'] == true) { $result = Result::factory()->create(); diff --git a/app/Filament/Pages/Dashboard.php b/app/Filament/Pages/Dashboard.php index 5051f8dcb..29a71ccd0 100644 --- a/app/Filament/Pages/Dashboard.php +++ b/app/Filament/Pages/Dashboard.php @@ -4,6 +4,7 @@ use App\Filament\Widgets\StatsOverview; use App\Jobs\ExecSpeedtest; +use App\Settings\GeneralSettings; use Filament\Notifications\Notification; use Filament\Pages\Actions\Action; use Filament\Pages\Dashboard as BasePage; @@ -28,9 +29,15 @@ public function getHeaderWidgets(): array ]; } - public function queueSpeedtest() + public function queueSpeedtest(GeneralSettings $settings) { - ExecSpeedtest::dispatch(); + $speedtest = [ + 'enabled' => ! blank($settings->speedtest_schedule), + 'schedule' => optional($settings)->speedtest_schedule, + 'ookla_server_id' => optional($settings)->speedtest_server, + ]; + + ExecSpeedtest::dispatch(speedtest: $speedtest, scheduled: false); Notification::make() ->title('Speedtest added to the queue') diff --git a/app/Filament/Pages/Settings/General.php b/app/Filament/Pages/Settings/General.php new file mode 100644 index 000000000..5247d155f --- /dev/null +++ b/app/Filament/Pages/Settings/General.php @@ -0,0 +1,89 @@ + 1, + 'md' => 3, + ]) + ->schema([ + Grid::make([ + 'default' => 1, + ]) + ->schema([ + Section::make('Site Settings') + ->collapsible() + ->schema([ + TextInput::make('site_name') + ->maxLength(50) + ->required() + ->columnSpan(['md' => 2]), + Select::make('timezone') + ->options(Timezone::all()->pluck('code', 'code')) + ->searchable() + ->required() + ->columnSpan(1), + ]) + ->columns([ + 'default' => 1, + 'md' => 2, + ]), + + Section::make('Speedtest Settings') + ->collapsible() + ->schema([ + TextInput::make('speedtest_schedule') + ->helperText('Leave empty to disable the schedule. You can also use the cron expression generator [HERE](https://crontab.cronhub.io/) to help you make schedules.') + ->nullable() + ->columnSpan(1), + TextInput::make('speedtest_server') + ->helperText('Leave empty to let the system pick the best server.') + ->nullable() + ->columnSpan(1), + ]) + ->columns([ + 'default' => 1, + 'md' => 2, + ]), + ]) + ->columnSpan([ + 'md' => 2, + ]), + + Card::make() + ->schema([ + Toggle::make('auth_enabled') + ->label('Authentication enabled') + ->helperText("NOTE: Authentication is currently required. It's on the roadmap to be able to disabled it though.") + ->disabled(), + ]) + ->columnSpan([ + 'md' => 1, + ]), + ]), + ]; + } +} diff --git a/app/Filament/Pages/Settings/InfluxDb.php b/app/Filament/Pages/Settings/InfluxDb.php new file mode 100644 index 000000000..e0dddd097 --- /dev/null +++ b/app/Filament/Pages/Settings/InfluxDb.php @@ -0,0 +1,82 @@ + 1, + 'md' => 3, + ]) + ->schema([ + Grid::make([ + 'default' => 1, + ]) + ->schema([ + Section::make('InfluxDB v2 Settings') + ->collapsible() + ->schema([ + TextInput::make('v2_url') + ->label('URL') + ->placeholder('http://your-influxdb-instance') + ->maxLength(255) + ->columnSpan(['md' => 2]), + TextInput::make('v2_org') + ->label('Org') + ->maxLength(255) + ->columnSpan(1), + TextInput::make('v2_bucket') + ->placeholder('speedtest-tracker') + ->label('Bucket') + ->maxLength(255) + ->columnSpan(1), + TextInput::make('v2_token') + ->label('Token') + ->maxLength(255) + ->password() + ->disableAutocomplete() + ->columnSpan(['md' => 2]), + ]) + ->columns([ + 'default' => 1, + 'md' => 2, + ]), + ]) + ->columnSpan([ + 'md' => 2, + ]), + + Card::make() + ->schema([ + Toggle::make('v2_enabled') + ->label('v2 enabled') + ->helperText('NOTE: At this time only InfluxDB v2 is supported'), + ]) + ->columnSpan([ + 'md' => 1, + ]), + ]), + ]; + } +} diff --git a/app/Jobs/SearchForSpeedtests.php b/app/Jobs/SearchForSpeedtests.php index 1a99da0b9..eccbf2757 100644 --- a/app/Jobs/SearchForSpeedtests.php +++ b/app/Jobs/SearchForSpeedtests.php @@ -2,52 +2,37 @@ namespace App\Jobs; +use App\Settings\GeneralSettings; use Cron\CronExpression; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\File; -use Symfony\Component\Yaml\Yaml; class SearchForSpeedtests implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - /** - * Create a new job instance. - * - * @return void - */ - public function __construct() - { - // - } - /** * Execute the job. * * @return void */ - public function handle() + public function handle(GeneralSettings $settings) { - if (File::exists(base_path().'/config.yml')) { - $config = Yaml::parseFile( - base_path().'/config.yml' - ); - } - - if (File::exists('/app/config.yml')) { - $config = Yaml::parseFile('/app/config.yml'); - } - - $speedtest = $config['speedtest']; - - $cron = new CronExpression($speedtest['schedule']); - - if ($cron->isDue() && $speedtest['enabled']) { - ExecSpeedtest::dispatch(speedtest: $speedtest, scheduled: true); + $speedtest = [ + 'enabled' => ! blank($settings->speedtest_schedule), + 'schedule' => optional($settings)->speedtest_schedule, + 'ookla_server_id' => optional($settings)->speedtest_server, + ]; + + if ($speedtest['enabled']) { + $cron = new CronExpression($speedtest['schedule']); + + if ($cron->isDue()) { + ExecSpeedtest::dispatch(speedtest: $speedtest, scheduled: true); + } } } } diff --git a/app/Observers/ResultObserver.php b/app/Observers/ResultObserver.php index 0089a3182..c00c95e6a 100644 --- a/app/Observers/ResultObserver.php +++ b/app/Observers/ResultObserver.php @@ -3,10 +3,9 @@ namespace App\Observers; use App\Models\Result; -use Illuminate\Support\Facades\File; +use App\Settings\InfluxDbSettings; use Illuminate\Support\Facades\Log; use InfluxDB2\Client; -use Symfony\Component\Yaml\Yaml; class ResultObserver { @@ -17,6 +16,13 @@ class ResultObserver */ public $afterCommit = true; + public $settings; + + public function __construct(InfluxDbSettings $settings) + { + $this->settings = $settings; + } + /** * Handle the Result "created" event. * @@ -25,17 +31,13 @@ class ResultObserver */ public function created(Result $result) { - if (File::exists(base_path().'/config.yml')) { - $config = Yaml::parseFile( - base_path().'/config.yml' - ); - } - - if (File::exists('/app/config.yml')) { - $config = Yaml::parseFile('/app/config.yml'); - } - - $influxdb = $config['influxdb']; + $influxdb = [ + 'enabled' => $this->settings->v2_enabled, + 'url' => optional($this->settings)->v2_url, + 'org' => optional($this->settings)->v2_org, + 'bucket' => optional($this->settings)->v2_bucket, + 'token' => optional($this->settings)->v2_token, + ]; if ($influxdb['enabled'] == true) { $client = new Client([ diff --git a/app/Providers/FilamentServiceProvider.php b/app/Providers/FilamentServiceProvider.php index 83fd0fe49..ca37a3c7f 100644 --- a/app/Providers/FilamentServiceProvider.php +++ b/app/Providers/FilamentServiceProvider.php @@ -27,6 +27,7 @@ public function boot() { Filament::serving(function () { Filament::registerNavigationGroups([ + 'Settings', 'Links', ]); diff --git a/app/Settings/GeneralSettings.php b/app/Settings/GeneralSettings.php new file mode 100644 index 000000000..191f6deba --- /dev/null +++ b/app/Settings/GeneralSettings.php @@ -0,0 +1,23 @@ +=8.1", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<5.4" - }, - "require-dev": { - "symfony/console": "^5.4|^6.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v6.1.6" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-10-07T08:04:03+00:00" - }, { "name": "tgalopin/html-sanitizer", "version": "1.5.0", @@ -7872,114 +8425,6 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, { "name": "phpunit/php-code-coverage", "version": "9.2.17", diff --git a/config.example.yml b/config.example.yml deleted file mode 100644 index 4a35b5305..000000000 --- a/config.example.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -authentication: true -influxdb: - enabled: false - version: 2 # Only InfluxDB2 is supported right now - url: 'http://your-influxdb-instance' # Full url to your InfluxDB instance, sometimes this includes a port number - org: '' # Organization name, usually created when you installed InfluxDB - bucket: 'speedtest-tracker' # A name location to store the speedtest data in - token: '' # This is your API token -notifications: - channels: - discord: - webhook_url: null # Set as null to disable - slack: - webhook_url: null # Set as null to disable -speedtest: - enabled: true - schedule: '*/60 * * * *' # every hour - ookla_server_id: null # specify a server ID to use a specific server -tz: 'UTC' diff --git a/config/settings.php b/config/settings.php new file mode 100644 index 000000000..89cb1e076 --- /dev/null +++ b/config/settings.php @@ -0,0 +1,80 @@ + [ + + ], + + /* + * In these directories settings migrations will be stored and ran when migrating. A settings + * migration created via the make:settings-migration command will be stored in the first path or + * a custom defined path when running the command. + */ + 'migrations_paths' => [ + database_path('settings'), + ], + + /* + * When no repository was set for a settings class the following repository + * will be used for loading and saving settings. + */ + 'default_repository' => 'database', + + /* + * Settings will be stored and loaded from these repositories. + */ + 'repositories' => [ + 'database' => [ + 'type' => Spatie\LaravelSettings\SettingsRepositories\DatabaseSettingsRepository::class, + 'model' => null, + 'table' => null, + 'connection' => null, + ], + 'redis' => [ + 'type' => Spatie\LaravelSettings\SettingsRepositories\RedisSettingsRepository::class, + 'connection' => null, + 'prefix' => null, + ], + ], + + /* + * The contents of settings classes can be cached through your application, + * settings will be stored within a provided Laravel store and can have an + * additional prefix. + */ + 'cache' => [ + 'enabled' => env('SETTINGS_CACHE_ENABLED', false), + 'store' => null, + 'prefix' => null, + 'ttl' => null, + ], + + /* + * These global casts will be automatically used whenever a property within + * your settings class isn't a default PHP type. + */ + 'global_casts' => [ + DateTimeInterface::class => Spatie\LaravelSettings\SettingsCasts\DateTimeInterfaceCast::class, + DateTimeZone::class => Spatie\LaravelSettings\SettingsCasts\DateTimeZoneCast::class, + Spatie\DataTransferObject\DataTransferObject::class => Spatie\LaravelSettings\SettingsCasts\DtoCast::class, + ], + + /* + * The package will look for settings in these paths and automatically + * register them. + */ + 'auto_discover_settings' => [ + app()->path(), + ], + + /* + * Automatically discovered settings classes can be cached so they don't + * need to be searched each time the application boots up. + */ + 'discovered_settings_cache_path' => storage_path('app/laravel-settings'), +]; diff --git a/database/migrations/2022_10_21_104903_create_settings_table.php b/database/migrations/2022_10_21_104903_create_settings_table.php new file mode 100644 index 000000000..d420e1eaa --- /dev/null +++ b/database/migrations/2022_10_21_104903_create_settings_table.php @@ -0,0 +1,27 @@ +id(); + + $table->string('group')->index(); + $table->string('name'); + $table->boolean('locked'); + $table->json('payload'); + + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('settings'); + } +} diff --git a/database/settings/2022_10_21_105703_create_general_settings.php b/database/settings/2022_10_21_105703_create_general_settings.php new file mode 100644 index 000000000..eeda81475 --- /dev/null +++ b/database/settings/2022_10_21_105703_create_general_settings.php @@ -0,0 +1,15 @@ +migrator->add('general.auth_enabled', true); + $this->migrator->add('general.site_name', 'Speedtest Tracker'); + $this->migrator->add('general.speedtest_schedule', '0 * * * *'); // every hour + $this->migrator->add('general.speedtest_server', null); + $this->migrator->add('general.timezone', 'UTC'); + } +} diff --git a/database/settings/2022_10_21_130121_create_influxdb_settings.php b/database/settings/2022_10_21_130121_create_influxdb_settings.php new file mode 100644 index 000000000..75b6aa89b --- /dev/null +++ b/database/settings/2022_10_21_130121_create_influxdb_settings.php @@ -0,0 +1,15 @@ +migrator->add('influxdb.v2_enabled', false); + $this->migrator->add('influxdb.v2_url', null); + $this->migrator->add('influxdb.v2_org', null); + $this->migrator->add('influxdb.v2_bucket', 'speedtest-tracker'); + $this->migrator->add('influxdb.v2_token', null); + } +} diff --git a/docker/deploy/etc/s6-overlay/scripts/startup b/docker/deploy/etc/s6-overlay/scripts/startup index 630c96d12..b1f61901a 100644 --- a/docker/deploy/etc/s6-overlay/scripts/startup +++ b/docker/deploy/etc/s6-overlay/scripts/startup @@ -39,19 +39,10 @@ else echo "✅ Environment file exists" fi -# Check for config file -if [ ! -f /config/config.yml ]; then - echo "🙄 Config file not found, creating..." - cp $WEBUSER_HOME/config.example.yml /config/config.yml -else - echo "✅ Environment file exists" -fi - # create symlinks echo "🔗 Creating symlinks to config and log files" symlinks=( \ /var/www/html/.env \ -/var/www/html/config.yml \ /var/www/html/storage/logs/laravel.log )