Issues (374)

app/Http/Controllers/GetNzbController.php (3 issues)

Labels
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Models\Release;
6
use App\Models\User;
7
use App\Models\UserDownload;
8
use App\Models\UsersRelease;
9
use Blacklight\NZB;
10
use Blacklight\utility\Utility;
11
use Illuminate\Http\Request;
12
use Illuminate\Support\Facades\File;
13
14
class GetNzbController extends BasePageController
15
{
16
    /**
17
     * @throws \Exception
18
     */
19
    public function getNzb(Request $request)
20
    {
21
        $this->setPreferences();
22
23
        // Page is accessible only by the rss token, or logged in users.
24
        if ($request->user()) {
25
            $uid = $this->userdata->id;
26
            $maxDownloads = $this->userdata->role->downloadrequests;
0 ignored issues
show
The property downloadrequests does not seem to exist on Spatie\Permission\Models\Role.
Loading history...
27
            $rssToken = $this->userdata->api_token;
28
            if ($this->userdata->hasRole('Disabled')) {
29
                return Utility::showApiError(101);
30
            }
31
        } else {
32
            if ($request->missing('r')) {
33
                return Utility::showApiError(200);
34
            }
35
36
            $res = User::getByRssToken($request->input('r'));
37
            if (! $res) {
38
                return Utility::showApiError(100);
39
            }
40
41
            $uid = $res['id'];
42
            $rssToken = $res['api_token'];
43
            $maxDownloads = $res->role->downloadrequests;
44
            if ($res->hasRole('Disabled')) {
45
                return Utility::showApiError(101);
46
            }
47
        }
48
49
        // Check download limit on user role.
50
        $requests = UserDownload::getDownloadRequests($uid);
51
        if ($requests > $maxDownloads) {
52
            return Utility::showApiError(501);
53
        }
54
55
        if (! $request->input('id')) {
56
            return Utility::showApiError(200, 'Parameter id is required');
57
        }
58
59
        // Remove any suffixed id with .nzb which is added to help weblogging programs see nzb traffic.
60
        $request->merge(['id' => str_ireplace('.nzb', '', $request->input('id'))]);
61
62
        // User requested a zip of guid,guid,guid releases.
63
        if ($request->has('zip') && $request->input('zip') === '1') {
64
            $guids = explode(',', $request->input('id'));
65
            if ($requests + \count($guids) > $maxDownloads) {
66
                return Utility::showApiError(501);
67
            }
68
69
            $zip = getStreamingZip($guids);
70
            if ($zip !== '') {
71
                User::incrementGrabs($uid, \count($guids));
72
                foreach ($guids as $guid) {
73
                    Release::updateGrab($guid);
74
                    UserDownload::addDownloadRequest($uid, $guid);
75
76
                    if ($request->has('del') && (int) $request->input('del') === 1) {
77
                        UsersRelease::delCartByUserAndRelease($guid, $uid);
78
                    }
79
                }
80
81
                return $zip;
82
            }
83
84
            return response()->json(['message' => 'Unable to create .zip file'], 404);
85
        }
86
87
        $nzbPath = (new NZB)->getNZBPath($request->input('id'));
88
89
        if (! File::exists($nzbPath)) {
90
            return Utility::showApiError(300, 'NZB file not found!');
91
        }
92
93
        $relData = Release::getByGuid($request->input('id'));
94
        if ($relData === null) {
95
            return Utility::showApiError(300, 'Release not found!');
96
        }
97
98
        // Update release and user actions
99
        Release::updateGrab($request->input('id'));
100
        UserDownload::addDownloadRequest($uid, $relData['id']);
101
        User::incrementGrabs($uid);
102
103
        if ($request->has('del') && (int) $request->input('del') === 1) {
104
            UsersRelease::delCartByUserAndRelease($request->input('id'), $uid);
105
        }
106
107
        // Build headers
108
        $headers = [
109
            'Content-Type' => 'application/x-nzb',
110
            'Expires' => now()->addYear()->toRfc7231String(),
111
            'X-DNZB-Failure' => url('/failed').'?guid='.$request->input('id').'&userid='.$uid.'&api_token='.$rssToken,
112
            'X-DNZB-Category' => e($relData['category_name']), // Escape category name
113
            'X-DNZB-Details' => url('/details/'.$request->input('id')),
114
        ];
115
116
        if (! empty($relData['imdbid']) && $relData['imdbid'] > 0) {
117
            $headers['X-DNZB-MoreInfo'] = 'http://www.imdb.com/title/tt'.$relData['imdbid'];
118
        } elseif (! empty($relData['tvdb']) && $relData['tvdb'] > 0) {
119
            $headers['X-DNZB-MoreInfo'] = 'http://www.thetvdb.com/?tab=series&id='.$relData['tvdb'];
120
        }
121
122
        if ((int) $relData['nfostatus'] === 1) {
123
            $headers['X-DNZB-NFO'] = url('/nfo/'.$request->input('id'));
124
        }
125
126
        $headers['X-DNZB-RCode'] = '200';
127
        $headers['X-DNZB-RText'] = 'OK, NZB content follows.';
128
129
        // Sanitize file name
130
        $cleanName = str_replace([',', ' ', '/', '\\'], '_', $relData['searchname']);
131
132
        // Stream the file content
133
        return response()->streamDownload(function () use ($nzbPath) {
134
            $bufferSize = 1000000; // 1 MB chunks
135
            $gz = gzopen($nzbPath, 'rb');
136
137
            if (! $gz) {
0 ignored issues
show
$gz is of type resource, thus it always evaluated to false.
Loading history...
138
                throw new RuntimeException('Failed to open gzipped file for streaming.');
0 ignored issues
show
The type App\Http\Controllers\RuntimeException was not found. Did you mean RuntimeException? If so, make sure to prefix the type with \.
Loading history...
139
            }
140
141
            while (! gzeof($gz)) {
142
                echo gzread($gz, $bufferSize);
143
                flush(); // Ensure chunks are sent immediately
144
            }
145
146
            gzclose($gz);
147
        }, $cleanName.'.nzb', $headers);
148
    }
149
}
150