Skip to content

Commit

Permalink
Merge pull request #127 from Kovah/dev
Browse files Browse the repository at this point in the history
v0.0.36
  • Loading branch information
Kovah authored May 8, 2020
2 parents 8660c44 + 310a363 commit b3352ee
Show file tree
Hide file tree
Showing 70 changed files with 1,014 additions and 237 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Analyze

on:
pull_request:

jobs:

analyze-php:
name: PHP Code Coverage Generation
runs-on: ubuntu-latest
continue-on-error: true

steps:
- uses: actions/checkout@v1

- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.x

- name: Build all assets
run: |
npm ci
npm run production
- name: Setup PHP
uses: shivammathur/setup-php@v1
with:
php-version: 7.4
coverage: pcov
extensions: mbstring

- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"

- name: Cache dependencies
uses: actions/cache@v1
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Prepare the environment
run: cp .env.example .env

- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest

- name: Test & publish code coverage
uses: paambaati/codeclimate-action@v2.6.0
env:
CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
with:
coverageCommand: composer run code-coverage
coverageLocations: ${{github.workspace}}/test-coverage.xml:clover
debug: true
94 changes: 40 additions & 54 deletions app/Console/Commands/CheckLinksCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
use App\Models\Link;
use App\Models\User;
use App\Notifications\LinkCheckNotification;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;

