mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-04-24 03:59:08 -05:00
Merge branch '7.x.x' into active-peers
This commit is contained in:
@@ -106,11 +106,11 @@ class SystemBot
|
||||
$this->target->save();
|
||||
|
||||
$bonTransactions = new BonTransactions();
|
||||
$bonTransactions->itemID = 0;
|
||||
$bonTransactions->bon_exchange_id = 0;
|
||||
$bonTransactions->name = 'gift';
|
||||
$bonTransactions->cost = $value;
|
||||
$bonTransactions->sender = $this->target->id;
|
||||
$bonTransactions->receiver = $recipient->id;
|
||||
$bonTransactions->sender_id = $this->target->id;
|
||||
$bonTransactions->receiver_id = $recipient->id;
|
||||
$bonTransactions->comment = $output;
|
||||
$bonTransactions->torrent_id = null;
|
||||
$bonTransactions->save();
|
||||
|
||||
@@ -107,8 +107,7 @@ class AutoBonAllocation extends Command
|
||||
->toArray();
|
||||
|
||||
$participaintSeeder = DB::table('history')
|
||||
->select(DB::raw('count(DISTINCT(history.torrent_id)) as value'), 'history.user_id')
|
||||
->join('torrents', 'torrents.id', 'history.torrent_id')
|
||||
->select(DB::raw('count(*) as value'), 'history.user_id')
|
||||
->where('history.active', 1)
|
||||
->where('history.seedtime', '>=', 2_592_000)
|
||||
->where('history.seedtime', '<', 2_592_000 * 2)
|
||||
@@ -117,8 +116,7 @@ class AutoBonAllocation extends Command
|
||||
->toArray();
|
||||
|
||||
$teamplayerSeeder = DB::table('history')
|
||||
->select(DB::raw('count(DISTINCT(history.torrent_id)) as value'), 'history.user_id')
|
||||
->join('torrents', 'torrents.id', 'history.torrent_id')
|
||||
->select(DB::raw('count(*) as value'), 'history.user_id')
|
||||
->where('history.active', 1)
|
||||
->where('history.seedtime', '>=', 2_592_000 * 2)
|
||||
->where('history.seedtime', '<', 2_592_000 * 3)
|
||||
@@ -127,8 +125,7 @@ class AutoBonAllocation extends Command
|
||||
->toArray();
|
||||
|
||||
$commitedSeeder = DB::table('history')
|
||||
->select(DB::raw('count(DISTINCT(history.torrent_id)) as value'), 'history.user_id')
|
||||
->join('torrents', 'torrents.id', 'history.torrent_id')
|
||||
->select(DB::raw('count(*) as value'), 'history.user_id')
|
||||
->where('history.active', 1)
|
||||
->where('history.seedtime', '>=', 2_592_000 * 3)
|
||||
->where('history.seedtime', '<', 2_592_000 * 6)
|
||||
@@ -137,8 +134,7 @@ class AutoBonAllocation extends Command
|
||||
->toArray();
|
||||
|
||||
$mvpSeeder = DB::table('history')
|
||||
->select(DB::raw('count(DISTINCT(history.torrent_id)) as value'), 'history.user_id')
|
||||
->join('torrents', 'torrents.id', 'history.torrent_id')
|
||||
->select(DB::raw('count(*) as value'), 'history.user_id')
|
||||
->where('history.active', 1)
|
||||
->where('history.seedtime', '>=', 2_592_000 * 6)
|
||||
->where('history.seedtime', '<', 2_592_000 * 12)
|
||||
@@ -147,8 +143,7 @@ class AutoBonAllocation extends Command
|
||||
->toArray();
|
||||
|
||||
$legendarySeeder = DB::table('history')
|
||||
->select(DB::raw('count(DISTINCT(history.torrent_id)) as value'), 'history.user_id')
|
||||
->join('torrents', 'torrents.id', 'history.torrent_id')
|
||||
->select(DB::raw('count(*) as value'), 'history.user_id')
|
||||
->where('history.active', 1)
|
||||
->where('history.seedtime', '>=', 2_592_000 * 12)
|
||||
->groupBy('history.user_id')
|
||||
@@ -250,22 +245,19 @@ class AutoBonAllocation extends Command
|
||||
//Move data from array to BonTransactions table
|
||||
/*foreach ($array as $key => $value) {
|
||||
$log = new BonTransactions();
|
||||
$log->itemID = 0;
|
||||
$log->bon_exchange_id = 0;
|
||||
$log->name = "Seeding Award";
|
||||
$log->cost = $value;
|
||||
$log->receiver = $key;
|
||||
$log->receiver_id = $key;
|
||||
$log->comment = "Seeding Award";
|
||||
$log->save();
|
||||
}*/
|
||||
|
||||
//Move data from array to Users table
|
||||
foreach ($array as $key => $value) {
|
||||
$user = User::find($key);
|
||||
|
||||
if ($user) {
|
||||
$user->seedbonus += $value;
|
||||
$user->save();
|
||||
}
|
||||
User::whereKey($key)->update([
|
||||
'seedbonus' => DB::raw('seedbonus + '.$value),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->comment('Automated BON Allocation Command Complete');
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition 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 Community Edition
|
||||
*
|
||||
* @author Roardom <roardom@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Peer;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @see \Tests\Unit\Console\Commands\AutoFlushPeersTest
|
||||
*/
|
||||
class AutoInsertPeers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'auto:insert_peers';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Inserts peers in batches';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
/**
|
||||
* MySql can handle a max of 65k placeholders per query,
|
||||
* and there are 14 fields on each peer that are updated.
|
||||
* (`agent`, `connectable`, `created_at`, `downloaded`, `id`, `ip`, `left`, `peer_id`, `port`, `seeder`, `torrent_id`, `updated_at`, `uploaded`, `user_id`).
|
||||
*/
|
||||
$peerPerCycle = intdiv(65_000, 14);
|
||||
|
||||
$key = config('cache.prefix').':peers:batch';
|
||||
$peerCount = Redis::connection('announce')->command('LLEN', [$key]);
|
||||
|
||||
for ($peersLeft = $peerCount; $peersLeft > 0; $peersLeft -= $peerPerCycle) {
|
||||
$peers = Redis::connection('announce')->command('LPOP', [$key, $peerPerCycle]);
|
||||
$peers = array_map('unserialize', $peers);
|
||||
|
||||
Peer::upsert(
|
||||
$peers,
|
||||
['user_id', 'torrent_id', 'peer_id'],
|
||||
[
|
||||
'peer_id',
|
||||
'ip',
|
||||
'port',
|
||||
'agent',
|
||||
'uploaded',
|
||||
'downloaded',
|
||||
'left',
|
||||
'seeder',
|
||||
'torrent_id',
|
||||
'user_id',
|
||||
'connectable'
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$this->comment('Automated insert peers command complete');
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Graveyard;
|
||||
use App\Models\Resurrection;
|
||||
use App\Models\History;
|
||||
use App\Models\PrivateMessage;
|
||||
use App\Models\Torrent;
|
||||
@@ -25,10 +25,10 @@ use Illuminate\Support\Carbon;
|
||||
/**
|
||||
* @see \Tests\Unit\Console\Commands\AutoGraveyardTest
|
||||
*/
|
||||
class AutoGraveyard extends Command
|
||||
class AutoRewardResurrection extends Command
|
||||
{
|
||||
/**
|
||||
* AutoGraveyards Constructor.
|
||||
* AutoRewardResurrection's Constructor.
|
||||
*/
|
||||
public function __construct(private readonly ChatRepository $chatRepository)
|
||||
{
|
||||
@@ -40,35 +40,35 @@ class AutoGraveyard extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'auto:graveyard';
|
||||
protected $signature = 'auto:reward_resurrection';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Automatically Checks Graveyard Records For Succesful Ressurections';
|
||||
protected $description = 'Automatically Hands Out Rewards For Successful Resurrections';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
foreach (Graveyard::where('rewarded', '!=', 1)->oldest()->get() as $reward) {
|
||||
$user = User::find($reward->user_id);
|
||||
foreach (Resurrection::where('rewarded', '!=', 1)->oldest()->get() as $resurrection) {
|
||||
$user = User::find($resurrection->user_id);
|
||||
|
||||
$torrent = Torrent::find($reward->torrent_id);
|
||||
$torrent = Torrent::find($resurrection->torrent_id);
|
||||
|
||||
if (isset($user, $torrent)) {
|
||||
$history = History::where('torrent_id', '=', $torrent->id)
|
||||
->where('user_id', '=', $user->id)
|
||||
->where('seedtime', '>=', $reward->seedtime)
|
||||
->where('seedtime', '>=', $resurrection->seedtime)
|
||||
->first();
|
||||
}
|
||||
|
||||
if (isset($history)) {
|
||||
$reward->rewarded = 1;
|
||||
$reward->save();
|
||||
$resurrection->rewarded = 1;
|
||||
$resurrection->save();
|
||||
|
||||
$user->fl_tokens += config('graveyard.reward');
|
||||
$user->save();
|
||||
@@ -101,6 +101,6 @@ class AutoGraveyard extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$this->comment('Automated Graveyard Rewards Command Complete');
|
||||
$this->comment('Automated Reward Resurrections Command Complete');
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,13 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
$schedule->command('auto:insert_peers')->everyMinute();
|
||||
$schedule->command('auto:upsert_histories')->everyFiveSeconds();
|
||||
$schedule->command('auto:update_user_last_actions')->everyFiveSeconds();
|
||||
$schedule->command('auto:delete_stopped_peers')->everyTwoMinutes();
|
||||
$schedule->command('auto:group ')->daily();
|
||||
$schedule->command('auto:nerdstat ')->hourly();
|
||||
$schedule->command('auto:graveyard')->daily();
|
||||
$schedule->command('auto:reward_resurrection')->daily();
|
||||
$schedule->command('auto:highspeed_tag')->hourly();
|
||||
$schedule->command('auto:prewarning')->hourly();
|
||||
$schedule->command('auto:warning')->daily();
|
||||
@@ -53,7 +54,7 @@ class Kernel extends ConsoleKernel
|
||||
$schedule->command('auto:torrent_balance')->hourly();
|
||||
//$schedule->command('auto:ban_disposable_users')->weekends();
|
||||
//$schedule->command('backup:clean')->daily();
|
||||
//$schedule->command('backup:run')->daily();
|
||||
//$schedule->command('backup:run --only-db')->daily();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,6 @@ class TorrentTools
|
||||
|
||||
// Whitelisted keys
|
||||
$result = array_intersect_key($result, [
|
||||
'announce' => '',
|
||||
'comment' => '',
|
||||
'created by' => '',
|
||||
'encoding' => '',
|
||||
@@ -46,8 +45,6 @@ class TorrentTools
|
||||
'name' => '',
|
||||
'piece length' => '',
|
||||
'pieces' => '',
|
||||
'private' => '',
|
||||
'source' => '',
|
||||
]);
|
||||
|
||||
// The PID will be set if an user downloads the torrent, but for
|
||||
@@ -63,7 +60,7 @@ class TorrentTools
|
||||
$result['created by'] = config('torrent.created_by', '');
|
||||
}
|
||||
|
||||
$comment = config('torrent.comment', null);
|
||||
$comment = config('torrent.comment');
|
||||
|
||||
if ($comment !== null) {
|
||||
$result['comment'] = $comment;
|
||||
|
||||
@@ -21,13 +21,16 @@ use App\Http\Resources\TorrentsResource;
|
||||
use App\Models\Category;
|
||||
use App\Models\FeaturedTorrent;
|
||||
use App\Models\Keyword;
|
||||
use App\Models\Movie;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\TorrentFile;
|
||||
use App\Models\Tv;
|
||||
use App\Models\User;
|
||||
use App\Repositories\ChatRepository;
|
||||
use App\Services\Tmdb\TMDBScraper;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
@@ -53,10 +56,40 @@ class TorrentController extends BaseController
|
||||
*/
|
||||
public function index(): TorrentsResource
|
||||
{
|
||||
return new TorrentsResource(Torrent::with(['category', 'type', 'resolution'])
|
||||
$torrents = Torrent::with(['user:id,username', 'category', 'type', 'resolution', 'region', 'distributor'])
|
||||
->select('*')
|
||||
->selectRaw("
|
||||
CASE
|
||||
WHEN category_id IN (SELECT `id` from `categories` where `movie_meta` = 1) THEN 'movie'
|
||||
WHEN category_id IN (SELECT `id` from `categories` where `tv_meta` = 1) THEN 'tv'
|
||||
END as meta
|
||||
")
|
||||
->latest('sticky')
|
||||
->latest('bumped_at')
|
||||
->paginate(25));
|
||||
->paginate(25);
|
||||
|
||||
$movieIds = $torrents->getCollection()->where('meta', '=', 'movie')->pluck('tmdb');
|
||||
$tvIds = $torrents->getCollection()->where('meta', '=', 'tv')->pluck('tmdb');
|
||||
|
||||
$movies = Movie::select(['id', 'poster'])->with('genres:name')->whereIntegerInRaw('id', $movieIds)->get()->keyBy('id');
|
||||
$tv = Tv::select(['id', 'poster'])->with('genres:name')->whereIntegerInRaw('id', $tvIds)->get()->keyBy('id');
|
||||
|
||||
$torrents = $torrents->through(function ($torrent) use ($movies, $tv) {
|
||||
switch ($torrent->meta) {
|
||||
case 'movie':
|
||||
$torrent->setRelation('movie', $movies[$torrent->tmdb] ?? collect());
|
||||
|
||||
break;
|
||||
case 'tv':
|
||||
$torrent->setRelation('tv', $tv[$torrent->tmdb] ?? collect());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $torrent;
|
||||
});
|
||||
|
||||
return new TorrentsResource($torrents);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,7 +399,14 @@ class TorrentController extends BaseController
|
||||
$cacheKey = $url.'?'.$queryString;
|
||||
|
||||
$torrents = cache()->remember($cacheKey, 300, function () use ($request, $isRegex) {
|
||||
return Torrent::with(['user:id,username,group_id', 'category', 'type', 'resolution'])
|
||||
$torrents = Torrent::with(['user:id,username', 'category', 'type', 'resolution', 'distributor', 'region'])
|
||||
->select('*')
|
||||
->selectRaw("
|
||||
CASE
|
||||
WHEN category_id IN (SELECT `id` from `categories` where `movie_meta` = 1) THEN 'movie'
|
||||
WHEN category_id IN (SELECT `id` from `categories` where `tv_meta` = 1) THEN 'tv'
|
||||
END as meta
|
||||
")
|
||||
->when($request->filled('name'), fn ($query) => $query->ofName($request->name, $isRegex($request->name)))
|
||||
->when($request->filled('description'), fn ($query) => $query->ofDescription($request->description, $isRegex($request->description)))
|
||||
->when($request->filled('mediainfo'), fn ($query) => $query->ofMediainfo($request->mediainfo, $isRegex($request->mediainfo)))
|
||||
@@ -401,6 +441,29 @@ class TorrentController extends BaseController
|
||||
->latest('sticky')
|
||||
->orderBy($request->input('sortField') ?? $this->sortField, $request->input('sortDirection') ?? $this->sortDirection)
|
||||
->cursorPaginate($request->input('perPage') ?? $this->perPage);
|
||||
|
||||
$movieIds = $torrents->getCollection()->where('meta', '=', 'movie')->pluck('tmdb');
|
||||
$tvIds = $torrents->getCollection()->where('meta', '=', 'tv')->pluck('tmdb');
|
||||
|
||||
$movies = Movie::select(['id', 'poster'])->with('genres:name')->whereIntegerInRaw('id', $movieIds)->get()->keyBy('id');
|
||||
$tv = Tv::select(['id', 'poster'])->with('genres:name')->whereIntegerInRaw('id', $tvIds)->get()->keyBy('id');
|
||||
|
||||
$torrents = $torrents->through(function ($torrent) use ($movies, $tv) {
|
||||
switch ($torrent->meta) {
|
||||
case 'movie':
|
||||
$torrent->setRelation('movie', $movies[$torrent->tmdb] ?? collect());
|
||||
|
||||
break;
|
||||
case 'tv':
|
||||
$torrent->setRelation('tv', $tv[$torrent->tmdb] ?? collect());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $torrent;
|
||||
});
|
||||
|
||||
return $torrents;
|
||||
});
|
||||
|
||||
if ($torrents !== null) {
|
||||
|
||||
@@ -388,11 +388,6 @@ class AnnounceController extends Controller
|
||||
$torrentId = Redis::connection('cache')->command('HGET', [$cacheKey, hex2bin($infoHash)]);
|
||||
|
||||
$torrent = Torrent::withoutGlobalScope(ApprovedScope::class)
|
||||
->with([
|
||||
'peers' => fn ($query) => $query
|
||||
->select(['id', 'torrent_id', 'peer_id', 'user_id', 'left', 'seeder', 'port', 'updated_at'])
|
||||
->selectRaw('INET6_NTOA(ip) as ip')
|
||||
])
|
||||
->select(['id', 'free', 'doubleup', 'seeders', 'leechers', 'times_completed', 'status'])
|
||||
->when(
|
||||
$torrentId === null,
|
||||
@@ -426,6 +421,16 @@ class AnnounceController extends Controller
|
||||
new TrackerException(151, [':status' => 'POSTPONED In Moderation'])
|
||||
);
|
||||
|
||||
// Don't use eager loading so that we can make use of mysql prepared statement caching.
|
||||
// If we use eager loading, then laravel will use `where torrent_id in (123)` instead of `where torrent_id = ?`
|
||||
$torrent->setRelation(
|
||||
'peers',
|
||||
Peer::select(['id', 'torrent_id', 'peer_id', 'user_id', 'left', 'seeder', 'port', 'updated_at'])
|
||||
->selectRaw('INET6_NTOA(ip) as ip')
|
||||
->where('torrent_id', '=', $torrent->id)
|
||||
->get()
|
||||
);
|
||||
|
||||
return $torrent;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,11 +53,11 @@ class ApprovedRequestFillController extends Controller
|
||||
]);
|
||||
|
||||
BonTransactions::create([
|
||||
'itemID' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $torrentRequest->bounty,
|
||||
'receiver' => $torrentRequest->filled_by,
|
||||
'comment' => sprintf('%s has filled %s and has been awarded %s BONUS.', $filler->username, $torrentRequest->name, $torrentRequest->bounty),
|
||||
'bon_exchange_id' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $torrentRequest->bounty,
|
||||
'receiver_id' => $torrentRequest->filled_by,
|
||||
'comment' => sprintf('%s has filled %s and has been awarded %s BONUS.', $filler->username, $torrentRequest->name, $torrentRequest->bounty),
|
||||
]);
|
||||
|
||||
$filler->increment('seedbonus', $torrentRequest->bounty);
|
||||
@@ -107,11 +107,11 @@ class ApprovedRequestFillController extends Controller
|
||||
$refunded = min($torrentRequest->bounty, $filler->seedbonus);
|
||||
|
||||
BonTransactions::create([
|
||||
'itemID' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $refunded,
|
||||
'sender' => $torrentRequest->filled_by,
|
||||
'comment' => sprintf('%s has had %s unfilled and has forfeited %s BONUS.', $filler->username, $torrentRequest->name, $refunded),
|
||||
'bon_exchange_id' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $refunded,
|
||||
'sender_id' => $torrentRequest->filled_by,
|
||||
'comment' => sprintf('%s has had %s unfilled and has forfeited %s BONUS.', $filler->username, $torrentRequest->name, $refunded),
|
||||
]);
|
||||
|
||||
$filler->decrement('seedbonus', $refunded);
|
||||
|
||||
@@ -50,11 +50,11 @@ class BountyController extends Controller
|
||||
$torrentRequest->save();
|
||||
|
||||
BonTransactions::create([
|
||||
'itemID' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $request->float('seedbonus'),
|
||||
'sender' => $user->id,
|
||||
'comment' => sprintf('adding bonus to %s', $torrentRequest->name),
|
||||
'bon_exchange_id' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $request->float('seedbonus'),
|
||||
'sender_id' => $user->id,
|
||||
'comment' => sprintf('adding bonus to %s', $torrentRequest->name),
|
||||
]);
|
||||
|
||||
$user->decrement('seedbonus', $request->float('seedbonus'));
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
namespace App\Http\Controllers\MediaHub;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Category;
|
||||
use App\Models\Person;
|
||||
|
||||
class PersonController extends Controller
|
||||
@@ -33,14 +32,7 @@ class PersonController extends Controller
|
||||
public function show(int $id): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
{
|
||||
return view('mediahub.person.show', [
|
||||
'person' => Person::with([
|
||||
'tv' => fn ($query) => $query->has('torrents'),
|
||||
'tv.genres',
|
||||
'movie' => fn ($query) => $query->has('torrents'),
|
||||
'movie.genres'
|
||||
])->findOrFail($id),
|
||||
'movieCategoryIds' => Category::where('movie_meta', '=', 1)->pluck('id')->toArray(),
|
||||
'tvCategoryIds' => Category::where('tv_meta', '=', 1)->pluck('id')->toArray()
|
||||
'person' => Person::findOrFail($id),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +138,11 @@ class RequestController extends Controller
|
||||
]);
|
||||
|
||||
BonTransactions::create([
|
||||
'itemID' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $request->bounty,
|
||||
'sender' => $user->id,
|
||||
'comment' => sprintf('new request - %s', $request->name),
|
||||
'bon_exchange_id' => 0,
|
||||
'name' => 'request',
|
||||
'cost' => $request->bounty,
|
||||
'sender_id' => $user->id,
|
||||
'comment' => sprintf('new request - %s', $request->name),
|
||||
]);
|
||||
|
||||
$user->decrement('seedbonus', $request->bounty);
|
||||
|
||||
@@ -62,9 +62,7 @@ class RequestFillController extends Controller
|
||||
*/
|
||||
public function destroy(Request $request, TorrentRequest $torrentRequest): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
abort_unless($request->user()->group->is_modo, 403);
|
||||
abort_unless($request->user()->id === $torrentRequest->user_id || $request->user()->group->is_modo, 403);
|
||||
|
||||
$torrentRequest->update([
|
||||
'filled_by' => null,
|
||||
@@ -72,10 +70,11 @@ class RequestFillController extends Controller
|
||||
'torrent_id' => null,
|
||||
]);
|
||||
|
||||
$sender = $torrentRequest->filled_anon ? 'Anonymous' : $torrentRequest->user()->username;
|
||||
$filler = $torrentRequest->user;
|
||||
|
||||
if ($filler->acceptsNotification($request->user(), $filler, 'request', 'show_request_fill_reject')) {
|
||||
$filler->notify(new NewRequestFillReject('torrent', $user->username, $torrentRequest));
|
||||
$filler->notify(new NewRequestFillReject('torrent', $sender, $torrentRequest));
|
||||
}
|
||||
|
||||
return to_route('requests.show', ['torrentRequest' => $torrentRequest])
|
||||
|
||||
@@ -385,4 +385,22 @@ class TopicController extends Controller
|
||||
])
|
||||
->withFragment('post-'.$postId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the appropriate topic page for the latest post.
|
||||
*/
|
||||
public function latestPermalink(int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$post = Post::query()
|
||||
->selectRaw('MAX(id) as id')
|
||||
->selectRaw('count(*) as post_count')
|
||||
->where('topic_id', '=', $id)
|
||||
->first();
|
||||
|
||||
return to_route('topics.show', [
|
||||
'id' => $id,
|
||||
'page' => intdiv($post?->post_count === null ? 0 : $post->post_count - 1, 25) + 1
|
||||
])
|
||||
->withFragment('post-'.($post?->id ?? 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ class TorrentController extends Controller
|
||||
'trailer' => $trailer,
|
||||
'platforms' => $platforms,
|
||||
'total_tips' => BonTransactions::where('torrent_id', '=', $id)->sum('cost'),
|
||||
'user_tips' => BonTransactions::where('torrent_id', '=', $id)->where('sender', '=', $user->id)->sum('cost'),
|
||||
'user_tips' => BonTransactions::where('torrent_id', '=', $id)->where('sender_id', '=', $user->id)->sum('cost'),
|
||||
'featured' => $torrent->featured == 1 ? FeaturedTorrent::where('torrent_id', '=', $id)->first() : null,
|
||||
'mediaInfo' => $torrent->mediainfo !== null ? (new MediaInfo())->parse($torrent->mediainfo) : null,
|
||||
'last_seed_activity' => History::where('torrent_id', '=', $torrent->id)->where('seeder', '=', 1)->latest('updated_at')->first(),
|
||||
|
||||
@@ -40,10 +40,10 @@ class GiftController extends Controller
|
||||
return view('user.gift.index', [
|
||||
'user' => $user,
|
||||
'gifts' => BonTransactions::query()
|
||||
->with(['senderObj.group', 'receiverObj.group'])
|
||||
->where(fn ($query) => $query->where('sender', '=', $user->id)->orwhere('receiver', '=', $user->id))
|
||||
->with(['sender.group', 'receiver.group'])
|
||||
->where(fn ($query) => $query->where('sender_id', '=', $user->id)->orwhere('receiver_id', '=', $user->id))
|
||||
->where('name', '=', 'gift')
|
||||
->latest('date_actioned')
|
||||
->latest()
|
||||
->paginate(25),
|
||||
'bon' => $user->getSeedbonus(),
|
||||
'sentGifts' => $user->sentGifts()->sum('cost'),
|
||||
@@ -76,13 +76,13 @@ class GiftController extends Controller
|
||||
$sender->decrement('seedbonus', $request->cost);
|
||||
|
||||
$bonTransactions = BonTransactions::create([
|
||||
'itemID' => 0,
|
||||
'name' => 'gift',
|
||||
'cost' => $request->cost,
|
||||
'sender' => $sender->id,
|
||||
'receiver' => $receiver->id,
|
||||
'comment' => $request->comment,
|
||||
'torrent_id' => null,
|
||||
'bon_exchange_id' => 0,
|
||||
'name' => 'gift',
|
||||
'cost' => $request->cost,
|
||||
'sender_id' => $sender->id,
|
||||
'receiver_id' => $receiver->id,
|
||||
'comment' => $request->comment,
|
||||
'torrent_id' => null,
|
||||
]);
|
||||
|
||||
if ($receiver->acceptsNotification($sender, $receiver, 'bon', 'show_bon_gift')) {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Graveyard;
|
||||
use App\Models\Resurrection;
|
||||
use App\Models\History;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\User;
|
||||
@@ -56,16 +56,16 @@ class ResurrectionController extends Controller
|
||||
->withErrors('This torrent is not older than 30 days.');
|
||||
}
|
||||
|
||||
$isPending = Graveyard::whereBelongsTo($torrent)->where('rewarded', '=', 0)->exists();
|
||||
$isPending = Resurrection::whereBelongsTo($torrent)->where('rewarded', '=', 0)->exists();
|
||||
|
||||
if ($isPending) {
|
||||
return to_route('torrents.show', ['id' => $torrent->id])
|
||||
->withErrors(trans('graveyard.resurrect-failed-pending'));
|
||||
}
|
||||
|
||||
$history = History::whereBelongsTo($torrent)->whereBelongsTo($user)->sole();
|
||||
$history = History::whereBelongsTo($torrent)->whereBelongsTo($user)->first();
|
||||
|
||||
Graveyard::create([
|
||||
Resurrection::create([
|
||||
'user_id' => $user->id,
|
||||
'torrent_id' => $torrent->id,
|
||||
'seedtime' => config('graveyard.time') + $history?->seedtime ?? 0,
|
||||
@@ -78,7 +78,7 @@ class ResurrectionController extends Controller
|
||||
/**
|
||||
* Cancel A Ressurection.
|
||||
*/
|
||||
public function destroy(Request $request, User $user, Graveyard $resurrection): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(Request $request, User $user, Resurrection $resurrection): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
abort_unless($request->user()->group->is_modo || $request->user()->is($user), 403);
|
||||
|
||||
|
||||
@@ -38,10 +38,10 @@ class TipController extends Controller
|
||||
|
||||
return view('user.tip.index', [
|
||||
'user' => $user,
|
||||
'tips' => BonTransactions::with(['senderObj.group', 'receiverObj.group', 'torrent'])
|
||||
->where(fn ($query) => $query->where('sender', '=', $user->id)->orwhere('receiver', '=', $user->id))
|
||||
'tips' => BonTransactions::with(['sender.group', 'receiver.group', 'torrent'])
|
||||
->where(fn ($query) => $query->where('sender_id', '=', $user->id)->orwhere('receiver_id', '=', $user->id))
|
||||
->where('name', '=', 'tip')
|
||||
->latest('date_actioned')
|
||||
->latest()
|
||||
->paginate(25),
|
||||
'bon' => $user->getSeedbonus(),
|
||||
'sentTips' => $user->sentTips()->sum('cost'),
|
||||
@@ -70,14 +70,14 @@ class TipController extends Controller
|
||||
$user->decrement('seedbonus', $tipAmount);
|
||||
|
||||
BonTransactions::create([
|
||||
'itemID' => 0,
|
||||
'name' => 'tip',
|
||||
'cost' => $tipAmount,
|
||||
'sender' => $user->id,
|
||||
'receiver' => $recipient->id,
|
||||
'comment' => 'tip',
|
||||
'post_id' => $request->has('post') ? $tipable->id : null,
|
||||
'torrent_id' => $request->has('torrent') ? $tipable->id : null,
|
||||
'bon_exchange_id' => 0,
|
||||
'name' => 'tip',
|
||||
'cost' => $tipAmount,
|
||||
'sender_id' => $user->id,
|
||||
'receiver_id' => $recipient->id,
|
||||
'comment' => 'tip',
|
||||
'post_id' => $request->has('post') ? $tipable->id : null,
|
||||
'torrent_id' => $request->has('torrent') ? $tipable->id : null,
|
||||
]);
|
||||
|
||||
if ($request->has('torrent')) {
|
||||
|
||||
@@ -23,6 +23,7 @@ use App\Models\User;
|
||||
use App\Services\Unit3dAnnounce;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* @see \Tests\Feature\Http\Controllers\BonusControllerTest
|
||||
@@ -59,51 +60,70 @@ class TransactionController extends Controller
|
||||
abort_unless($request->user()->is($user), 403);
|
||||
|
||||
$request = (object) $request->validated();
|
||||
$item = BonExchange::findOrFail($request->exchange);
|
||||
|
||||
switch (true) {
|
||||
case $item->upload:
|
||||
$user->increment('uploaded', $item->value);
|
||||
return DB::transaction(function () use ($request, $user) {
|
||||
$user->refresh();
|
||||
$bonExchange = BonExchange::findOrFail($request->exchange);
|
||||
|
||||
break;
|
||||
case $item->download:
|
||||
$user->decrement('downloaded', $item->value);
|
||||
if ($bonExchange->cost > $user->seedbonus) {
|
||||
return back()->withErrors('Not enough BON.');
|
||||
}
|
||||
|
||||
break;
|
||||
case $item->personal_freeleech:
|
||||
PersonalFreeleech::create(['user_id' => $user->id]);
|
||||
switch (true) {
|
||||
case $bonExchange->upload:
|
||||
$user->increment('uploaded', $bonExchange->value);
|
||||
|
||||
cache()->put('personal_freeleech:'.$user->id, true);
|
||||
break;
|
||||
case $bonExchange->download:
|
||||
if ($user->downloaded < $bonExchange->value) {
|
||||
return back()->withErrors('Not enough download.');
|
||||
}
|
||||
|
||||
Unit3dAnnounce::addPersonalFreeleech($user->id);
|
||||
$user->decrement('downloaded', $bonExchange->value);
|
||||
|
||||
PrivateMessage::create([
|
||||
'sender_id' => 1,
|
||||
'receiver_id' => $user->id,
|
||||
'subject' => trans('bon.pm-subject'),
|
||||
'message' => sprintf(trans('bon.pm-message'), Carbon::now()->addDays(1)->toDayDateTimeString()).config('app.timezone').'[/b]!
|
||||
break;
|
||||
case $bonExchange->personal_freeleech:
|
||||
if (cache()->get('personal_freeleech:'.$user->id)) {
|
||||
return back()->withErrors('Your previous personal freeleech is still active.');
|
||||
}
|
||||
|
||||
PersonalFreeleech::create(['user_id' => $user->id]);
|
||||
|
||||
cache()->put('personal_freeleech:'.$user->id, true);
|
||||
|
||||
Unit3dAnnounce::addPersonalFreeleech($user->id);
|
||||
|
||||
PrivateMessage::create([
|
||||
'sender_id' => 1,
|
||||
'receiver_id' => $user->id,
|
||||
'subject' => trans('bon.pm-subject'),
|
||||
'message' => sprintf(trans('bon.pm-message'), Carbon::now()->addDays(1)->toDayDateTimeString()).config('app.timezone').'[/b]!
|
||||
[color=red][b]'.trans('common.system-message').'[/b][/color]',
|
||||
]);
|
||||
]);
|
||||
|
||||
break;
|
||||
case $item->invite:
|
||||
$user->increment('invites', $item->value);
|
||||
break;
|
||||
case $bonExchange->invite:
|
||||
if ($user->invites >= config('other.max_unused_user_invites', 1)) {
|
||||
return back()->withErrors('You already have the maximum amount of unused invites allowed per user.');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
$user->increment('invites', $bonExchange->value);
|
||||
|
||||
BonTransactions::create([
|
||||
'itemID' => $item->id,
|
||||
'name' => $item->description,
|
||||
'cost' => $item->value,
|
||||
'sender' => $user->id,
|
||||
'comment' => $item->description,
|
||||
'torrent_id' => null,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
$user->decrement('seedbonus', $item->cost);
|
||||
BonTransactions::create([
|
||||
'bon_exchange_id' => $bonExchange->id,
|
||||
'name' => $bonExchange->description,
|
||||
'cost' => $bonExchange->value,
|
||||
'sender_id' => $user->id,
|
||||
'comment' => $bonExchange->description,
|
||||
'torrent_id' => null,
|
||||
]);
|
||||
|
||||
return to_route('users.transactions.create', ['user' => $user])
|
||||
->withSuccess(trans('bon.success'));
|
||||
$user->decrement('seedbonus', $bonExchange->cost);
|
||||
|
||||
return back()->withSuccess(trans('bon.success'));
|
||||
}, 5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ class UserController extends Controller
|
||||
->with(['torrenttitle', 'warneduser'])
|
||||
->latest('created_at')
|
||||
->paginate(10, ['*'], 'deletedWarningsPage'),
|
||||
'boughtUpload' => BonTransactions::where('sender', '=', $user->id)->where([['name', 'like', '%Upload%']])->sum('cost'),
|
||||
// 'boughtDownload' => BonTransactions::where('sender', '=', $user->id)->where([['name', 'like', '%Download%']])->sum('cost'),
|
||||
'boughtUpload' => BonTransactions::where('sender_id', '=', $user->id)->where([['name', 'like', '%Upload%']])->sum('cost'),
|
||||
// 'boughtDownload' => BonTransactions::where('sender_id', '=', $user->id)->where([['name', 'like', '%Download%']])->sum('cost'),
|
||||
'invitedBy' => Invite::where('accepted_by', '=', $user->id)->first(),
|
||||
'clients' => $user->peers()
|
||||
->select('agent', 'port')
|
||||
|
||||
@@ -35,7 +35,7 @@ class BbcodeInput extends Component
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
$this->isRequired = $required;
|
||||
$this->contentBbcode = $content ?? old($name) ?? '';
|
||||
$this->contentBbcode = $content === null ? (old($name) ?? '') : htmlspecialchars_decode($content);
|
||||
}
|
||||
|
||||
final public function updatedIsPreviewEnabled(): void
|
||||
|
||||
@@ -24,21 +24,25 @@ class PersonCredit extends Component
|
||||
{
|
||||
public Person $person;
|
||||
|
||||
public ?Occupations $occupation = null;
|
||||
public ?int $occupationId = null;
|
||||
|
||||
public $queryString = [
|
||||
'occupationId',
|
||||
];
|
||||
|
||||
final public function mount(): void
|
||||
{
|
||||
$this->occupation = match (true) {
|
||||
0 < $this->createdCount => Occupations::CREATOR,
|
||||
0 < $this->directedCount => Occupations::DIRECTOR,
|
||||
0 < $this->writtenCount => Occupations::WRITER,
|
||||
0 < $this->producedCount => Occupations::PRODUCER,
|
||||
0 < $this->composedCount => Occupations::COMPOSER,
|
||||
0 < $this->cinematographedCount => Occupations::CINEMATOGRAPHER,
|
||||
0 < $this->editedCount => Occupations::EDITOR,
|
||||
0 < $this->productionDesignedCount => Occupations::PRODUCTION_DESIGNER,
|
||||
0 < $this->artDirectedCount => Occupations::ART_DIRECTOR,
|
||||
0 < $this->actedCount => Occupations::ACTOR,
|
||||
$this->occupationId ??= match (true) {
|
||||
0 < $this->createdCount => Occupations::CREATOR->value,
|
||||
0 < $this->directedCount => Occupations::DIRECTOR->value,
|
||||
0 < $this->writtenCount => Occupations::WRITER->value,
|
||||
0 < $this->producedCount => Occupations::PRODUCER->value,
|
||||
0 < $this->composedCount => Occupations::COMPOSER->value,
|
||||
0 < $this->cinematographedCount => Occupations::CINEMATOGRAPHER->value,
|
||||
0 < $this->editedCount => Occupations::EDITOR->value,
|
||||
0 < $this->productionDesignedCount => Occupations::PRODUCTION_DESIGNER->value,
|
||||
0 < $this->artDirectedCount => Occupations::ART_DIRECTOR->value,
|
||||
0 < $this->actedCount => Occupations::ACTOR->value,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
@@ -108,24 +112,22 @@ class PersonCredit extends Component
|
||||
|
||||
final public function getMediasProperty(): \Illuminate\Support\Collection
|
||||
{
|
||||
if ($this->occupation === null) {
|
||||
if ($this->occupationId === null) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
$movies = $this->person
|
||||
->movie()
|
||||
->whereHas('torrents')
|
||||
->with('genres', 'directors')
|
||||
->wherePivot('occupation_id', '=', $this->occupation)
|
||||
->wherePivot('occupation_id', '=', $this->occupationId)
|
||||
->orderBy('release_date')
|
||||
->get()
|
||||
// Since the credits table unique index has nullable columns, we get duplicate credits, which means duplicate movies
|
||||
->unique();
|
||||
$tv = $this->person
|
||||
->tv()
|
||||
->whereHas('torrents')
|
||||
->with('genres', 'creators')
|
||||
->wherePivot('occupation_id', '=', $this->occupation)
|
||||
->wherePivot('occupation_id', '=', $this->occupationId)
|
||||
->orderBy('first_air_date')
|
||||
->get()
|
||||
// Since the credits table unique index has nullable columns, we get duplicate credits, which means duplicate tv
|
||||
@@ -302,19 +304,23 @@ class PersonCredit extends Component
|
||||
$medias = collect();
|
||||
|
||||
foreach ($movies as $movie) {
|
||||
$media = $movie;
|
||||
$media->meta = 'movie';
|
||||
$media->torrents = $torrents['movie'][$movie->id];
|
||||
$media->category_id = $media->torrents->pop();
|
||||
$medias->add($media);
|
||||
if ($torrents->has('movie') && $torrents['movie']->has($movie->id)) {
|
||||
$media = $movie;
|
||||
$media->meta = 'movie';
|
||||
$media->torrents = $torrents['movie'][$movie->id];
|
||||
$media->category_id = $media->torrents->pop();
|
||||
$medias->add($media);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($tv as $show) {
|
||||
$media = $show;
|
||||
$media->meta = 'tv';
|
||||
$media->torrents = $torrents['tv'][$show->id];
|
||||
$media->category_id = $media->torrents->pop();
|
||||
$medias->add($media);
|
||||
if ($torrents->has('tv') && $torrents['tv']->has($show->id)) {
|
||||
$media = $show;
|
||||
$media->meta = 'tv';
|
||||
$media->torrents = $torrents['tv'][$show->id];
|
||||
$media->category_id = $media->torrents->pop();
|
||||
$medias->add($media);
|
||||
}
|
||||
}
|
||||
|
||||
return $medias;
|
||||
|
||||
@@ -22,7 +22,16 @@ class QuickSearchDropdown extends Component
|
||||
'movies' => Movie::query()
|
||||
->select(['id', 'poster', 'title', 'release_date'])
|
||||
->selectRaw("concat(title, ' ', release_date) as title_and_year")
|
||||
->having('title_and_year', 'LIKE', $search)
|
||||
->when(
|
||||
preg_match('/^\d+$/', $this->quicksearchText),
|
||||
fn ($query) => $query->where('id', '=', $this->quicksearchText),
|
||||
fn ($query) => $query
|
||||
->when(
|
||||
preg_match('/tt0*(?=(\d{7,}))/', $this->quicksearchText, $matches),
|
||||
fn ($query) => $query->where('imdb_id', '=', $matches[1]),
|
||||
fn ($query) => $query->having('title_and_year', 'LIKE', $search),
|
||||
)
|
||||
)
|
||||
->has('torrents')
|
||||
->oldest('title')
|
||||
->take(10)
|
||||
@@ -30,7 +39,16 @@ class QuickSearchDropdown extends Component
|
||||
'series' => Tv::query()
|
||||
->select(['id', 'poster', 'name', 'first_air_date'])
|
||||
->selectRaw("concat(name, ' ', first_air_date) as title_and_year")
|
||||
->having('title_and_year', 'LIKE', $search)
|
||||
->when(
|
||||
preg_match('/^\d+$/', $this->quicksearchText),
|
||||
fn ($query) => $query->where('id', '=', $this->quicksearchText),
|
||||
fn ($query) => $query
|
||||
->when(
|
||||
preg_match('/tt0*(?=(\d{7,}))/', $this->quicksearchText, $matches),
|
||||
fn ($query) => $query->where('imdb_id', '=', $matches[1]),
|
||||
fn ($query) => $query->having('title_and_year', 'LIKE', $search),
|
||||
)
|
||||
)
|
||||
->has('torrents')
|
||||
->oldest('name')
|
||||
->take(10)
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Subtitle;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\User;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
@@ -30,6 +31,8 @@ class SubtitleSearch extends Component
|
||||
|
||||
public string $language = '';
|
||||
|
||||
public string $username = '';
|
||||
|
||||
public string $sortField = 'created_at';
|
||||
|
||||
public string $sortDirection = 'desc';
|
||||
@@ -54,6 +57,15 @@ class SubtitleSearch extends Component
|
||||
return $query->whereIntegerInRaw('torrent_id', $torrents);
|
||||
})
|
||||
->when($this->language, fn ($query) => $query->where('language_id', '=', $this->language))
|
||||
->when(
|
||||
$this->username,
|
||||
fn ($query) => $query
|
||||
->whereIn('user_id', User::select('id')->where('username', '=', $this->username))
|
||||
->when(
|
||||
! auth()->user()->group->is_modo,
|
||||
fn ($query) => $query->where(fn ($query) => $query->where('anon', '=', false)->orWhere('user_id', '=', auth()->id()))
|
||||
)
|
||||
)
|
||||
->orderBy($this->sortField, $this->sortDirection)
|
||||
->paginate($this->perPage);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Graveyard;
|
||||
use App\Models\Resurrection;
|
||||
use App\Models\User;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
@@ -59,23 +59,23 @@ class UserResurrections extends Component
|
||||
|
||||
final public function getResurrectionsProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
{
|
||||
return Graveyard::query()
|
||||
return Resurrection::query()
|
||||
->select([
|
||||
'graveyard.id',
|
||||
'graveyard.created_at',
|
||||
'graveyard.seedtime',
|
||||
'graveyard.rewarded',
|
||||
'graveyard.torrent_id'
|
||||
'resurrections.id',
|
||||
'resurrections.created_at',
|
||||
'resurrections.seedtime',
|
||||
'resurrections.rewarded',
|
||||
'resurrections.torrent_id'
|
||||
])
|
||||
->with(['torrent', 'user'])
|
||||
->leftJoin('torrents', 'torrents.id', '=', 'graveyard.torrent_id')
|
||||
->where('graveyard.user_id', '=', $this->user->id)
|
||||
->leftJoin('torrents', 'torrents.id', '=', 'resurrections.torrent_id')
|
||||
->where('resurrections.user_id', '=', $this->user->id)
|
||||
->when($this->rewarded === 'include', fn ($query) => $query->where('rewarded', '=', 1))
|
||||
->when($this->rewarded === 'exclude', fn ($query) => $query->where('rewarded', '=', 0))
|
||||
->when($this->name, fn ($query) => $query->where('name', 'like', '%'.str_replace(' ', '%', $this->name).'%'))
|
||||
->when(
|
||||
\in_array($this->sortField, ['created_at', 'seedtime', 'rewarded']),
|
||||
fn ($query) => $query->orderBy('graveyard.'.$this->sortField, $this->sortDirection),
|
||||
fn ($query) => $query->orderBy('resurrections.'.$this->sortField, $this->sortDirection),
|
||||
fn ($query) => $query->orderBy('torrents.'.$this->sortField, $this->sortDirection)
|
||||
)
|
||||
->paginate($this->perPage);
|
||||
|
||||
@@ -44,8 +44,11 @@ class StoreTorrentRequest extends FormRequest
|
||||
'torrent' => [
|
||||
'required',
|
||||
'file',
|
||||
'mimes:torrent',
|
||||
function (string $attribute, mixed $value, Closure $fail): void {
|
||||
if ($value->getClientOriginalExtension() !== 'torrent') {
|
||||
$fail('The torrent file uploaded does not have a ".torrent" file extension (it has "'.$value->getClientOriginalExtension().'"). Did you upload the correct file?');
|
||||
}
|
||||
|
||||
$decodedTorrent = TorrentTools::normalizeTorrent($value);
|
||||
|
||||
$v2 = Bencode::is_v2_or_hybrid($decodedTorrent);
|
||||
@@ -79,6 +82,16 @@ class StoreTorrentRequest extends FormRequest
|
||||
}
|
||||
}
|
||||
],
|
||||
'nfo' => [
|
||||
'nullable',
|
||||
'sometimes',
|
||||
'file',
|
||||
function (string $attribute, mixed $value, Closure $fail): void {
|
||||
if ($value->getClientOriginalExtension() !== 'nfo') {
|
||||
$fail('The NFO uploaded does not have a ".nfo" file extension (it has "'.$value->getClientOriginalExtension().'"). Did you upload the correct file?');
|
||||
}
|
||||
},
|
||||
],
|
||||
'name' => [
|
||||
'required',
|
||||
'unique:torrents',
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\BonExchange;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -37,32 +36,8 @@ class StoreTransactionRequest extends FormRequest
|
||||
{
|
||||
return [
|
||||
'exchange' => [
|
||||
'bail',
|
||||
'required',
|
||||
'exists:bon_exchange,id',
|
||||
function ($attribute, $value, $fail) use ($request): void {
|
||||
$user = $request->user();
|
||||
$item = BonExchange::findOrFail($value);
|
||||
|
||||
switch (true) {
|
||||
case $item->cost > $user->seedbonus:
|
||||
$fail('Not enough BON.');
|
||||
|
||||
break;
|
||||
case $item->download && $user->downloaded < $item->value:
|
||||
$fail('Not enough download.');
|
||||
|
||||
break;
|
||||
case $item->personal_freeleech && cache()->get('personal_freeleech:'.$user->id):
|
||||
$fail('Your previous personal freeleech is still active.');
|
||||
|
||||
break;
|
||||
case $item->invite && $user->invites >= config('other.max_unused_user_invites', 1):
|
||||
$fail('You already have the maximum amount of unused invites allowed per user.');
|
||||
|
||||
break;
|
||||
}
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Movie;
|
||||
use App\Models\Tv;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class TorrentResource extends JsonResource
|
||||
@@ -24,15 +22,7 @@ class TorrentResource extends JsonResource
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
$meta = null;
|
||||
|
||||
if ($this->category->tv_meta && ($this->tmdb !== 0)) {
|
||||
$meta = Tv::with(['genres:name'])->find($this->tmdb);
|
||||
}
|
||||
|
||||
if ($this->category->movie_meta && ($this->tmdb !== 0)) {
|
||||
$meta = Movie::with(['genres:name'])->find($this->tmdb);
|
||||
}
|
||||
$meta = $this->movie ?? $this->tv;
|
||||
|
||||
return [
|
||||
'type' => 'torrent',
|
||||
|
||||
@@ -163,6 +163,23 @@ class ProcessAnnounce implements ShouldQueue
|
||||
$peer->updateConnectableStateIfNeeded();
|
||||
$peer->updated_at = now();
|
||||
|
||||
Redis::connection('announce')->command('LPUSH', [
|
||||
config('cache.prefix').':peers:batch',
|
||||
serialize($peer->only([
|
||||
'peer_id',
|
||||
'ip',
|
||||
'port',
|
||||
'agent',
|
||||
'uploaded',
|
||||
'downloaded',
|
||||
'left',
|
||||
'seeder',
|
||||
'torrent_id',
|
||||
'user_id',
|
||||
'connectable'
|
||||
]))
|
||||
]);
|
||||
|
||||
$history->agent = $this->queries['user-agent'];
|
||||
$history->seeder = (int) ($this->queries['left'] == 0);
|
||||
$history->client_uploaded = $realUploaded;
|
||||
|
||||
@@ -44,10 +44,9 @@ class BonTransactions extends Model
|
||||
/**
|
||||
* Belongs To A Sender.
|
||||
*/
|
||||
// Bad name to not conflict with sender (not sender_id)
|
||||
public function senderObj(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function sender(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'sender', 'id')->withDefault([
|
||||
return $this->belongsTo(User::class)->withDefault([
|
||||
'username' => 'System',
|
||||
'id' => '1',
|
||||
]);
|
||||
@@ -56,10 +55,9 @@ class BonTransactions extends Model
|
||||
/**
|
||||
* Belongs To A Receiver.
|
||||
*/
|
||||
// Bad name to not conflict with sender (not sender_id)
|
||||
public function receiverObj(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function receiver(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'receiver', 'id')->withDefault([
|
||||
return $this->belongsTo(User::class)->withDefault([
|
||||
'username' => 'System',
|
||||
'id' => '1',
|
||||
]);
|
||||
@@ -70,7 +68,7 @@ class BonTransactions extends Model
|
||||
*/
|
||||
public function exchange(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(BonExchange::class, 'itemID', 'id')->withDefault([
|
||||
return $this->belongsTo(BonExchange::class)->withDefault([
|
||||
'value' => 0,
|
||||
'cost' => 0,
|
||||
]);
|
||||
|
||||
@@ -32,7 +32,6 @@ class BotTransaction extends Model
|
||||
/**
|
||||
* Belongs To A User.
|
||||
*/
|
||||
// Bad name to not conflict with sender (not sender_id)
|
||||
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class)->withDefault([
|
||||
@@ -44,7 +43,6 @@ class BotTransaction extends Model
|
||||
/**
|
||||
* Belongs To A Bot.
|
||||
*/
|
||||
// Bad name to not conflict with sender (not sender_id)
|
||||
public function bot(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Bot::class)->withDefault([
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
@@ -22,6 +23,14 @@ class Peer extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* Prepare a date for array / JSON serialization.
|
||||
*/
|
||||
protected function serializeDate(DateTimeInterface $date): string
|
||||
{
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To A User.
|
||||
*/
|
||||
|
||||
@@ -66,6 +66,6 @@ class Playlist extends Model
|
||||
{
|
||||
$bbcode = new Bbcode();
|
||||
|
||||
return (new Linkify())->linky($bbcode->parse(htmlspecialchars_decode($this->description)));
|
||||
return (new Linkify())->linky($bbcode->parse($this->description));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ class Post extends Model
|
||||
{
|
||||
$bbcode = new Bbcode();
|
||||
|
||||
return (new Linkify())->linky($bbcode->parse(htmlspecialchars_decode($this->content)));
|
||||
return (new Linkify())->linky($bbcode->parse($this->content));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ use App\Traits\Auditable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Graveyard extends Model
|
||||
class Resurrection extends Model
|
||||
{
|
||||
use Auditable;
|
||||
use HasFactory;
|
||||
@@ -27,8 +27,6 @@ class Graveyard extends Model
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'graveyard';
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
/**
|
||||
@@ -128,14 +128,6 @@ class Torrent extends Model
|
||||
return $this->belongsToMany(Playlist::class, 'playlist_torrents')->using(PlaylistTorrent::class)->withPivot('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Genres.
|
||||
*/
|
||||
public function genres(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Genre::class, 'genre_torrent', 'torrent_id', 'genre_id', 'id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Torrent Has Been Moderated By.
|
||||
*/
|
||||
@@ -253,7 +245,7 @@ class Torrent extends Model
|
||||
*/
|
||||
public function resurrections(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Graveyard::class);
|
||||
return $this->hasMany(Resurrection::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-6
@@ -491,7 +491,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function bonGiven(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BonTransactions::class, 'sender');
|
||||
return $this->hasMany(BonTransactions::class, 'sender_id');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,7 +499,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function bonReceived(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BonTransactions::class, 'receiver');
|
||||
return $this->hasMany(BonTransactions::class, 'receiver_id');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,6 +510,14 @@ class User extends Authenticatable
|
||||
return $this->hasMany(Subscription::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Resurrections.
|
||||
*/
|
||||
public function resurrections(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Resurrection::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Subscribed topics.
|
||||
*/
|
||||
@@ -579,7 +587,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function sentGifts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BonTransactions::class, 'sender')->where('name', '=', 'gift');
|
||||
return $this->hasMany(BonTransactions::class, 'sender_id')->where('name', '=', 'gift');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -587,7 +595,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function receivedGifts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BonTransactions::class, 'receiver')->where('name', '=', 'gift');
|
||||
return $this->hasMany(BonTransactions::class, 'receiver_id')->where('name', '=', 'gift');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -595,7 +603,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function sentTips(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BonTransactions::class, 'sender')->where('name', '=', 'tip');
|
||||
return $this->hasMany(BonTransactions::class, 'sender_id')->where('name', '=', 'tip');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -603,7 +611,7 @@ class User extends Authenticatable
|
||||
*/
|
||||
public function receivedTips(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BonTransactions::class, 'receiver')->where('name', '=', 'tip');
|
||||
return $this->hasMany(BonTransactions::class, 'receiver_id')->where('name', '=', 'tip');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,7 +45,7 @@ class NewBon extends Notification implements ShouldQueue
|
||||
return [
|
||||
'title' => $this->sender.' Has Gifted You '.$this->bonTransactions->cost.' BON',
|
||||
'body' => $this->sender.' has gifted you '.$this->bonTransactions->cost.' BON with the following note: '.$this->bonTransactions->comment,
|
||||
'url' => sprintf('/users/%s', $this->bonTransactions->senderObj->username),
|
||||
'url' => sprintf('/users/%s', $this->bonTransactions->sender->username),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,16 @@ class BonTransactionsFactory extends Factory
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'itemID' => fn () => BonExchange::factory()->create()->id,
|
||||
'name' => $this->faker->name(),
|
||||
'cost' => $this->faker->randomFloat(),
|
||||
'sender' => fn () => User::factory()->create()->id,
|
||||
'receiver' => fn () => User::factory()->create()->id,
|
||||
'torrent_id' => $this->faker->randomNumber(),
|
||||
'donation_id' => $this->faker->randomNumber(),
|
||||
'post_id' => $this->faker->randomNumber(),
|
||||
'comment' => $this->faker->text(),
|
||||
'date_actioned' => $this->faker->dateTime(),
|
||||
'bon_exchange_id' => fn () => BonExchange::factory()->create()->id,
|
||||
'name' => $this->faker->name(),
|
||||
'cost' => $this->faker->randomFloat(),
|
||||
'sender_id' => fn () => User::factory()->create()->id,
|
||||
'receiver_id' => fn () => User::factory()->create()->id,
|
||||
'torrent_id' => $this->faker->randomNumber(),
|
||||
'donation_id' => $this->faker->randomNumber(),
|
||||
'post_id' => $this->faker->randomNumber(),
|
||||
'comment' => $this->faker->text(),
|
||||
'created_at' => $this->faker->dateTime(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ use App\Models\Torrent;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class GraveyardFactory extends Factory
|
||||
class ResurrectionFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('recommendations')
|
||||
->whereNotIn('movie_id', DB::table('movie')->select('id'))
|
||||
->orWhereNotIn('recommendation_movie_id', DB::table('movie')->select('id'))
|
||||
->delete();
|
||||
|
||||
DB::table('recommendations')
|
||||
->whereNotIn('tv_id', DB::table('tv')->select('id'))
|
||||
->orWhereNotIn('recommendation_tv_id', DB::table('tv')->select('id'))
|
||||
->delete();
|
||||
|
||||
DB::table('seasons')->whereNotIn('tv_id', DB::table('tv')->select('id'))->delete();
|
||||
DB::table('episodes')->whereNotIn('tv_id', DB::table('tv')->select('id'))->delete();
|
||||
DB::table('company_movie')->whereNotIn('movie_id', DB::table('movie')->select('id'))->delete();
|
||||
DB::table('company_tv')->whereNotIn('tv_id', DB::table('tv')->select('id'))->delete();
|
||||
DB::table('collection_movie')->whereNotIn('movie_id', DB::table('movie')->select('id'))->delete();
|
||||
DB::table('network_tv')->whereNotIn('tv_id', DB::table('tv')->select('id'))->delete();
|
||||
DB::table('genre_movie')->whereNotIn('movie_id', DB::table('movie')->select('id'))->delete();
|
||||
DB::table('genre_tv')->whereNotIn('tv_id', DB::table('tv')->select('id'))->delete();
|
||||
|
||||
Schema::table('recommendations', function (Blueprint $table): void {
|
||||
$table->dropForeign(['movie_id']);
|
||||
$table->dropForeign(['recommendation_movie_id']);
|
||||
$table->dropForeign(['tv_id']);
|
||||
$table->dropForeign(['recommendation_tv_id']);
|
||||
});
|
||||
|
||||
Schema::table('credits', function (Blueprint $table): void {
|
||||
$table->dropForeign(['movie_id']);
|
||||
$table->dropForeign(['tv_id']);
|
||||
});
|
||||
|
||||
Schema::table('movie', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('tv', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('recommendations', function (Blueprint $table): void {
|
||||
$table->unsignedInteger('movie_id')->change();
|
||||
$table->foreign('movie_id')->references('id')->on('movie')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
|
||||
$table->unsignedInteger('recommendation_movie_id')->change();
|
||||
$table->foreign('recommendation_movie_id')->references('id')->on('movie')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
|
||||
$table->unsignedInteger('tv_id')->change();
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
|
||||
$table->unsignedInteger('recommendation_tv_id')->change();
|
||||
$table->foreign('recommendation_tv_id')->references('id')->on('tv')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('credits', function (Blueprint $table): void {
|
||||
$table->unsignedInteger('movie_id')->nullable()->change();
|
||||
$table->foreign('movie_id')->references('id')->on('movie')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
|
||||
$table->unsignedInteger('tv_id')->nullable()->change();
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('seasons', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
$table->unsignedInteger('tv_id')->change();
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate();
|
||||
});
|
||||
|
||||
Schema::table('episodes', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
$table->unsignedInteger('tv_id')->change();
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate();
|
||||
|
||||
$table->unsignedInteger('season_id')->change();
|
||||
$table->foreign('season_id')->references('id')->on('seasons')->cascadeOnUpdate();
|
||||
});
|
||||
|
||||
Schema::table('company_movie', function (Blueprint $table): void {
|
||||
$table->foreign('movie_id')->references('id')->on('movie')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('company_tv', function (Blueprint $table): void {
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('collection_movie', function (Blueprint $table): void {
|
||||
$table->foreign('movie_id')->references('id')->on('movie')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('network_tv', function (Blueprint $table): void {
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('genre_movie', function (Blueprint $table): void {
|
||||
$table->foreign('movie_id')->references('id')->on('movie')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('genre_tv', function (Blueprint $table): void {
|
||||
$table->foreign('tv_id')->references('id')->on('tv')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class () extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('posts')
|
||||
->lazyById()
|
||||
->each(function (object $post): void {
|
||||
DB::table('posts')
|
||||
->where('id', '=', $post->id)
|
||||
->update([
|
||||
'content' => htmlspecialchars_decode($post->content),
|
||||
]);
|
||||
});
|
||||
|
||||
DB::table('playlists')
|
||||
->lazyById()
|
||||
->each(function (object $playlist): void {
|
||||
DB::table('playlists')
|
||||
->where('id', '=', $playlist->id)
|
||||
->update([
|
||||
'description' => htmlspecialchars_decode($playlist->description),
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('bon_transactions', function (Blueprint $table): void {
|
||||
$table->renameColumn('itemID', 'bon_exchange_id');
|
||||
$table->renameColumn('sender', 'sender_id');
|
||||
$table->renameColumn('receiver', 'receiver_id');
|
||||
$table->renameColumn('date_actioned', 'created_at');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('genre_torrent', function (Blueprint $table): void {
|
||||
$table->drop();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('graveyard', function (Blueprint $table): void {
|
||||
$table->rename('resurrections');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('company_movie')->whereNotIn('company_id', DB::table('companies')->select('id'))->delete();
|
||||
DB::table('company_tv')->whereNotIn('company_id', DB::table('companies')->select('id'))->delete();
|
||||
DB::table('collection_movie')->whereNotIn('collection_id', DB::table('collection')->select('id'))->delete();
|
||||
DB::table('network_tv')->whereNotIn('network_id', DB::table('networks')->select('id'))->delete();
|
||||
DB::table('genre_movie')->whereNotIn('genre_id', DB::table('genres')->select('id'))->delete();
|
||||
DB::table('genre_tv')->whereNotIn('genre_id', DB::table('genres')->select('id'))->delete();
|
||||
|
||||
Schema::table('credits', function (Blueprint $table): void {
|
||||
$table->dropForeign(['person_id']);
|
||||
});
|
||||
|
||||
Schema::table('companies', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('collection', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('networks', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('genres', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('recommendations', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('person', function (Blueprint $table): void {
|
||||
$table->increments('id')->change();
|
||||
});
|
||||
|
||||
Schema::table('company_movie', function (Blueprint $table): void {
|
||||
$table->foreign('company_id')->references('id')->on('companies')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('company_tv', function (Blueprint $table): void {
|
||||
$table->foreign('company_id')->references('id')->on('companies')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('collection_movie', function (Blueprint $table): void {
|
||||
$table->foreign('collection_id')->references('id')->on('collection')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('network_tv', function (Blueprint $table): void {
|
||||
$table->foreign('network_id')->references('id')->on('networks')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('genre_movie', function (Blueprint $table): void {
|
||||
$table->foreign('genre_id')->references('id')->on('genres')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('genre_tv', function (Blueprint $table): void {
|
||||
$table->foreign('genre_id')->references('id')->on('genres')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('credits', function (Blueprint $table): void {
|
||||
$table->unsignedInteger('person_id')->change();
|
||||
$table->foreign('person_id')->references('id')->on('person')->cascadeOnUpdate()->cascadeOnDelete();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -43,6 +43,7 @@
|
||||
<i
|
||||
v-if="message.user.id != 1 && canMod(message)"
|
||||
@click="deleteMessage(message.id)"
|
||||
title="Delete message"
|
||||
class="fa fa-times text-red"
|
||||
>
|
||||
</i>
|
||||
@@ -50,12 +51,14 @@
|
||||
<a
|
||||
v-if="message.user && message.user.id > 1 && message.user.id != $parent.auth.id"
|
||||
@click.prevent="$parent.forceMessage(message.user.username)"
|
||||
title="Send chat PM (/msg <username> <message>)"
|
||||
>
|
||||
<i class="fas fa-envelope pointee"></i>
|
||||
</a>
|
||||
<a
|
||||
v-if="message.user && message.user.id > 1 && message.user.id != $parent.auth.id"
|
||||
@click.prevent="$parent.forceGift(message.user.username)"
|
||||
title="Gift user bon (/gift <username> <amount> <message>)"
|
||||
>
|
||||
<i class="fas fa-gift pointee"></i>
|
||||
</a>
|
||||
|
||||
@@ -261,6 +261,8 @@
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
padding: 0.25em 0.25em 0.25em 1em;
|
||||
color: var(--bbcode-rendered-fg-muted);
|
||||
border-left: 0.25em solid var(--bbcode-rendered-quote-border);
|
||||
@@ -274,6 +276,11 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
blockquote > blockquote {
|
||||
margin-left: 6px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin-top: 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<article class="post" id="post-{{ $post->id }}">
|
||||
<article class="post" id="post-{{ $post->id }}" x-data>
|
||||
<header class="post__header">
|
||||
<time
|
||||
class="post__datetime"
|
||||
@@ -74,11 +74,16 @@
|
||||
<button
|
||||
class="post__quote"
|
||||
title="{{ __('forum.quote') }}"
|
||||
x-data
|
||||
x-on:click="
|
||||
document.getElementById('forum_reply_form').style.display = 'block';
|
||||
input = document.getElementById('bbcode-content');
|
||||
input.value += '[quote={{ \htmlspecialchars('@'.$post->user->username) }}] {{ \str_replace(["\n", "\r"], ["\\n", "\\r"], \htmlspecialchars($post->content)) }}[/quote]';
|
||||
input.value += '[quote={{ \htmlspecialchars('@'.$post->user->username) }}]';
|
||||
input.value += (() => {
|
||||
var text = document.createElement('textarea');
|
||||
text.innerHTML = atob($refs.content.dataset.base64Bbcode);
|
||||
return text.value;
|
||||
})();
|
||||
input.value += '[/quote]';
|
||||
input.dispatchEvent(new Event('input'));
|
||||
input.focus();
|
||||
"
|
||||
@@ -178,7 +183,8 @@
|
||||
</aside>
|
||||
<div
|
||||
class="post__content bbcode-rendered"
|
||||
data-bbcode="{{ $post->content }}"
|
||||
x-ref="content"
|
||||
data-base64-bbcode="{{ base64_encode($post->content) }}"
|
||||
>
|
||||
@joypixels($post->getContentHtml())
|
||||
</div>
|
||||
|
||||
@@ -53,7 +53,16 @@
|
||||
datetime="{{ $subforum->updated_at }}"
|
||||
title="{{ $subforum->updated_at }}"
|
||||
>
|
||||
{{ $subforum->updated_at?->diffForHumans() ?? __('common.unknown') }}
|
||||
@if ($subforum->last_topic_id === null)
|
||||
{{ $subforum->updated_at?->diffForHumans() ?? __('common.unknown') }}
|
||||
@else
|
||||
<a
|
||||
class="subforum-listing__latest-post-link"
|
||||
href="{{ route('topics.latestPermalink', ['id' => $subforum->last_topic_id]) }}"
|
||||
>
|
||||
{{ $subforum->updated_at?->diffForHumans() ?? __('common.unknown') }}
|
||||
</a>
|
||||
@endif
|
||||
</time>
|
||||
@if ($subforum->last_topic_id !== null && $subforum->last_post_user_username !== null)
|
||||
<address class="subforum-listing__latest-author">
|
||||
|
||||
@@ -104,7 +104,12 @@
|
||||
datetime="{{ $topic->last_reply_at ?? '' }}"
|
||||
title="{{ $topic->last_reply_at ?? '' }}"
|
||||
>
|
||||
{{ $topic->last_reply_at?->diffForHumans() ?? __('common.unknown') }}
|
||||
<a
|
||||
class="topic-listing__latest-post-link"
|
||||
href="{{ route('topics.latestPermalink', ['id' => $topic->id]) }}"
|
||||
>
|
||||
{{ $topic->last_reply_at?->diffForHumans() ?? __('common.unknown') }}
|
||||
</a>
|
||||
</time>
|
||||
</article>
|
||||
</article>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<span class="torrent-search-grouped__directors-by">by</span>
|
||||
@foreach($media->directors as $director)
|
||||
<a
|
||||
href="{{ route('mediahub.persons.show', ['id' => $director->id]) }}"
|
||||
href="{{ route('mediahub.persons.show', ['id' => $director->id, 'occupationId' => App\Enums\Occupations::DIRECTOR->value]) }}"
|
||||
class="torrent-search--grouped__director"
|
||||
>
|
||||
{{ $director->name }}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<span class="torrent-search-grouped__directors-by">by</span>
|
||||
@foreach($media->creators as $creator)
|
||||
<a
|
||||
href="{{ route('mediahub.persons.show', ['id' => $creator->id]) }}"
|
||||
href="{{ route('mediahub.persons.show', ['id' => $creator->id, 'occupationId' => App\Enums\Occupations::CREATOR->value]) }}"
|
||||
class="torrent-search--grouped__director"
|
||||
>
|
||||
{{ $creator->name }}
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
<section class="panelV2" x-data="{ tab: @entangle('occupation') }">
|
||||
<section class="panelV2" x-data="{ tab: @entangle('occupationId') }">
|
||||
<h2 class="panel__heading">{{ __('torrent.torrents') }}</h2>
|
||||
<menu class="panel__tabs">
|
||||
<li
|
||||
class="panel__tab"
|
||||
role="tab"
|
||||
x-bind:class="tab === {{ App\Enums\Occupations::DIRECTOR->value }} && 'panel__tab--active'"
|
||||
x-cloak
|
||||
x-on:click="tab = {{ App\Enums\Occupations::DIRECTOR->value }}"
|
||||
x-show="{{ $directedCount }} > 0"
|
||||
>
|
||||
Director ({{ $directedCount }})
|
||||
</li>
|
||||
<li
|
||||
class="panel__tab"
|
||||
role="tab"
|
||||
@@ -21,6 +11,16 @@
|
||||
>
|
||||
Creator ({{ $createdCount }})
|
||||
</li>
|
||||
<li
|
||||
class="panel__tab"
|
||||
role="tab"
|
||||
x-bind:class="tab === {{ App\Enums\Occupations::DIRECTOR->value }} && 'panel__tab--active'"
|
||||
x-cloak
|
||||
x-on:click="tab = {{ App\Enums\Occupations::DIRECTOR->value }}"
|
||||
x-show="{{ $directedCount }} > 0"
|
||||
>
|
||||
Director ({{ $directedCount }})
|
||||
</li>
|
||||
<li
|
||||
class="panel__tab"
|
||||
role="tab"
|
||||
|
||||
@@ -152,6 +152,18 @@
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<p class="form__group">
|
||||
<input
|
||||
id="username"
|
||||
wire:model="username"
|
||||
type="search"
|
||||
class="form__text"
|
||||
placeholder=" "
|
||||
>
|
||||
<label for="username" class="form__label form__label--floating">
|
||||
{{ __('subtitle.uploader') }}
|
||||
</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<select
|
||||
id="quantity"
|
||||
|
||||
@@ -28,42 +28,12 @@
|
||||
alt="{{ $person->name }}"
|
||||
style="max-width: 100%;"
|
||||
>
|
||||
<div class="panel__body">{{ $person->biography ?? 'No biography' }}</div>
|
||||
<dl class="key-value">
|
||||
<dt>{{ __('mediahub.born') }}</dt>
|
||||
<dd>{{ $person->birthday ?? __('common.unknown') }}</dd>
|
||||
<dt>Place of Birth</dt>
|
||||
<dd>{{ $person->place_of_birth ?? __('common.unknown') }}</dd>
|
||||
<dt>{{ __('mediahub.movie-credits') }}</dt>
|
||||
<dd>{{ $person->movie->count() ?? '0' }}</dd>
|
||||
<dt>{{ __('mediahub.first-seen') }} </dt>
|
||||
<dd>
|
||||
<a href="{{ route('torrents.index', ['view' => 'group', 'tmdb' => $person->movie->first()->id ?? '0', 'categories' => $movieCategoryIds]) }}">
|
||||
{{ $person->movie->first()->title ?? 'N/A'}}
|
||||
</a>
|
||||
</dd>
|
||||
<dt>{{ __('mediahub.latest-project') }}</dt>
|
||||
<dd>
|
||||
<a href="{{ route('torrents.index', ['view' => 'group', 'tmdb' => $person->movie->last()->id ?? '0', 'categories' => $movieCategoryIds]) }}">
|
||||
{{ $person->movie->last()->title ?? 'N/A' }}
|
||||
</a>
|
||||
</dd>
|
||||
<dt>{{ __('mediahub.tv-credits') }}</dt>
|
||||
<dd>{{ $person->tv->count() ?? '0' }}</dd>
|
||||
<dt>{{ __('mediahub.first-seen') }}</dt>
|
||||
<dd>
|
||||
In
|
||||
<a href="{{ route('torrents.index', ['view' => 'group', 'tmdb' => $person->tv->first()->id ?? '0', 'categories' => $tvCategoryIds]) }}">
|
||||
{{ $person->tv->first()->name ?? 'N/A'}}
|
||||
</a>
|
||||
</dd>
|
||||
<dt>{{ __('mediahub.latest-project') }}</dt>
|
||||
<dd>
|
||||
Last in
|
||||
<a href="{{ route('torrents.index', ['view' => 'group', 'tmdb' => $person->tv->last()->id ?? '0', 'categories' => $tvCategoryIds]) }}">
|
||||
{{ $person->tv->last()->name ?? 'N/A' }}
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="panel__body">{{ $person->biography ?? 'No biography' }}</div>
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<h2 class="meta__heading">Cast</h2>
|
||||
@foreach ($meta?->credits?->where('occupation_id', '=', App\Enums\Occupations::ACTOR->value)?->sortBy('order') ?? [] as $credit)
|
||||
<article class="meta-chip-wrapper">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id]) }}" class="meta-chip">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id, 'occupationId' => $credit->occupation_id]) }}" class="meta-chip">
|
||||
@if ($credit->person->still)
|
||||
<img
|
||||
class="meta-chip__image"
|
||||
@@ -134,7 +134,7 @@
|
||||
<h2 class="meta__heading">Crew</h2>
|
||||
@foreach($meta?->credits?->where('occupation_id', '!=', App\Enums\Occupations::ACTOR->value)?->sortBy('occupation.position') ?? [] as $credit)
|
||||
<article class="meta-chip-wrapper">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id]) }}" class="meta-chip">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id, 'occupationId' => $credit->occupation_id]) }}" class="meta-chip">
|
||||
@if ($credit->person->still)
|
||||
<img
|
||||
class="meta-chip__image"
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<h2 class="meta__heading">Cast</h2>
|
||||
@foreach ($meta?->credits?->where('occupation_id', '=', App\Enums\Occupations::ACTOR->value)?->sortBy('order') ?? [] as $credit)
|
||||
<article class="meta-chip-wrapper">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id]) }}" class="meta-chip">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id, 'occupationId' => $credit->occupation_id]) }}" class="meta-chip">
|
||||
@if ($credit->person->still)
|
||||
<img
|
||||
class="meta-chip__image"
|
||||
@@ -134,7 +134,7 @@
|
||||
<h2 class="meta__heading">Crew</h2>
|
||||
@foreach($meta?->credits?->where('occupation_id', '!=', App\Enums\Occupations::ACTOR->value)?->sortBy('occupation.position') ?? [] as $credit)
|
||||
<article class="meta-chip-wrapper">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id]) }}" class="meta-chip">
|
||||
<a href="{{ route('mediahub.persons.show', ['id' => $credit->person->id, 'occupationId' => $credit->occupation_id]) }}" class="meta-chip">
|
||||
@if ($credit->person->still)
|
||||
<img
|
||||
class="meta-chip__image"
|
||||
|
||||
@@ -52,16 +52,16 @@
|
||||
@foreach($gifts as $gift)
|
||||
<tr>
|
||||
<td>
|
||||
<x-user_tag :user="$gift->senderObj" :anon="false" />
|
||||
<x-user_tag :user="$gift->sender" :anon="false" />
|
||||
</td>
|
||||
<td>
|
||||
<x-user_tag :user="$gift->receiverObj" :anon="false" />
|
||||
<x-user_tag :user="$gift->receiver" :anon="false" />
|
||||
</td>
|
||||
<td>
|
||||
{{ $gift->cost }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $gift->date_actioned }}
|
||||
{{ $gift->created_at }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
@@ -43,20 +43,20 @@
|
||||
@foreach($tips as $tip)
|
||||
<tr>
|
||||
<td>
|
||||
<x-user_tag :user="$tip->receiverObj" :anon="false" />
|
||||
<x-user_tag :user="$tip->receiver" :anon="false" />
|
||||
</td>
|
||||
<td>
|
||||
@switch(true)
|
||||
@case($tip->torrent_id !== null)
|
||||
<x-user_tag :user="$tip->receiverObj" :anon="$tip->torrent->anon" />
|
||||
<x-user_tag :user="$tip->receiver" :anon="$tip->torrent->anon" />
|
||||
@break
|
||||
@case($tip->post_id !== null)
|
||||
<x-user_tag :user="$tip->receiverObj" :anon="false" />
|
||||
<x-user_tag :user="$tip->receiver" :anon="false" />
|
||||
@break
|
||||
@endswitch
|
||||
</td>
|
||||
<td>{{ $tip->cost }}</td>
|
||||
<td>{{ $tip->date_actioned }}</td>
|
||||
<td>{{ $tip->created_at }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
||||
@@ -364,6 +364,7 @@ Route::middleware('language')->group(function (): void {
|
||||
Route::get('/forum/{id}/create', [App\Http\Controllers\TopicController::class, 'create'])->name('create');
|
||||
Route::post('/forum/{id}', [App\Http\Controllers\TopicController::class, 'store'])->name('store');
|
||||
Route::get('/{topicId}/posts/{postId}', [App\Http\Controllers\TopicController::class, 'permalink'])->name('permalink');
|
||||
Route::get('/{id}/latest', [App\Http\Controllers\TopicController::class, 'latestPermalink'])->name('latestPermalink');
|
||||
Route::get('/{id}', [App\Http\Controllers\TopicController::class, 'show'])->name('show');
|
||||
Route::get('/{id}/edit', [App\Http\Controllers\TopicController::class, 'edit'])->name('edit');
|
||||
Route::patch('/{id}', [App\Http\Controllers\TopicController::class, 'update'])->name('update');
|
||||
|
||||
+7
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Tests\Todo\Feature\Http\Controllers;
|
||||
|
||||
use App\Models\Graveyard;
|
||||
use App\Models\Resurrection;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
@@ -10,7 +10,7 @@ use Tests\TestCase;
|
||||
/**
|
||||
* @see \App\Http\Controllers\GraveyardController
|
||||
*/
|
||||
class GraveyardControllerTest extends TestCase
|
||||
class ResurrectionControllerTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
@@ -21,13 +21,13 @@ class GraveyardControllerTest extends TestCase
|
||||
{
|
||||
$this->markTestIncomplete('This test case was generated by Shift. When you are ready, remove this line and complete this test case.');
|
||||
|
||||
$graveyard = Graveyard::factory()->create();
|
||||
$resurrection = Resurrection::factory()->create();
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this->actingAs($user)->delete(route('users.resurrections.destroy.destroy', ['user' => $user, 'resurrection' => $graveyard]));
|
||||
$response = $this->actingAs($user)->delete(route('users.resurrections.destroy', ['user' => $user, 'resurrection' => $resurrection]));
|
||||
|
||||
$response->assertRedirect(withSuccess('Resurrection Successfully Canceled!'));
|
||||
$this->assertModelMissing($graveyard);
|
||||
$this->assertModelMissing($resurrection);
|
||||
|
||||
// TODO: perform additional assertions
|
||||
}
|
||||
@@ -39,11 +39,11 @@ class GraveyardControllerTest extends TestCase
|
||||
{
|
||||
$this->markTestIncomplete('This test case was generated by Shift. When you are ready, remove this line and complete this test case.');
|
||||
|
||||
$graveyard = Graveyard::factory()->create();
|
||||
$resurrection = Resurrection::factory()->create();
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this->actingAs($user)->post(route('users.resurrections.store', ['user' => $user]), [
|
||||
'torrent_id' => $graveyard->id,
|
||||
'torrent_id' => $resurrection->torrent_id,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(withErrors('Torrent Resurrection Failed! This torrent is already pending a resurrection.'));
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Console\Commands;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @see \App\Console\Commands\AutoGraveyard
|
||||
*/
|
||||
class AutoGraveyardTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_runs_successfully(): void
|
||||
{
|
||||
$this->artisan('auto:graveyard')
|
||||
->expectsOutput('Automated Graveyard Rewards Command Complete')
|
||||
->assertExitCode(0)
|
||||
->run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Console\Commands;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @see \App\Console\Commands\AutoRewardResurrection
|
||||
*/
|
||||
class AutoRewardResurrectionTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_runs_successfully(): void
|
||||
{
|
||||
$this->artisan('auto:reward_resurrection')
|
||||
->expectsOutput('Automated Reward Resurrections Command Complete')
|
||||
->assertExitCode(0)
|
||||
->run();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user