Files
UNIT3D/app/Http/Controllers/API/TorrentController.php
2019-11-28 17:21:56 -05:00

284 lines
9.4 KiB
PHP

<?php
/**
* NOTICE OF LICENSE.
*
* UNIT3D is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D
*
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
* @author HDVinnie
*/
namespace App\Http\Controllers\API;
use App\Helpers\Bencode;
use App\Helpers\MediaInfo;
use App\Helpers\TorrentHelper;
use App\Helpers\TorrentTools;
use App\Http\Resources\TorrentResource;
use App\Http\Resources\TorrentsResource;
use App\Models\Category;
use App\Models\TagTorrent;
use App\Models\Torrent;
use App\Models\TorrentFile;
use App\Repositories\ChatRepository;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class TorrentController extends BaseController
{
/**
* @var ChatRepository
*/
private $chat;
/**
* RequestController Constructor.
*
* @param ChatRepository $chat
*/
public function __construct(ChatRepository $chat)
{
$this->chat = $chat;
}
/**
* Display a listing of the resource.
*
* @return TorrentsResource
*/
public function index()
{
return new TorrentsResource(Torrent::with(['category', 'tags'])->latest()->paginate());
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$user = $request->user();
$requestFile = $request->file('torrent');
if ($request->hasFile('torrent') == false) {
return $this->sendError('Validation Error.', 'You Must Provide A Torrent File For Upload!');
} elseif ($requestFile->getError() != 0 && $requestFile->getClientOriginalExtension() != 'torrent') {
return $this->sendError('Validation Error.', 'You Must Provide A Valid Torrent File For Upload!');
}
$client = new \App\Services\MovieScrapper(config('api-keys.tmdb'), config('api-keys.tvdb'), config('api-keys.omdb'));
// Deplace and decode the torrent temporarily
$decodedTorrent = TorrentTools::normalizeTorrent($requestFile);
$infohash = Bencode::get_infohash($decodedTorrent);
$meta = Bencode::get_meta($decodedTorrent);
$fileName = uniqid().'.torrent'; // Generate a unique name
file_put_contents(getcwd().'/files/torrents/'.$fileName, Bencode::bencode($decodedTorrent));
// Find the right category
$category = Category::withCount('torrents')->findOrFail($request->input('category_id'));
// Create the torrent (DB)
$torrent = new Torrent();
$torrent->name = $request->input('name');
$torrent->slug = Str::slug($torrent->name);
$torrent->description = $request->input('description');
$torrent->mediainfo = self::anonymizeMediainfo($request->input('mediainfo'));
$torrent->info_hash = $infohash;
$torrent->file_name = $fileName;
$torrent->num_file = $meta['count'];
$torrent->announce = $decodedTorrent['announce'];
$torrent->size = $meta['size'];
$torrent->nfo = ($request->hasFile('nfo')) ? TorrentTools::getNfo($request->file('nfo')) : '';
$torrent->category_id = $category->id;
$torrent->user_id = $user->id;
$torrent->imdb = $request->input('imdb');
$torrent->tvdb = $request->input('tvdb');
$torrent->tmdb = $request->input('tmdb');
$torrent->mal = $request->input('mal');
$torrent->igdb = $request->input('igdb');
$torrent->type = $request->input('type');
$torrent->anon = $request->input('anonymous');
$torrent->stream = $request->input('stream');
$torrent->sd = $request->input('sd');
$torrent->internal = $request->input('internal');
$torrent->moderated_at = Carbon::now();
$torrent->moderated_by = 1; //System ID
// Validation
$v = validator($torrent->toArray(), [
'name' => 'required|unique:torrents',
'slug' => 'required',
'description' => 'required',
'info_hash' => 'required|unique:torrents',
'file_name' => 'required',
'num_file' => 'required|numeric',
'announce' => 'required',
'size' => 'required',
'category_id' => 'required',
'user_id' => 'required',
'imdb' => 'required|numeric',
'tvdb' => 'required|numeric',
'tmdb' => 'required|numeric',
'mal' => 'required|numeric',
'igdb' => 'required|numeric',
'type' => 'required',
'anon' => 'required',
'stream' => 'required',
'sd' => 'required',
]);
if ($v->fails()) {
if (file_exists(getcwd().'/files/torrents/'.$fileName)) {
unlink(getcwd().'/files/torrents/'.$fileName);
}
return $this->sendError('Validation Error.', $v->errors());
} else {
// Save The Torrent
$torrent->save();
// Count and save the torrent number in this category
$category->num_torrent = $category->torrents_count;
$category->save();
// Backup the files contained in the torrent
$fileList = TorrentTools::getTorrentFiles($decodedTorrent);
foreach ($fileList as $file) {
$f = new TorrentFile();
$f->name = $file['name'];
$f->size = $file['size'];
$f->torrent_id = $torrent->id;
$f->save();
unset($f);
}
$meta = null;
// Torrent Tags System
if ($torrent->category->tv_meta) {
if ($torrent->tmdb && $torrent->tmdb != 0) {
$meta = $client->scrape('tv', null, $torrent->tmdb);
} else {
$meta = $client->scrape('tv', 'tt'.$torrent->imdb);
}
}
if ($torrent->category->movie_meta) {
if ($torrent->tmdb && $torrent->tmdb != 0) {
$meta = $client->scrape('movie', null, $torrent->tmdb);
} else {
$meta = $client->scrape('movie', 'tt'.$torrent->imdb);
}
}
if (isset($meta) && $meta->genres) {
foreach ($meta->genres as $genre) {
$tag = new TagTorrent();
$tag->torrent_id = $torrent->id;
$tag->tag_name = $genre;
$tag->save();
}
}
// check for trusted user and update torrent
if ($user->group->is_trusted) {
$appurl = config('app.url');
$user = $torrent->user;
$user_id = $user->id;
$username = $user->username;
$anon = $torrent->anon;
// Announce To Shoutbox
if ($anon == 0) {
$this->chat->systemMessage(
"User [url={$appurl}/users/".$username.']'.$username."[/url] has uploaded [url={$appurl}/torrents/".$torrent->id.']'.$torrent->name.'[/url] grab it now! :slight_smile:'
);
} else {
$this->chat->systemMessage(
"An anonymous user has uploaded [url={$appurl}/torrents/".$torrent->id.']'.$torrent->name.'[/url] grab it now! :slight_smile:'
);
}
TorrentHelper::approveHelper($torrent->id);
}
return $this->sendResponse($torrent->toArray(), 'Torrent uploaded successfully.');
}
}
/**
* Display the specified resource.
*
* @param int $id
*
* @return TorrentResource
*/
public function show($id)
{
$torrent = Torrent::findOrFail($id);
TorrentResource::withoutWrapping();
return new TorrentResource($torrent);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
/**
* Anonymize A Torrent Media Info.
*
* @param $mediainfo
*
* @return array
*/
private static function anonymizeMediainfo($mediainfo)
{
if ($mediainfo === null) {
return;
}
$complete_name_i = strpos($mediainfo, 'Complete name');
if ($complete_name_i !== false) {
$path_i = strpos($mediainfo, ': ', $complete_name_i);
if ($path_i !== false) {
$path_i += 2;
$end_i = strpos($mediainfo, "\n", $path_i);
$path = substr($mediainfo, $path_i, $end_i - $path_i);
$new_path = MediaInfo::stripPath($path);
return substr_replace($mediainfo, $new_path, $path_i, strlen($path));
}
}
return $mediainfo;
}
}