app/Helpers/StorageCleaner.php
<?php
namespace App\Helpers;
use App\Contracts\ScreenshotService;
use App\Models\TimeInterval;
use Cache;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Database\Eloquent\Builder;
use Storage;
class StorageCleaner
{
public static function getFreeSpace(): float
{
return disk_free_space(Storage::path(ScreenshotService::PARENT_FOLDER));
}
public static function getUsedSpace(): float
{
return config('cleaner.total_space') - self::getFreeSpace();
}
public static function needThinning(): bool
{
return
self::getUsedSpace() * 100 / config('cleaner.total_space')
>= config('cleaner.threshold');
}
/**
* @throws BindingResolutionException
*/
public static function thin($force = false): void
{
if ((!$force && !self::needThinning()) || Cache::store('octane')->get('thinning_now')) {
return;
}
Cache::store('octane')->set('thinning_now', true);
$service = app()->make(ScreenshotService::class);
while (self::getUsedSpace() > self::getWaterlineBorder()) {
$availableScreenshots = self::getAvailableScreenshots();
if (count($availableScreenshots) === 0) {
break;
}
foreach ($availableScreenshots as $screenshot) {
$service->destroyScreenshot($screenshot);
}
}
Cache::store('octane')->set('thinning_now',false);
Cache::store('octane')->set('last_thin',now());
}
/**
* @return array
* @throws BindingResolutionException
*/
public static function getAvailableScreenshots(): array
{
$service = app()->make(ScreenshotService::class);
$collection = self::getScreenshotsCollection();
$result = [];
$i = 0;
foreach ($collection->cursor() as $interval) {
if (Storage::exists($service->getScreenshotPath($interval))) {
$result[] = $interval->id;
}
if ($i >= config('cleaner.page_size')) {
break;
}
}
return $result;
}
/**
* @return int
* @throws BindingResolutionException
*/
public static function countAvailableScreenshots(): int
{
$count = 0;
$service = app()->make(ScreenshotService::class);
$collection = self::getScreenshotsCollection();
foreach ($collection->cursor() as $interval) {
$count += (int)Storage::exists($service->getScreenshotPath($interval));
}
return $count;
}
private static function getWaterlineBorder(): float
{
return config('cleaner.total_space')
* (config('cleaner.threshold') * 0.01)
* (1 - config('cleaner.waterline') * 0.01);
}
private static function getScreenshotsCollection(): Builder|TimeInterval|\Illuminate\Database\Query\Builder
{
return TimeInterval::whereHas('task', function (Builder $query) {
$query->where('important', '=', 0);
})
->whereHas('task.project', function (Builder $query) {
$query->where('important', '=', 0);
})->whereHas('user', function (Builder $query) {
$query->where('permanent_screenshots', '=', 0);
})->orderBy('id');
}
}