From 7d7210424f6732a01fb55196a2282f84be4b1125 Mon Sep 17 00:00:00 2001 From: Erik Yeoh Date: Wed, 17 Jun 2020 16:47:54 +0800 Subject: [PATCH 1/4] :sparkles: Health Checks for Links --- app/Console/Commands/LinkHealthChecks.php | 54 ++++++++ app/Console/Kernel.php | 14 ++ .../Controllers/Manage/LinksController.php | 51 ++++++++ app/Services/HealthCheckStats.php | 64 +++++++++ composer.json | 1 + composer.lock | 123 +++++++++++++++++- config/shaark.php | 8 ++ database/factories/LinkFactory.php | 16 +++ ...60000_add_health_checks_to_links_table.php | 38 ++++++ database/seeds/LinkSeeder.php | 16 +++ resources/lang/en/shaark.php | 8 +- resources/lang/ja.json | 16 ++- resources/lang/ja/shaark.php | 8 +- resources/views/layouts/manage.blade.php | 3 + resources/views/manage/links.blade.php | 70 ++++++++++ resources/views/manage/links_dead.blade.php | 46 +++++++ resources/views/manage/links_other.blade.php | 46 +++++++ resources/views/manage/settings.blade.php | 24 ++++ routes/web.php | 5 + 19 files changed, 606 insertions(+), 5 deletions(-) create mode 100644 app/Console/Commands/LinkHealthChecks.php create mode 100644 app/Http/Controllers/Manage/LinksController.php create mode 100644 app/Services/HealthCheckStats.php create mode 100644 database/migrations/2020_06_17_060000_add_health_checks_to_links_table.php create mode 100644 database/seeds/LinkSeeder.php create mode 100644 resources/views/manage/links.blade.php create mode 100644 resources/views/manage/links_dead.blade.php create mode 100644 resources/views/manage/links_other.blade.php diff --git a/app/Console/Commands/LinkHealthChecks.php b/app/Console/Commands/LinkHealthChecks.php new file mode 100644 index 0000000..c43e4bb --- /dev/null +++ b/app/Console/Commands/LinkHealthChecks.php @@ -0,0 +1,54 @@ +option('all'); + + $links = Link::where('http_checked_at', '<', now()->subDays(app(Shaark::class)->getLinkHealthChecksAge())) + ->orWhereNull('http_checked_at') + ->orderBy('http_checked_at', 'ASC'); + + if (! $check_all_links) { + $links->limit(20); + } + + $links->get() + ->each(function (Link $link) { + try { + $response = (new Client())->request('GET', $link->getUrlAttribute(), [ + 'headers' => [ + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36', + ], + 'http_errors' => false, + 'timeout' => 5, + ]); + + $link->http_status = $response->getStatusCode(); + } catch (RequestException $exception) { + // Might happen when the domain as expired + $link->http_status = 500; + } finally { + $link->http_checked_at = now(); + $link->save(); + } + }); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 7c18a95..c445922 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -30,6 +30,9 @@ protected function schedule(Schedule $schedule) // Make backup $this->scheduleBackup($schedule); + + // Link health checks + $this->scheduleLinkHealthChecks($schedule); } protected function scheduleBackup(Schedule $schedule): self @@ -54,4 +57,15 @@ protected function scheduleBackup(Schedule $schedule): self return $this; } + + protected function scheduleLinkHealthChecks(Schedule $schedule): self + { + $shaark = app(Shaark::class); + + if (false === $shaark->getLinkHealthChecksEnabled()) { + return $this; + } + + $schedule->command('shaark:link_health_check')->everyTenMinutes(); + } } diff --git a/app/Http/Controllers/Manage/LinksController.php b/app/Http/Controllers/Manage/LinksController.php new file mode 100644 index 0000000..bf2e937 --- /dev/null +++ b/app/Http/Controllers/Manage/LinksController.php @@ -0,0 +1,51 @@ +middleware('auth'); + + $this->middleware('demo')->except('view'); + } + + public function view() + { + $stats = new HealthCheckStats(); + + return view('manage.links')->with([ + 'page_title' => __('Links'), + 'num_total' => $stats->countTotal(), + 'health_checks_enabled' => app(Shaark::class)->getLinkHealthChecksEnabled(), + 'num_pending' => $stats->countPending(), + 'num_healthy' => $stats->countHealthy(), + 'num_other' => $stats->countOther(), + 'num_dead' => $stats->countDead(), + ]); + } + + public function viewDead() + { + return view('manage.links_dead')->with([ + 'page_title' => __('Dead Links'), + 'dead_links' => Link::whereBetween('http_status', [400, 499])->orderBy('http_checked_at', 'DESC')->paginate(10), + ]); + } + + public function viewOther() + { + return view('manage.links_other')->with([ + 'page_title' => __('Other Status Links'), + 'other_links' => Link::whereBetween('http_status', [300, 399]) + ->orWhereBetween('http_status', [500, 599]) + ->orderBy('http_checked_at', 'DESC')->paginate(10), + ]); + } +} diff --git a/app/Services/HealthCheckStats.php b/app/Services/HealthCheckStats.php new file mode 100644 index 0000000..88aedc4 --- /dev/null +++ b/app/Services/HealthCheckStats.php @@ -0,0 +1,64 @@ +stats = \DB::table('links') + ->select('http_status', \DB::raw('count(id) as num_count')) + ->groupBy('http_status') + ->get(); + } + + public function get() + { + return [ + 'num_healthy' => $this->countHealthy(), + 'num_other' => $this->countOther(), + 'num_dead' => $this->countDead(), + 'num_pending' => $this->countPending(), + ]; + } + + public function countTotal() + { + return $this->stats->sum('num_count'); + } + + public function countHealthy() + { + return $this->stats->where('http_status', 200)->sum('num_count'); + } + + public function countOther() + { + $redirects = $this->stats->whereBetween('http_status', [300, 399]) + ->sum('num_count'); + + $server_errors = $this->stats->whereBetween('http_status', [500, 599]) + ->sum('num_count'); + + return $redirects + $server_errors; + } + + public function countDead() + { + return $this->stats->whereBetween('http_status', [400, 499]) + ->sum('num_count'); + } + + public function countPending() + { + return \DB::table('links') + ->where('http_checked_at', '<', now()->subDays(app(Shaark::class)->getLinkHealthChecksAge())) + ->orWhereNull('http_checked_at') + ->count(); + } +} diff --git a/composer.json b/composer.json index 8aac0de..9975351 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "php": "^7.2", "doctrine/dbal": "^2.9", "fideloper/proxy": "^4.0", + "guzzlehttp/guzzle": "^6.5", "hashids/hashids": "^2.0.4|~3.0", "lab404/laravel-auth-checker": "^1.4", "laravel/framework": "^6.0", diff --git a/composer.lock b/composer.lock index 3140db5..24a15e9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6a1c0803587a9053ccab074ee0d36977", + "content-hash": "5f8b851e33ca8323793fce95286f8db4", "packages": [ { "name": "clue/socket-raw", @@ -689,6 +689,124 @@ ], "time": "2019-12-12T13:22:17+00:00" }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.11" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-04-18T10:38:46+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, { "name": "guzzlehttp/psr7", "version": "1.6.1", @@ -7594,5 +7712,6 @@ "platform": { "php": "^7.2" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/config/shaark.php b/config/shaark.php index 1087106..3c99cbd 100644 --- a/config/shaark.php +++ b/config/shaark.php @@ -142,5 +142,13 @@ 'default' => 'whitelist', 'rules' => ['nullable', 'in:disabled,whitelist,all'] ], + 'link_health_checks_enabled' => [ + 'default' => false, + 'rules' => ['nullable', 'in:on,off'] + ], + 'link_health_checks_age' => [ + 'default' => '7', + 'rules' => ['required', 'numeric', 'min:7', 'max:365'] + ], ], ]; diff --git a/database/factories/LinkFactory.php b/database/factories/LinkFactory.php index b61347f..3b6869b 100644 --- a/database/factories/LinkFactory.php +++ b/database/factories/LinkFactory.php @@ -5,9 +5,25 @@ use Faker\Generator as Faker; $factory->define(Link::class, function (Faker $faker) { + $http_status_codes = [ + null, + 200, + 302, + 404, + 500, + ]; + + $http_status_code = $http_status_codes[rand(0, 4)]; + $http_checked_at = null; + if (! is_null($http_status_code)) { + $http_checked_at = $faker->dateTimeThisMonth; + } + return [ 'title' => $faker->sentence, 'content' => $faker->paragraph, 'url' => $faker->url, + 'http_status' => $http_status_code, + 'http_checked_at' => $http_checked_at, ]; }); diff --git a/database/migrations/2020_06_17_060000_add_health_checks_to_links_table.php b/database/migrations/2020_06_17_060000_add_health_checks_to_links_table.php new file mode 100644 index 0000000..9e535ee --- /dev/null +++ b/database/migrations/2020_06_17_060000_add_health_checks_to_links_table.php @@ -0,0 +1,38 @@ +unsignedSmallInteger('http_status')->after('url')->nullable(); + $table->timestamp('http_checked_at')->after('http_status')->nullable(); + + $table->index('http_status'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('links', function (Blueprint $table) { + $table->dropColumn([ + 'http_status', + 'http_checked_at', + ]); + }); + } +} diff --git a/database/seeds/LinkSeeder.php b/database/seeds/LinkSeeder.php new file mode 100644 index 0000000..595f9d8 --- /dev/null +++ b/database/seeds/LinkSeeder.php @@ -0,0 +1,16 @@ +create(); + } +} diff --git a/resources/lang/en/shaark.php b/resources/lang/en/shaark.php index c45567f..5216f1b 100644 --- a/resources/lang/en/shaark.php +++ b/resources/lang/en/shaark.php @@ -76,7 +76,13 @@ 'disabled' => 'Disabled', 'whitelist' => 'White-listing', 'all' => 'All', - ] + ], + + 'links' => [ + 'title' => 'Link Health Checks', + 'health_checks_enabled' => 'Enable health checks', + 'health_checks_age' => 'Number of days between checks for each link', + ], ], // Mails diff --git a/resources/lang/ja.json b/resources/lang/ja.json index df47020..128bd3b 100644 --- a/resources/lang/ja.json +++ b/resources/lang/ja.json @@ -25,6 +25,8 @@ "Whoops, something went wrong on our servers.": "サーバー上にエラーが発生してしまった。", "Yes": "はい", "No": "いいえ", + "Enabled": "有効", + "Disabled": "無効", "Previous": "前", "Next": "次", @@ -240,5 +242,17 @@ "Source code": "ソースコード", "RSS Feed": "RSSフィード", "Atom Feed": "ATOMフィード", - "All new content of :title": ":titleの最新コンテンツ" + "All new content of :title": ":titleの最新コンテンツ", + + "Total": "合計", + "Health Checks": "健康チェック", + "Pending Checks": "チェック待ち", + "Healthy (200)": "健康(200)", + "Dead (4xx)": "URL切れ(4xx)", + "Other (3xx, 5xx)": "他(3xx、5xx)", + "Dead Links": "切れたURL", + "No dead links found": "切れたURLはありません", + "Other-status Links": "他ステータスのURL", + "No other-status links found": "他ステータスのURLはありません", + "Last Checked": "最後のチェック" } diff --git a/resources/lang/ja/shaark.php b/resources/lang/ja/shaark.php index d6d1500..2063fa6 100644 --- a/resources/lang/ja/shaark.php +++ b/resources/lang/ja/shaark.php @@ -75,7 +75,13 @@ 'disabled' => '無効', 'whitelist' => 'ホワイトリスト', 'all' => 'すべて', - ] + ], + + 'links' => [ + 'title' => 'URLの健康チェック', + 'health_checks_enabled' => '健康チェックを有効にしますか?', + 'health_checks_age' => '各URLの次のチェックを行うまで何日待ちますか?', + ], ], // Mails diff --git a/resources/views/layouts/manage.blade.php b/resources/views/layouts/manage.blade.php index efd1e08..c8d2030 100644 --- a/resources/views/layouts/manage.blade.php +++ b/resources/views/layouts/manage.blade.php @@ -15,6 +15,9 @@ class="list-group-item list-group-item-action{{ request()->is('manage/settings') ? ' active' : '' }}" > {{ __('Settings') }} + {{ __('Links') }} {{ __('Walls') }} diff --git a/resources/views/manage/links.blade.php b/resources/views/manage/links.blade.php new file mode 100644 index 0000000..fc9b5be --- /dev/null +++ b/resources/views/manage/links.blade.php @@ -0,0 +1,70 @@ +@extends('layouts.manage') + +@section('content') +
+
+
+
+
+
+ {{ __('Total') }} +

{{ number_format($num_total, 0) }}

+
+
+
+ +
+
+
+ {{ __('Health Checks') }} + @if ($health_checks_enabled) +

{{ __('Enabled') }}

+ @else +

{{ __('Disabled') }}

+ @endif +
+
+
+ +
+
+
+ {{ __('Pending Checks') }} +

{{ number_format($num_pending, 0) }}

+
+
+
+ +
+
+
+ {{ __('Healthy (200)') }} +

{{ number_format($num_healthy, 0) }}

+
+
+
+ +
+
+
+ {{ __('Dead (4xx)') }} +

{{ number_format($num_dead, 0) }}

+ +
+
+
+ +
+
+
+ {{ __('Other (3xx, 5xx)') }} +

{{ number_format($num_other, 0) }}

+ +
+
+
+
+
+
+ +@endsection diff --git a/resources/views/manage/links_dead.blade.php b/resources/views/manage/links_dead.blade.php new file mode 100644 index 0000000..9feac09 --- /dev/null +++ b/resources/views/manage/links_dead.blade.php @@ -0,0 +1,46 @@ +@extends('layouts.manage') + +@section('content') +
+
+
+
+ + {{ __('Dead Links') }} + +
+
+
+ @if ($dead_links->isEmpty()) +
+ {{ __('No dead links found') }} +
+ @else + + + + + + + + + + @foreach ($dead_links as $dead_link) + + + + + + @endforeach + +
{{ __('Title') }}{{ __('Status') }}{{ __('Last Checked') }}
{{ $dead_link->title }}{{ $dead_link->http_status }}{{ $dead_link->http_checked_at }}
+ + {{ $dead_links->links() }} + @endif +
+
+
+
+
+ +@endsection diff --git a/resources/views/manage/links_other.blade.php b/resources/views/manage/links_other.blade.php new file mode 100644 index 0000000..f9af6ed --- /dev/null +++ b/resources/views/manage/links_other.blade.php @@ -0,0 +1,46 @@ +@extends('layouts.manage') + +@section('content') +
+
+
+
+ + {{ __('Other-status Links') }} + +
+
+
+ @if ($other_links->isEmpty()) +
+ {{ __('No other-status links found') }} +
+ @else + + + + + + + + + + @foreach ($other_links as $other_link) + + + + + + @endforeach + +
{{ __('Title') }}{{ __('Status') }}{{ __('Last Checked') }}
{{ $other_link->title }}{{ $other_link->http_status }}{{ $other_link->http_checked_at }}
+ + {{ $other_links->links() }} + @endif +
+
+
+
+
+ +@endsection diff --git a/resources/views/manage/settings.blade.php b/resources/views/manage/settings.blade.php index 9d010f8..88a93da 100644 --- a/resources/views/manage/settings.blade.php +++ b/resources/views/manage/settings.blade.php @@ -387,6 +387,30 @@ class="form-control" placeholder="<link href='' rel='stylesheet' />, <s + +
diff --git a/routes/web.php b/routes/web.php index 0ffe4e6..66432de 100644 --- a/routes/web.php +++ b/routes/web.php @@ -60,6 +60,11 @@ $router->get('walls', 'WallsController@view')->name('walls'); + $router->get('links', 'LinksController@view')->name('links'); + $router->post('links', 'LinksController@store'); + $router->get('links/dead', 'LinksController@viewDead')->name('links.dead.view'); + $router->get('links/other', 'LinksController@viewOther')->name('links.other.view'); + $router->get('archives', 'ArchivesController@view')->name('archives'); $router->get('settings', 'SettingsController@form')->name('settings'); From 710b60c53f8a80a79bc0fce24417e001379a948b Mon Sep 17 00:00:00 2001 From: Erik Yeoh Date: Thu, 3 Sep 2020 12:17:06 +0800 Subject: [PATCH 2/4] :lipstick: Show link's http status and last checked date in the link card --- app/Http/Resources/LinkResource.php | 33 ++++++++++++++++++++++++++++ resources/js/components/LinkCard.vue | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/app/Http/Resources/LinkResource.php b/app/Http/Resources/LinkResource.php index 8763c69..bf684ce 100644 --- a/app/Http/Resources/LinkResource.php +++ b/app/Http/Resources/LinkResource.php @@ -13,6 +13,9 @@ public function toArray($request) 'title' => $this->title, 'content' => $this->content, 'url' => $this->url, + 'http_status' => $this->getStatusText($this->http_status), + 'http_status_color' => $this->getStatusColor($this->http_status), + 'http_checked_at' => $this->http_checked_at, 'permalink' => $this->permalink, 'is_private' => $this->post->is_private, 'is_pinned' => $this->post->is_pinned, @@ -33,4 +36,34 @@ public function toArray($request) ]) ]; } + + public function getStatusText($status) + { + if (is_null($status)) { + return null; + } + + if ($status == 200) { + return 'Healthy (200)'; + } + + if (400 <= $status and $status <= 499) { + return 'Dead (4xx)'; + } + + return 'Other (3xx, 5xx)'; + } + + public function getStatusColor($status) + { + if ($status == 200) { + return 'success'; + } + + if (400 <= $status and $status <= 499) { + return 'danger'; + } + + return 'warning'; + } } diff --git a/resources/js/components/LinkCard.vue b/resources/js/components/LinkCard.vue index 549e6f0..f536e09 100644 --- a/resources/js/components/LinkCard.vue +++ b/resources/js/components/LinkCard.vue @@ -14,6 +14,11 @@

{{ tag }}

+ +

+ {{ __(link.http_status) }} + {{ __('Last Checked') }}: {{ link.http_checked_at }} +

-
+
@@ -30,7 +30,7 @@
-
+
@@ -38,6 +38,15 @@
+ +
+
+
+ + +
+
+
@@ -130,6 +139,7 @@ let defaultLink = function () { url: null, title: null, content: null, + is_health_check_enabled: true, is_private: false, is_pinned: false, tags: [] diff --git a/resources/lang/ja.json b/resources/lang/ja.json index 128bd3b..79086ed 100644 --- a/resources/lang/ja.json +++ b/resources/lang/ja.json @@ -251,8 +251,10 @@ "Dead (4xx)": "URL切れ(4xx)", "Other (3xx, 5xx)": "他(3xx、5xx)", "Dead Links": "切れたURL", + "Disabled Links": "健康チェック無効のURL", "No dead links found": "切れたURLはありません", "Other-status Links": "他ステータスのURL", "No other-status links found": "他ステータスのURLはありません", - "Last Checked": "最後のチェック" + "Last Checked": "最後のチェック", + "Enable Health Check?": "健康チェックを有効しますか?" } diff --git a/resources/views/layouts/manage.blade.php b/resources/views/layouts/manage.blade.php index c8d2030..3a34260 100644 --- a/resources/views/layouts/manage.blade.php +++ b/resources/views/layouts/manage.blade.php @@ -16,7 +16,7 @@ class="list-group-item list-group-item-action{{ request()->is('manage/settings') > {{ __('Settings') }} {{ __('Links') }} - -
- + @include('manage.links_dashboard') @endsection diff --git a/resources/views/manage/links_dashboard.blade.php b/resources/views/manage/links_dashboard.blade.php new file mode 100644 index 0000000..94116e0 --- /dev/null +++ b/resources/views/manage/links_dashboard.blade.php @@ -0,0 +1,75 @@ +
+
+
+
+
+
+ {{ __('Total') }} +

{{ number_format($stats->countTotal(), 0) }}

+
+
+
+ +
+
+
+ {{ __('Health Checks') }} + @if ($stats->isHealthCheckEnabled()) +

{{ __('Enabled') }}

+ @else +

{{ __('Disabled') }}

+ @endif +
+
+
+ +
+
+
+ {{ __('Pending Checks') }} +

{{ number_format($stats->countPending(), 0) }}

+
+
+
+ +
+
+
+ {{ __('Healthy (200)') }} +

{{ number_format($stats->countHealthy(), 0) }}

+
+
+
+ +
+
+
+ {{ __('Dead (4xx)') }} +

{{ number_format($stats->countDead(), 0) }}

+ +
+
+
+ +
+
+
+ {{ __('Other (3xx, 5xx)') }} +

{{ number_format($stats->countOther(), 0) }}

+ +
+
+
+ +
+
+
+ {{ __('Disabled Links') }} +

{{ number_format($stats->countDisabled(), 0) }}

+ +
+
+
+
+
+
\ No newline at end of file diff --git a/resources/views/manage/links_dead.blade.php b/resources/views/manage/links_dead.blade.php index 9feac09..c3fd32c 100644 --- a/resources/views/manage/links_dead.blade.php +++ b/resources/views/manage/links_dead.blade.php @@ -1,46 +1,47 @@ @extends('layouts.manage') @section('content') -
-
-
-
- - {{ __('Dead Links') }} - -
-
-
- @if ($dead_links->isEmpty()) -
- {{ __('No dead links found') }} -
- @else - - - - - - - - - - @foreach ($dead_links as $dead_link) + @include('manage.links_dashboard') + +
+
+
+
+ + {{ __('Dead Links') }} + +
+
+
+ @if ($dead_links->isEmpty()) +
+ {{ __('No dead links found') }} +
+ @else +
{{ __('Title') }}{{ __('Status') }}{{ __('Last Checked') }}
+ - - - + + + - @endforeach - -
{{ $dead_link->title }}{{ $dead_link->http_status }}{{ $dead_link->http_checked_at }}{{ __('Title') }}{{ __('Status') }}{{ __('Last Checked') }}
+ + + @foreach ($dead_links as $dead_link) + + {{ $dead_link->title }} + {{ $dead_link->http_status }} + {{ $dead_link->http_checked_at }} + + @endforeach + + - {{ $dead_links->links() }} - @endif + {{ $dead_links->links() }} + @endif +
-
- @endsection diff --git a/resources/views/manage/links_disabled.blade.php b/resources/views/manage/links_disabled.blade.php new file mode 100644 index 0000000..a02a4b4 --- /dev/null +++ b/resources/views/manage/links_disabled.blade.php @@ -0,0 +1,43 @@ +@extends('layouts.manage') + +@section('content') + @include('manage.links_dashboard') + +
+
+
+
+ + {{ __('Disabled Links') }} + +
+
+
+ @if ($disabled_links->isEmpty()) +
+ {{ __('No disabled links found') }} +
+ @else + + + + + + + + @foreach ($disabled_links as $disabled_link) + + + + @endforeach + +
{{ __('Title') }}
{{ $disabled_link->title }}
+ + {{ $disabled_links->links() }} + @endif +
+
+
+
+
+@endsection diff --git a/resources/views/manage/links_other.blade.php b/resources/views/manage/links_other.blade.php index f9af6ed..398c6ff 100644 --- a/resources/views/manage/links_other.blade.php +++ b/resources/views/manage/links_other.blade.php @@ -1,46 +1,47 @@ @extends('layouts.manage') @section('content') -
-
-
-
- - {{ __('Other-status Links') }} - -
-
-
- @if ($other_links->isEmpty()) -
- {{ __('No other-status links found') }} -
- @else - - - - - - - - - - @foreach ($other_links as $other_link) + @include('manage.links_dashboard') + +
+
+
+
+ + {{ __('Other-status Links') }} + +
+
+
+ @if ($other_links->isEmpty()) +
+ {{ __('No other-status links found') }} +
+ @else +
{{ __('Title') }}{{ __('Status') }}{{ __('Last Checked') }}
+ - - - + + + - @endforeach - -
{{ $other_link->title }}{{ $other_link->http_status }}{{ $other_link->http_checked_at }}{{ __('Title') }}{{ __('Status') }}{{ __('Last Checked') }}
+ + + @foreach ($other_links as $other_link) + + {{ $other_link->title }} + {{ $other_link->http_status }} + {{ $other_link->http_checked_at }} + + @endforeach + + - {{ $other_links->links() }} - @endif + {{ $other_links->links() }} + @endif +
-
- @endsection diff --git a/routes/web.php b/routes/web.php index 66432de..752071c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -64,6 +64,7 @@ $router->post('links', 'LinksController@store'); $router->get('links/dead', 'LinksController@viewDead')->name('links.dead.view'); $router->get('links/other', 'LinksController@viewOther')->name('links.other.view'); + $router->get('links/disabled', 'LinksController@viewDisabled')->name('links.disabled.view'); $router->get('archives', 'ArchivesController@view')->name('archives'); From 2ec3168f91025518dc71628c6e9cb0bdcd707a1b Mon Sep 17 00:00:00 2001 From: Erik Yeoh Date: Thu, 3 Sep 2020 14:36:45 +0800 Subject: [PATCH 4/4] :bug: The number of links pending checks did not exclude links that have health checks disabled --- app/Services/HealthCheckStats.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/Services/HealthCheckStats.php b/app/Services/HealthCheckStats.php index 6528b48..eac5e46 100644 --- a/app/Services/HealthCheckStats.php +++ b/app/Services/HealthCheckStats.php @@ -62,8 +62,11 @@ public function countDead() public function countPending() { return \DB::table('links') - ->where('http_checked_at', '<', now()->subDays(app(Shaark::class)->getLinkHealthChecksAge())) - ->orWhereNull('http_checked_at') + ->where('is_health_check_enabled', 1) + ->where(function ($query) { + return $query->where('http_checked_at', '<', now()->subDays(app(Shaark::class)->getLinkHealthChecksAge())) + ->orWhereNull('http_checked_at'); + }) ->count(); }