Skip to content

Commit dd87160

Browse files
Merge pull request #521 from henrywhitaker3/alpha
Bunch of updates
2 parents 99d80ed + b82b7c6 commit dd87160

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+28318
-1952
lines changed

.github/workflows/laravel-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@ jobs:
5656
env:
5757
DB_CONNECTION: sqlite
5858
DB_DATABASE: database/database.sqlite
59-
run: vendor/bin/phpunit
59+
run: php artisan test --parallel

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Speedtest Tracker
22

3-
[![Docker pulls](https://img.shields.io/docker/pulls/henrywhitaker3/speedtest-tracker?style=flat-square)](https://hub.docker.com/r/henrywhitaker3/speedtest-tracker) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/henrywhitaker3/Speedtest-Tracker/Stable?label=master&logo=github&style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/actions) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/henrywhitaker3/Speedtest-Tracker/Dev?label=dev&logo=github&style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/actions) [![last_commit](https://img.shields.io/github/last-commit/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) [![issues](https://img.shields.io/github/issues/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/issues) [![commit_freq](https://img.shields.io/github/commit-activity/m/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) ![version](https://img.shields.io/badge/version-v1.10.4-success?style=flat-square) [![license](https://img.shields.io/github/license/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/blob/master/LICENSE)
3+
[![Docker pulls](https://img.shields.io/docker/pulls/henrywhitaker3/speedtest-tracker?style=flat-square)](https://hub.docker.com/r/henrywhitaker3/speedtest-tracker) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/henrywhitaker3/Speedtest-Tracker/Stable?label=master&logo=github&style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/actions) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/henrywhitaker3/Speedtest-Tracker/Dev?label=dev&logo=github&style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/actions) [![last_commit](https://img.shields.io/github/last-commit/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) [![issues](https://img.shields.io/github/issues/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/issues) [![commit_freq](https://img.shields.io/github/commit-activity/m/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/commits) ![version](https://img.shields.io/badge/version-v1.11.1-success?style=flat-square) [![license](https://img.shields.io/github/license/henrywhitaker3/Speedtest-Tracker?style=flat-square)](https://github.com/henrywhitaker3/Speedtest-Tracker/blob/master/LICENSE)
44

55
This program runs a speedtest check every hour and graphs the results. The back-end is written in [Laravel](https://laravel.com/) and the front-end uses [React](https://reactjs.org/). It uses the [Ookla's speedtest cli](https://www.speedtest.net/apps/cli) package to get the data and uses [Chart.js](https://www.chartjs.org/) to plot the results.
66

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace App\Actions;
4+
5+
use App\Speedtest;
6+
use Cache;
7+
use Carbon\Carbon;
8+
use DB;
9+
use Henrywhitaker3\LaravelActions\Interfaces\ActionInterface;
10+
11+
class GetFailedSpeedtestData implements ActionInterface
12+
{
13+
/**
14+
* Run the action.
15+
*
16+
* @return mixed
17+
*/
18+
public function run($days = 7)
19+
{
20+
$ttl = Carbon::now()->addDays(1);
21+
22+
return Cache::remember('failure-rate-' . $days, $ttl, function () use ($days) {
23+
$range = [
24+
Carbon::today()
25+
];
26+
for ($i = 0; $i < ($days - 1); $i++) {
27+
$prev = end($range);
28+
$new = $prev->copy()->subDays(1);
29+
array_push($range, $new);
30+
}
31+
32+
$rate = [];
33+
34+
foreach ($range as $day) {
35+
$success = Speedtest::select(DB::raw('COUNT(id) as rate'))->whereDate('created_at', $day)->where('failed', false)->get()[0]['rate'];
36+
$fail = Speedtest::select(DB::raw('COUNT(id) as rate'))->whereDate('created_at', $day)->where('failed', true)->get()[0]['rate'];
37+
38+
array_push($rate, [
39+
'date' => $day->toDateString(),
40+
'success' => $success,
41+
'failure' => $fail,
42+
]);
43+
}
44+
45+
return array_reverse($rate);
46+
});
47+
}
48+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace App\Actions;
4+
5+
use App\Helpers\SettingsHelper;
6+
use App\Helpers\SpeedtestHelper;
7+
use App\Speedtest;
8+
use DB;
9+
use Henrywhitaker3\LaravelActions\Interfaces\ActionInterface;
10+
11+
class GetLatestSpeedtestData implements ActionInterface
12+
{
13+
/**
14+
* Run the action.
15+
*
16+
* @return mixed
17+
*/
18+
public function run()
19+
{
20+
$data = SpeedtestHelper::latest();
21+
22+
$response = [
23+
'data' => $data,
24+
];
25+
26+
if (SettingsHelper::get('show_average')) {
27+
$avg = Speedtest::select(DB::raw('AVG(ping) as ping, AVG(download) as download, AVG(upload) as upload'))
28+
->where('failed', false)
29+
->first()
30+
->toArray();
31+
$response['average'] = $avg;
32+
}
33+
34+
if (SettingsHelper::get('show_max')) {
35+
$max = Speedtest::select(DB::raw('MAX(ping) as ping, MAX(download) as download, MAX(upload) as upload'))
36+
->where('failed', false)
37+
->first()
38+
->toArray();
39+
$response['maximum'] = $max;
40+
}
41+
42+
if (SettingsHelper::get('show_min')) {
43+
$min = Speedtest::select(DB::raw('MIN(ping) as ping, MIN(download) as download, MIN(upload) as upload'))
44+
->where('failed', false)
45+
->first()
46+
->toArray();
47+
$response['minimum'] = $min;
48+
}
49+
50+
return $response;
51+
}
52+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace App\Actions;
4+
5+
use App\Helpers\SettingsHelper;
6+
use App\Speedtest;
7+
use Cache;
8+
use Carbon\Carbon;
9+
use Henrywhitaker3\LaravelActions\Interfaces\ActionInterface;
10+
11+
class GetSpeedtestTimeData implements ActionInterface
12+
{
13+
/**
14+
* Run the action.
15+
*
16+
* @return mixed
17+
*/
18+
public function run($days = 7)
19+
{
20+
$ttl = Carbon::now()->addDays(1);
21+
22+
return Cache::remember('speedtest-days-' . $days, $ttl, function () use ($days) {
23+
$showFailed = (bool)SettingsHelper::get('show_failed_tests_on_graph')->value;
24+
25+
if ($showFailed === true) {
26+
return Speedtest::where('created_at', '>=', Carbon::now()->subDays($days))
27+
->orderBy('created_at', 'asc')
28+
->get();
29+
}
30+
31+
return Speedtest::where('created_at', '>=', Carbon::now()->subDays($days))
32+
->where('failed', false)
33+
->orderBy('created_at', 'asc')
34+
->get();
35+
});
36+
}
37+
}

app/Actions/QueueSpeedtest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace App\Actions;
4+
5+
use App\Helpers\SettingsHelper;
6+
use App\Interfaces\SpeedtestProvider;
7+
use App\Jobs\SpeedtestJob;
8+
use Henrywhitaker3\LaravelActions\Interfaces\ActionInterface;
9+
10+
class QueueSpeedtest implements ActionInterface
11+
{
12+
private SpeedtestProvider $speedtestProvider;
13+
14+
/**
15+
* Create a new action instance.
16+
*
17+
* @return void
18+
*/
19+
public function __construct(SpeedtestProvider $speedtestProvider)
20+
{
21+
$this->speedtestProvider = $speedtestProvider;
22+
}
23+
24+
/**
25+
* Run the action.
26+
*
27+
* @return mixed
28+
*/
29+
public function run()
30+
{
31+
SettingsHelper::loadIntegrationConfig();
32+
33+
SpeedtestJob::dispatch(false, config('integrations'), $this->speedtestProvider);
34+
}
35+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace App\Casts;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
7+
class CommaSeparatedArrayCast implements CastsAttributes
8+
{
9+
/**
10+
* Array of settings that should be cast
11+
*/
12+
private array $shouldCast = [
13+
'visible_columns',
14+
'hidden_columns',
15+
];
16+
17+
/**
18+
* Cast the given value.
19+
*
20+
* @param \Illuminate\Database\Eloquent\Model $model
21+
* @param string $key
22+
* @param mixed $value
23+
* @param array $attributes
24+
* @return mixed
25+
*/
26+
public function get($model, $key, $value, $attributes)
27+
{
28+
if (!in_array($model->name, $this->shouldCast)) {
29+
return $value;
30+
}
31+
32+
return explode(',', $value);
33+
}
34+
35+
/**
36+
* Prepare the given value for storage.
37+
*
38+
* @param \Illuminate\Database\Eloquent\Model $model
39+
* @param string $key
40+
* @param mixed $value
41+
* @param array $attributes
42+
* @return mixed
43+
*/
44+
public function set($model, $key, $value, $attributes)
45+
{
46+
if (!in_array($model->name, $this->shouldCast)) {
47+
return $value;
48+
}
49+
50+
return implode(',', $value);
51+
}
52+
}

app/Console/Commands/AcceptEULACommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function __construct()
3838
*/
3939
public function handle()
4040
{
41-
shell_exec(config('speedtest.home') . ' && ' . app_path() . '/Bin/speedtest --accept-license --accept-gdpr');
41+
$this->info('Acceping EULA');
42+
shell_exec(config('speedtest.home') . ' && timeout 3s ' . app_path() . '/Bin/speedtest --accept-license --accept-gdpr');
4243
}
4344
}

app/Console/Commands/SpeedtestCommand.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Console\Commands;
44

55
use App\Helpers\SpeedtestHelper;
6+
use App\Interfaces\SpeedtestProvider;
67
use Illuminate\Console\Command;
78

89
class SpeedtestCommand extends Command
@@ -21,13 +22,17 @@ class SpeedtestCommand extends Command
2122
*/
2223
protected $description = 'Performs a new speedtest';
2324

25+
private SpeedtestProvider $speedtestProvider;
26+
2427
/**
2528
* Create a new command instance.
2629
*
2730
* @return void
2831
*/
29-
public function __construct()
32+
public function __construct(SpeedtestProvider $speedtestProvider)
3033
{
34+
$this->speedtestProvider = $speedtestProvider;
35+
3136
parent::__construct();
3237
}
3338

@@ -40,14 +45,14 @@ public function handle()
4045
{
4146
$this->info('Running speedtest, this might take a while...');
4247

43-
$results = SpeedtestHelper::runSpeedtest(false, false);
48+
$results = $this->speedtestProvider->run(false, false);
4449

45-
if(!is_object($results)) {
50+
if (!is_object($results)) {
4651
$this->error('Something went wrong running the speedtest.');
4752
exit();
4853
}
4954

50-
if(property_exists($results, 'ping') && property_exists($results, 'download') && property_exists($results, 'upload')) {
55+
if (property_exists($results, 'ping') && property_exists($results, 'download') && property_exists($results, 'upload')) {
5156
$this->error('Something went wrong running the speedtest.');
5257
exit();
5358
}

app/Console/Commands/SpeedtestLatestCommand.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Console\Commands;
44

55
use App\Helpers\SpeedtestHelper;
6+
use App\Interfaces\SpeedtestProvider;
67
use Illuminate\Console\Command;
78
use Illuminate\Support\Facades\Artisan;
89

@@ -22,13 +23,17 @@ class SpeedtestLatestCommand extends Command
2223
*/
2324
protected $description = 'Returns the latest speedtest result';
2425

26+
private SpeedtestProvider $speedtestProvider;
27+
2528
/**
2629
* Create a new command instance.
2730
*
2831
* @return void
2932
*/
30-
public function __construct()
33+
public function __construct(SpeedtestProvider $speedtestProvider)
3134
{
35+
$this->speedtestProvider = $speedtestProvider;
36+
3237
parent::__construct();
3338
}
3439

@@ -41,16 +46,16 @@ public function handle()
4146
{
4247
$latest = SpeedtestHelper::latest();
4348

44-
if($latest) {
45-
if($latest->scheduled) {
49+
if ($latest) {
50+
if ($latest->scheduled) {
4651
$extra = '(scheduled)';
4752
} else {
4853
$extra = '(manual)';
4954
}
5055

5156
$this->info('Last speedtest run at: ' . $latest->created_at . ' ' . $extra);
5257

53-
if($latest->failed) {
58+
if ($latest->failed) {
5459
$this->error('Speedtest failed');
5560
} else {
5661
$this->info('Ping: ' . $latest->ping . ' ms');
@@ -62,7 +67,7 @@ public function handle()
6267

6368
$this->info('Running speedtest, this might take a while...');
6469

65-
$results = SpeedtestHelper::runSpeedtest();
70+
$results = $this->speedtestProvider->run();
6671

6772
$this->info('Ping: ' . $results->ping . ' ms');
6873
$this->info('Download: ' . $results->download . ' Mbit/s');

0 commit comments

Comments
 (0)