Passed
Push — master ( 03c468...179943 )
by Darko
11:56
created

BookCategorizer::checkMagazine()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 3
nc 3
nop 1
1
<?php
2
namespace App\Services\Categorization\Categorizers;
3
use App\Models\Category;
4
use App\Services\Categorization\CategorizationResult;
5
use App\Services\Categorization\ReleaseContext;
6
class BookCategorizer extends AbstractCategorizer
7
{
8
    protected int $priority = 45;
9
    public function getName(): string { return 'Book'; }
10
    public function shouldSkip(ReleaseContext $context): bool
11
    {
12
        if ($context->hasAdultMarkers()) return true;
13
        if (preg_match('/\.PS4-[A-Z0-9]+$/i', $context->releaseName)) return true;
14
        if (preg_match('/\b(?:PS[1-5]|PlayStation|Xbox|Switch|Nintendo|Wii|3DS|GameCube)\b/i', $context->releaseName)) return true;
15
        // Skip TV shows (season patterns)
16
        if (preg_match('/[._ -]S\d{1,3}[._ -]?(E\d|Complete|Full|1080|720|480|2160|WEB|HDTV|BluRay)/i', $context->releaseName)) return true;
17
        // Skip movies (year + quality patterns)
18
        if (preg_match('/\b(19|20)\d{2}\b.*\b(1080p|720p|2160p|BluRay|WEB-DL|BDRip|DVDRip)\b/i', $context->releaseName)) return true;
19
        return false;
20
    }
21
    public function categorize(ReleaseContext $context): CategorizationResult
22
    {
23
        $name = $context->releaseName;
24
        if ($result = $this->checkComic($name)) return $result;
25
        if ($result = $this->checkTechnical($name)) return $result;
26
        if ($result = $this->checkMagazine($name)) return $result;
27
        if ($result = $this->checkEbook($name)) return $result;
28
        return $this->noMatch();
29
    }
30
    protected function checkComic(string $name): ?CategorizationResult
31
    {
32
        if (preg_match('/\b(?:CBR|CBZ|C2C)\b|\.(?:cbr|cbz)$/i', $name)) return $this->matched(Category::BOOKS_COMICS, 0.9, 'comic_format');
33
        if (preg_match('/\b(?:Marvel|DC[._ -]Comics|Image[._ -]Comics|Dark[._ -]Horse|IDW)\b/i', $name) &&
34
            preg_match('/\b(?:Comics?|Annual|Issue|Vol|TPB)\b/i', $name)) return $this->matched(Category::BOOKS_COMICS, 0.85, 'comic_publisher');
35
        if (preg_match('/\b(?:Manga|Manhwa|Manhua|Webtoon)\b/i', $name)) return $this->matched(Category::BOOKS_COMICS, 0.85, 'manga');
36
        return null;
37
    }
38
    protected function checkTechnical(string $name): ?CategorizationResult
39
    {
40
        $publishers = 'Apress|Addison[._ -]Wesley|Manning|No[._ -]Starch|OReilly|Packt|Pragmatic|Wiley|Wrox';
41
        if (preg_match('/\b(' . $publishers . ')\b/i', $name)) return $this->matched(Category::BOOKS_TECHNICAL, 0.9, 'technical_publisher');
42
        $subjects = 'Programming|Python|JavaScript|Java|Database|Linux|DevOps|Machine[._ -]Learning|Data[._ -]Science';
43
        if (preg_match('/\b(' . $subjects . ')\b/i', $name) && preg_match('/\b(Book|Guide|Tutorial|Learn)\b/i', $name)) {
44
            return $this->matched(Category::BOOKS_TECHNICAL, 0.85, 'technical_subject');
45
        }
46
        return null;
47
    }
48
    protected function checkMagazine(string $name): ?CategorizationResult
49
    {
50
        if (preg_match('/[._ -](Monthly|Weekly|Annual|Quarterly|Issue)[._ -]/i', $name)) return $this->matched(Category::BOOKS_MAGAZINES, 0.9, 'magazine_frequency');
51
        $magazines = 'Forbes|Fortune|GQ|National[._ -]Geographic|Newsweek|Time|Vogue|Wired|PC[._ -]Gamer';
52
        if (preg_match('/\b(' . $magazines . ')\b/i', $name)) return $this->matched(Category::BOOKS_MAGAZINES, 0.85, 'magazine_title');
53
        return null;
54
    }
55
    protected function checkEbook(string $name): ?CategorizationResult
56
    {
57
        $formats = 'EPUB|MOBI|AZW\d?|PDF|FB2|DJVU|LIT';
58
        if (preg_match('/\.(' . $formats . ')$/i', $name)) return $this->matched(Category::BOOKS_EBOOK, 0.9, 'ebook_format');
59
        if (preg_match('/\b(' . $formats . ')\b/i', $name)) return $this->matched(Category::BOOKS_EBOOK, 0.85, 'ebook_indicator');
60
        if (preg_match('/\b(E-?book|Kindle|Kobo|Nook)\b/i', $name)) return $this->matched(Category::BOOKS_EBOOK, 0.8, 'ebook_platform');
61
        return null;
62
    }
63
}
64