Passed
Push — master ( db1db2...d25d15 )
by Darko
07:44
created

CleanNZB::GetNZBsWithNoDatabaseEntry()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 26
rs 9.1111
cc 6
nc 5
nop 1
1
<?php
2
3
namespace App\Console\Commands;
4
5
use App\Models\Release;
6
use App\Models\Settings;
7
use Blacklight\NZB;
8
use Blacklight\ReleaseImage;
9
use Blacklight\Releases;
10
use Illuminate\Console\Command;
11
use Illuminate\Support\Collection;
12
use Illuminate\Support\Facades\File;
13
14
class CleanNZB extends Command
15
{
16
    /**
17
     * The name and signature of the console command.
18
     *
19
     * @var string
20
     */
21
    protected $signature = 'nntmux:nzbclean
22
    {--notindb : Delete NZBs that dont exist in database}
23
    {--notondisk : Delete release in database that dont have a NZB on disk}
24
    {--chunksize=25000 : Chunk size for releases query}
25
    {--delete : Pass this argument to actually delete the files. Otherwise it\'s just a dry run.}';
26
27
    /**
28
     * The console command description.
29
     *
30
     * @var string
31
     */
32
    protected $description = 'Find NZBs that dont have a release, or releases that have no NZBs.';
33
34
    /**
35
     * Execute the console command.
36
     */
37
    public function handle()
38
    {
39
        // Check if any options are false
40
        if (! $this->option('notindb') && ! $this->option('notondisk')) {
41
            $this->error('You must specify at least one option. See: --help');
42
            exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
43
        }
44
        if ($this->option('notindb')) {
45
            $this->GetNZBsWithNoDatabaseEntry($this->option('delete'));
46
        }
47
        if ($this->option('notondisk')) {
48
            $this->GetReleasesWithNoNZBOnDisk($this->option('delete'));
49
        }
50
    }
51
52
    private function GetNZBsWithNoDatabaseEntry($delete = false)
53
    {
54
        $this->info('Getting list of NZB files on disk to check if they exist in database');
55
        $releases = new Release();
56
        $checked = $deleted = 0;
57
        // Get the list of NZBs in the NZB folder
58
        $dirItr = new \RecursiveDirectoryIterator(Settings::settingValue('..nzbpath'));
59
        $itr = new \RecursiveIteratorIterator($dirItr, \RecursiveIteratorIterator::LEAVES_ONLY);
60
61
        // Checking filename GUIDs against the releases table
62
        foreach ($itr as $filePath) {
63
            $guid = stristr($filePath->getFilename(), '.nzb.gz', true);
64
            if (File::isFile($filePath) && $guid) {
65
                // If NZB file guid is not present in DB delete the file from disk
66
                if (! $releases->whereGuid($guid)->exists()) {
67
                    if ($delete) {
68
                        File::delete($filePath);
69
                    }
70
                    $deleted++;
71
                    $this->line("Deleted orphan file: $guid.nzb.gz");
72
                }
73
                $checked++;
74
            }
75
            echo "Checked: $checked / Deleted: $deleted\r";
76
        }
77
        $this->info("Checked: $checked / Deleted: $deleted");
78
    }
79
80
    private function GetReleasesWithNoNZBOnDisk($delete = false)
81
    {
82
        // Setup
83
        $nzb = new NZB();
84
        $rel = new Releases();
85
        $checked = $deleted = 0;
86
87
        $this->info('Getting list of releases from database to check if they have a corresponding NZB on disk');
88
        $total = Release::count();
89
        $this->alert("Total releases to check: $total");
90
91
        Release::where('nzbstatus', 1)->chunkById((int) $this->option('chunksize'), function (Collection $releases) use ($delete, &$checked, &$deleted, $nzb, $rel) {
92
            echo 'Total done: '.$checked."\r";
93
            foreach ($releases as $r) {
94
95
                if (! $nzb->NZBPath($r->guid)) {
96
                    if ($delete) {
97
                        $rel->deleteSingle(['g' => $r->guid, 'i' => $r->id], $nzb, new ReleaseImage());
98
                    }
99
                    $deleted++;
100
                    $this->line("Deleted: $r->searchname -> $r->guid");
101
                }
102
                $checked++;
103
            }
104
        });
105
        $this->info("Checked: $checked / Deleted: $deleted");
106
    }
107
}
108