mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 01:08:56 +00:00
75 lines
2.3 KiB
PHP
75 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services\Releases;
|
|
|
|
use App\Models\Release;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
/**
|
|
* Finds an existing release that should be treated as a duplicate of an incoming import.
|
|
*
|
|
* Uses (predb_id OR searchname) within a configurable size band. Falls back to raw {@see Release::$name}
|
|
* when {@see Release::$searchname} is empty and there is no predb id.
|
|
*/
|
|
final class ReleaseDuplicateFinder
|
|
{
|
|
/**
|
|
* @return array{0: ?Release, 1: ?string} Tuple of matched release (if any) and dedupe reason for logging.
|
|
*/
|
|
public function findDuplicate(
|
|
string $cleanRelName,
|
|
string $searchName,
|
|
int $predbId,
|
|
int $filesize,
|
|
): array {
|
|
$tolerance = (float) config('nntmux.release_dedupe_size_tolerance', 0.05);
|
|
$lowSize = (int) floor($filesize * (1 - $tolerance));
|
|
$highSize = (int) ceil($filesize * (1 + $tolerance));
|
|
|
|
$query = Release::query()
|
|
->whereBetween('size', [$lowSize, $highSize]);
|
|
|
|
if ($predbId > 0 || $searchName !== '') {
|
|
$query->where(function (Builder $w) use ($searchName, $predbId): void {
|
|
if ($predbId > 0) {
|
|
$w->where('predb_id', $predbId);
|
|
if ($searchName !== '') {
|
|
$w->orWhere('searchname', $searchName);
|
|
}
|
|
} elseif ($searchName !== '') {
|
|
$w->where('searchname', $searchName);
|
|
} else {
|
|
$w->whereRaw('1 = 0');
|
|
}
|
|
});
|
|
} else {
|
|
$query->where('name', $cleanRelName);
|
|
}
|
|
|
|
$dup = $query->first(['id', 'predb_id', 'searchname', 'fromname', 'size', 'name']);
|
|
|
|
if ($dup === null) {
|
|
return [null, null];
|
|
}
|
|
|
|
$reason = $this->resolveReason($dup, $searchName, $predbId);
|
|
|
|
return [$dup, $reason];
|
|
}
|
|
|
|
private function resolveReason(Release $dup, string $searchName, int $predbId): string
|
|
{
|
|
if ($predbId > 0 && (int) $dup->predb_id === $predbId) {
|
|
return 'predb_id_match';
|
|
}
|
|
|
|
if ($searchName !== '' && (string) $dup->searchname === $searchName) {
|
|
return 'searchname_match';
|
|
}
|
|
|
|
return 'name_match_fallback';
|
|
}
|
|
}
|