/**
Expand All @@ -17,10 +17,10 @@
*/
class CheckLinksCommand extends Command
{
protected $signature = 'links:check';
protected $signature = 'links:check {--limit=} {--noWait}';

/** @var int $limit Check a maximum of 100 links at once */
protected $limit = 100;
public $limit = 100;

/** @var int */
protected $offset;
Expand All @@ -29,53 +29,44 @@ class CheckLinksCommand extends Command
protected $total;

/** @var int */
protected $checked_link_count;

/** @var Client */
protected $client;
protected $checkedLinkCount;

/** @var string */
protected $cache_key_offset = 'command_links:check_offset';
protected $cacheKeyOffset = 'command_links:check_offset';

/** @var string */
protected $cache_key_skip_timestamp = 'command_links:check_skip_timestamp';
protected $cacheKeySkipTimestamp = 'command_links:check_skip_timestamp';

/** @var string */
protected $cache_key_checked_count = 'command_links:check_checked_count';
protected $cacheKeyCheckedCount = 'command_links:check_checked_count';

/** @var array */
protected $moved_links = [];
protected $movedLinks = [];

/** @var array */
protected $broken_links = [];

/**
* RegisterUser constructor.
*/
public function __construct()
{
$this->client = new Client();

parent::__construct();
}
protected $brokenLinks = [];

public function handle(): void
{
// Check if the command should skip the execution
$skip_timestamp = Cache::get($this->cache_key_skip_timestamp);
$this->offset = Cache::get($this->cache_key_offset, 0);
$this->checked_link_count = Cache::get($this->cache_key_checked_count, 0);
$skipTimestamp = Cache::get($this->cacheKeySkipTimestamp);
$this->offset = Cache::get($this->cacheKeyOffset, 0);
$this->checkedLinkCount = Cache::get($this->cacheKeyCheckedCount, 0);

if (now()->timestamp < $skip_timestamp) {
if (now()->timestamp < $skipTimestamp) {
return;
}

if ($this->option('limit')) {
$this->limit = $this->option('limit');
}

$links = $this->getLinks();

// Cancel if there are no links to check
if ($links->isEmpty()) {
Cache::forget($this->cache_key_offset);
Cache::forget($this->cache_key_skip_timestamp);
Cache::forget($this->cacheKeyOffset);
Cache::forget($this->cacheKeySkipTimestamp);

$this->comment('No links found, aborting...');
return;
Expand All @@ -88,28 +79,28 @@ public function handle(): void
$this->checkLink($link);

// Prevent spam-ish behaviour by limiting outgoing HTTP requests
sleep(1);
if ($this->option('noWait') === null) {
sleep(1);
}
});

// Send notification about moved/broken links
$this->sendNotification();

// Check if there are more links to check
$checked_count = $this->checked_link_count + $links->count();
Cache::forever($this->cache_key_checked_count, $checked_count);
$checkedCount = $this->checkedLinkCount + $links->count();
Cache::forever($this->cacheKeyCheckedCount, $checkedCount);

if ($this->total > $checked_count) {
if ($this->total > $checkedCount) {
// If yes, simply save the offset to the cache.
// The next link check will pick it up and continue the check.
$next_offset = $this->offset + $this->limit;
Cache::forever($this->cache_key_offset, $next_offset);
$nextOffset = $this->offset + $this->limit;
Cache::forever($this->cacheKeyOffset, $nextOffset);

$this->comment('Saving offset for next link check.');
} else {
// If not, all links have been successfully checked.
// Save a cache flag that prevents link checks for the next days.
$next_check = now()->addDays(5)->timestamp;
Cache::forever($this->cache_key_skip_timestamp, $next_check);
$nextCheck = now()->addDays(20)->timestamp;
Cache::forever($this->cacheKeySkipTimestamp, $nextCheck);

$this->comment(
'All existing links checked, next link check scheduled for ' . now()->addDays(5)->toDateTimeString()
Expand Down Expand Up @@ -146,21 +137,16 @@ protected function checkLink(Link $link): void
{
$this->output->write('Checking link ' . $link->url . ' ');

$options = [
'http_errors' => false, // Do not throw exceptions for 4xx and 5xx errors
'timeout' => 5, // wait a maximum of 5 seconds for the request to finish
];

try {
$res = $this->client->request('GET', $link->url, $options);
$status_code = $res->getStatusCode();
$response = Http::timeout(5)->get($link->url);
$statusCode = $response->status();
} catch (\Exception $e) {
// Set status code to null so the link will be marked as broken
$status_code = 0;
$statusCode = 0;
}

if ($status_code !== 200) {
$this->processBrokenLink($status_code, $link);
if ($statusCode !== 200) {
$this->processBrokenLink($statusCode, $link);
} else {
$this->processWorkingLink($link);
}
Expand All @@ -179,12 +165,12 @@ protected function processBrokenLink(int $status_code, Link $link): void
$link->status = Link::STATUS_MOVED;
$this->warn('› Link moved to another URL!');

$this->moved_links[] = $link;
$this->movedLinks[] = $link;
} else {
$link->status = Link::STATUS_BROKEN;
$this->error('› Link seems to be broken!');

$this->broken_links[] = $link;
$this->brokenLinks[] = $link;
}

$link->save();
Expand Down Expand Up @@ -212,16 +198,16 @@ protected function processWorkingLink(Link $link): void
*/
protected function sendNotification()
{
if (empty($this->moved_links) && empty($this->broken_links)) {
if (empty($this->movedLinks) && empty($this->brokenLinks)) {
// Do not send a notification if there are no errors
return;
}

$this->info('› Notification sent to the user.');

Notification::send(
User::find(1),
new LinkCheckNotification($this->moved_links, $this->broken_links)
new LinkCheckNotification($this->movedLinks, $this->brokenLinks)
);

$this->info('› Notification sent to the user.');
}
}
5 changes: 2 additions & 3 deletions app/Console/Commands/RegisterUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* Class RegisterUser
*
* Provides a php artisan command to register a new user
* Provides a php artisan command to register a new user:
* php artisan registeruser UserName mail@user.com
*
* @package App\Console\Commands
Expand Down Expand Up @@ -39,13 +39,12 @@ public function handle(): void

$password = $this->secret('Please enter a password for ' . $name);

$new_user = User::create([
User::create([
'name' => $name,
'email' => $email,
'password' => Hash::make($password),
]);

$this->info('User ' . $name . ' registered.');
return;
}
}
5 changes: 5 additions & 0 deletions app/Console/Commands/ResetPasswordCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Validator;

/**
* Class ResetPasswordCommand
*
* @package App\Console\Commands
*/
class ResetPasswordCommand extends Command
{
protected $signature = 'reset-password';
Expand Down
20 changes: 16 additions & 4 deletions app/Helper/HtmlMeta.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class HtmlMeta
/** @var array */
protected static $fallback;

/** @var bool */
protected static $flashAlerts;

/**
* Get the title and description of an URL.
*
Expand All @@ -27,11 +30,14 @@ class HtmlMeta
* 'description' => string|null,
* ]
*
* @param $url
* @param string $url
* @param bool $flashAlerts
* @return array
*/
public static function getFromUrl($url): array
public static function getFromUrl(string $url, bool $flashAlerts = false): array
{
self::$flashAlerts = $flashAlerts;

if (!filter_var($url, FILTER_VALIDATE_URL)) {
return [
'success' => false,
Expand Down Expand Up @@ -68,12 +74,18 @@ protected static function getHtmlContent(string $url): ?string
try {
$response = Http::timeout(5)->get($url);
} catch (ConnectionException $e) {
flash(trans('link.added_connection_error'), 'warning');
if (self::$flashAlerts) {
flash(trans('link.added_connection_error'), 'warning');
}

Log::warning($url . ': ' . $e->getMessage());

return null;
} catch (RequestException $e) {
flash(trans('link.added_request_error'), 'warning');
if (self::$flashAlerts) {
flash(trans('link.added_request_error'), 'warning');
}

Log::warning($url . ': ' . $e->getMessage());

return null;
Expand Down
Loading

0 comments on commit b3352ee

Please sign in to comment.