mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-14 12:30:49 +08:00
API: upload sections list
This commit is contained in:
13
app/Auth/Permission.php
Normal file
13
app/Auth/Permission.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Auth;
|
||||||
|
|
||||||
|
use App\Enums\PermissionEnum;
|
||||||
|
|
||||||
|
class Permission
|
||||||
|
{
|
||||||
|
public static function canUploadToSpecialSection(): bool
|
||||||
|
{
|
||||||
|
return user_can(PermissionEnum::UPLOAD_TO_SPECIAL_SECTION->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Enums\PermissionEnum;
|
||||||
use App\Events\TorrentUpdated;
|
use App\Events\TorrentUpdated;
|
||||||
use App\Filament\Resources\System\AgentAllowResource;
|
use App\Filament\Resources\System\AgentAllowResource;
|
||||||
use App\Http\Resources\TagResource;
|
use App\Http\Resources\TagResource;
|
||||||
@@ -102,11 +103,10 @@ class Test extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$today = Carbon::today();
|
$with = ["ss" => function($query) {$query->orWhere("mode", 0);}];
|
||||||
$yesterday = Carbon::yesterday();
|
$r = SearchBox::query()->with($with)->find(4);
|
||||||
$tomorrow = Carbon::tomorrow();
|
// $r = SearchBox::query()->find(4)->ss()->orWhere("mode", 0)->get();
|
||||||
$diff = $tomorrow->diffInDays();
|
dd($r);
|
||||||
dd($today, $tomorrow, $diff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
7
app/Enums/PermissionEnum.php
Normal file
7
app/Enums/PermissionEnum.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
enum PermissionEnum: string {
|
||||||
|
case UPLOAD_TO_SPECIAL_SECTION = 'uploadspecial';
|
||||||
|
}
|
||||||
18
app/Http/Controllers/SearchBoxController.php
Normal file
18
app/Http/Controllers/SearchBoxController.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Resources\SearchBoxResource;
|
||||||
|
use App\Repositories\SearchBoxRepository;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class SearchBoxController extends Controller
|
||||||
|
{
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
public function __construct(SearchBoxRepository $repository)
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Models\PluginStore;
|
use App\Models\PluginStore;
|
||||||
use App\Repositories\ToolRepository;
|
use App\Repositories\ToolRepository;
|
||||||
|
use App\Repositories\UploadRepository;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
@@ -30,7 +31,9 @@ class ToolController extends Controller
|
|||||||
|
|
||||||
public function test(Request $request)
|
public function test(Request $request)
|
||||||
{
|
{
|
||||||
|
$rep = new UploadRepository();
|
||||||
|
$result = $rep->listSections();
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
29
app/Http/Controllers/UploadController.php
Normal file
29
app/Http/Controllers/UploadController.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Resources\SearchBoxResource;
|
||||||
|
use App\Repositories\SearchBoxRepository;
|
||||||
|
use App\Repositories\UploadRepository;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class UploadController extends Controller
|
||||||
|
{
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
private $searchBoxRepository;
|
||||||
|
|
||||||
|
public function __construct(UploadRepository $repository, SearchBoxRepository $searchBoxRepository)
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
$this->searchBoxRepository = $searchBoxRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sections(Request $request)
|
||||||
|
{
|
||||||
|
$sections = $this->searchBoxRepository->listSections();
|
||||||
|
$resource = SearchBoxResource::collection($sections);
|
||||||
|
return $this->success($resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
44
app/Http/Resources/SearchBoxResource.php
Normal file
44
app/Http/Resources/SearchBoxResource.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\SearchBox;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class SearchBoxResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
/** @var SearchBox $resource */
|
||||||
|
$searchBox = $this->resource;
|
||||||
|
$out = [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->displaySectionName,
|
||||||
|
'categories' => CategoryResource::collection($this->whenLoaded('categories')),
|
||||||
|
];
|
||||||
|
$subCategories = [];
|
||||||
|
$lang = get_langfolder_cookie();
|
||||||
|
$fields = array_keys(SearchBox::$taxonomies);
|
||||||
|
if (!empty($searchBox->extra['taxonomy_labels'])) {
|
||||||
|
$fields = array_column($searchBox->extra['taxonomy_labels'], 'torrent_field');
|
||||||
|
}
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$relationName = "taxonomy_$field";
|
||||||
|
if ($searchBox->relationLoaded($relationName)) {
|
||||||
|
$subCategories[] = [
|
||||||
|
'field' => $field,
|
||||||
|
'label' => $item['display_text'][$lang] ?? (nexus_trans("searchbox.sub_category_{$field}_label") ?: ucfirst($field)),
|
||||||
|
'data' => MediaResource::collection($searchBox->{$relationName}),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$out['sub_categories'] = $this->when($this->showsubcat, $subCategories);
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Http\Middleware\Locale;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -182,6 +183,25 @@ class SearchBox extends NexusModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDisplaySectionNameAttribute()
|
||||||
|
{
|
||||||
|
$locale = Locale::getDefault();
|
||||||
|
if (!empty($this->section_name[$locale])) {
|
||||||
|
return $this->section_name[$locale];
|
||||||
|
}
|
||||||
|
$defaultLang = get_setting("main.defaultlang");
|
||||||
|
if (!empty($this->section_name[$defaultLang])) {
|
||||||
|
return $this->section_name[$defaultLang];
|
||||||
|
}
|
||||||
|
if ($this->isSectionBrowse()) {
|
||||||
|
return nexus_trans("searchbox.sections.browse");
|
||||||
|
}
|
||||||
|
if ($this->isSectionSpecial()) {
|
||||||
|
return nexus_trans("searchbox.sections.special");
|
||||||
|
}
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
public static function listSearchModes(): array
|
public static function listSearchModes(): array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
@@ -206,6 +226,16 @@ class SearchBox extends NexusModel
|
|||||||
return Setting::get('main.specialcat');
|
return Setting::get('main.specialcat');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isSectionBrowse(): bool
|
||||||
|
{
|
||||||
|
return $this->id == self::getBrowseMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSectionSpecial(): bool
|
||||||
|
{
|
||||||
|
return $this->id == self::getSpecialMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function categories(): \Illuminate\Database\Eloquent\Relations\HasMany
|
public function categories(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||||
{
|
{
|
||||||
@@ -247,6 +277,17 @@ class SearchBox extends NexusModel
|
|||||||
return $this->hasMany(Processing::class, 'mode');
|
return $this->hasMany(Processing::class, 'mode');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadSubCategories(): void
|
||||||
|
{
|
||||||
|
foreach (self::$taxonomies as $name => $info) {
|
||||||
|
$relationName = "taxonomy_" . $name;
|
||||||
|
$show = "show" . $name;
|
||||||
|
if ($this->{$show}) {
|
||||||
|
$this->setRelation($relationName, $this->{$relationName}()->orWhere('mode', 0)->get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function getDefaultSearchMode()
|
public static function getDefaultSearchMode()
|
||||||
{
|
{
|
||||||
$meiliConf = get_setting("meilisearch");
|
$meiliConf = get_setting("meilisearch");
|
||||||
|
|||||||
@@ -100,4 +100,9 @@ class Setting extends NexusModel
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getDefaultLang()
|
||||||
|
{
|
||||||
|
return self::get("main.defaultlang");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Repositories;
|
namespace App\Repositories;
|
||||||
|
|
||||||
|
use App\Auth\Permission;
|
||||||
use App\Exceptions\InsufficientPermissionException;
|
use App\Exceptions\InsufficientPermissionException;
|
||||||
use App\Http\Middleware\Locale;
|
use App\Http\Middleware\Locale;
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
@@ -242,5 +243,20 @@ class SearchBoxRepository extends BaseRepository
|
|||||||
return Category::query()->whereIn('id', $idArr)->delete();
|
return Category::query()->whereIn('id', $idArr)->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function listSections()
|
||||||
|
{
|
||||||
|
$modeIds = [SearchBox::getBrowseMode()];
|
||||||
|
if (SearchBox::isSpecialEnabled() && Permission::canUploadToSpecialSection()) {
|
||||||
|
$modeIds[] = SearchBox::getSpecialMode();
|
||||||
|
}
|
||||||
|
$searchBoxList = SearchBox::query()->with("categories")->find($modeIds);
|
||||||
|
foreach ($searchBoxList as $searchBox) {
|
||||||
|
if ($searchBox->showsubcat) {
|
||||||
|
$searchBox->loadSubCategories();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $searchBoxList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
72
app/Repositories/UploadRepository.php
Normal file
72
app/Repositories/UploadRepository.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Repositories;
|
||||||
|
use App\Auth\Permission;
|
||||||
|
use App\Exceptions\NexusException;
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\SearchBox;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
|
||||||
|
class UploadRepository extends BaseRepository
|
||||||
|
{
|
||||||
|
public function upload(Request $request)
|
||||||
|
{
|
||||||
|
$user = $request->user();
|
||||||
|
if ($user->uploadpos != 'yes') {
|
||||||
|
throw new NexusException("user upload permission is disabled");
|
||||||
|
}
|
||||||
|
$rules = [
|
||||||
|
'descr' => 'required',
|
||||||
|
'type' => 'required',
|
||||||
|
'name' => 'required',
|
||||||
|
];
|
||||||
|
$request->validate($rules);
|
||||||
|
$category = Category::query()->firstOrFail($request->type);
|
||||||
|
$mode = $category->mode;
|
||||||
|
$anonymous = "no";
|
||||||
|
$uploaderUsername = $user->username;
|
||||||
|
if ($request->uplver == 'yes' && user_can('beanonymous')) {
|
||||||
|
$anonymous = "yes";
|
||||||
|
$uploaderUsername = "Anonymous";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTorrentFile(Request $request): UploadedFile
|
||||||
|
{
|
||||||
|
$file = $request->file('file');
|
||||||
|
if (empty($file)) {
|
||||||
|
throw new NexusException("torrent file not found");
|
||||||
|
}
|
||||||
|
if (!$file->isValid()) {
|
||||||
|
throw new NexusException("upload torrent file error");
|
||||||
|
}
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getNfoContent(Request $request): string
|
||||||
|
{
|
||||||
|
$enableNfo = get_setting("main.enablenfo") == "yes";
|
||||||
|
if (!$enableNfo) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
$file = $request->file('nfo');
|
||||||
|
if (empty($file)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (!$file->isValid()) {
|
||||||
|
throw new NexusException("upload nfo file error");
|
||||||
|
}
|
||||||
|
$size = $file->getSize();
|
||||||
|
if ($size == 0) {
|
||||||
|
throw new NexusException("upload nfo file size is zero");
|
||||||
|
}
|
||||||
|
if ($size > 65535) {
|
||||||
|
throw new NexusException("upload nfo file size is too large");
|
||||||
|
}
|
||||||
|
return str_replace("\x0d\x0d\x0a", "\x0d\x0a", $file->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
defined('VERSION_NUMBER') || define('VERSION_NUMBER', '1.9.0');
|
defined('VERSION_NUMBER') || define('VERSION_NUMBER', '1.9.0');
|
||||||
defined('RELEASE_DATE') || define('RELEASE_DATE', '2025-02-06');
|
defined('RELEASE_DATE') || define('RELEASE_DATE', '2025-02-15');
|
||||||
defined('IN_TRACKER') || define('IN_TRACKER', false);
|
defined('IN_TRACKER') || define('IN_TRACKER', false);
|
||||||
defined('PROJECTNAME') || define("PROJECTNAME","NexusPHP");
|
defined('PROJECTNAME') || define("PROJECTNAME","NexusPHP");
|
||||||
defined('NEXUSPHPURL') || define("NEXUSPHPURL","https://nexusphp.org");
|
defined('NEXUSPHPURL') || define("NEXUSPHPURL","https://nexusphp.org");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use Illuminate\Support\Str;
|
|||||||
|
|
||||||
function get_langfolder_cookie($transToLocale = false)
|
function get_langfolder_cookie($transToLocale = false)
|
||||||
{
|
{
|
||||||
global $deflang;
|
$deflang = \App\Models\Setting::getDefaultLang();
|
||||||
$lang = "";
|
$lang = "";
|
||||||
if (!isset($_COOKIE["c_lang_folder"])) {
|
if (!isset($_COOKIE["c_lang_folder"])) {
|
||||||
$lang = $deflang;
|
$lang = $deflang;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Nexus;
|
namespace Nexus;
|
||||||
|
|
||||||
|
use App\Http\Middleware\Locale;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Nexus\Plugin\Hook;
|
use Nexus\Plugin\Hook;
|
||||||
@@ -290,7 +291,7 @@ final class Nexus
|
|||||||
public static function trans($key, $replace = [], $locale = null)
|
public static function trans($key, $replace = [], $locale = null)
|
||||||
{
|
{
|
||||||
if (!IN_NEXUS) {
|
if (!IN_NEXUS) {
|
||||||
return trans($key, $replace, $locale);
|
return trans($key, $replace, $locale ?? Locale::getDefault());
|
||||||
}
|
}
|
||||||
if (empty(self::$translations)) {
|
if (empty(self::$translations)) {
|
||||||
//load from default lang dir
|
//load from default lang dir
|
||||||
@@ -301,7 +302,7 @@ final class Nexus
|
|||||||
self::loadTranslations($path, $namespace);
|
self::loadTranslations($path, $namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self::getTranslation($key, $replace, $locale);
|
return self::getTranslation($key, $replace, $locale ?? Locale::getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function loadTranslations($path, $namespace = null)
|
private static function loadTranslations($path, $namespace = null)
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ if (strlen($CURUSER['passkey']) != 32) {
|
|||||||
}
|
}
|
||||||
$dict = \Rhilip\Bencode\Bencode::load($fn);
|
$dict = \Rhilip\Bencode\Bencode::load($fn);
|
||||||
$dict['announce'] = $ssl_torrent . $base_announce_url . "?passkey=" . $CURUSER['passkey'];
|
$dict['announce'] = $ssl_torrent . $base_announce_url . "?passkey=" . $CURUSER['passkey'];
|
||||||
|
$dict['comment'] = getSchemeAndHttpHost(true) . "/details.php?id=" . $id;
|
||||||
do_log(sprintf("[ANNOUNCE_URL], user: %s, torrent: %s, url: %s", $CURUSER['id'] ?? '', $id, $dict['announce']));
|
do_log(sprintf("[ANNOUNCE_URL], user: %s, torrent: %s, url: %s", $CURUSER['id'] ?? '', $id, $dict['announce']));
|
||||||
/**
|
/**
|
||||||
* does not support multi-tracker
|
* does not support multi-tracker
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ Route::group(['middleware' => ['auth:sanctum', 'locale']], function () {
|
|||||||
Route::resource('over-forums', \App\Http\Controllers\OverForumController::class);
|
Route::resource('over-forums', \App\Http\Controllers\OverForumController::class);
|
||||||
Route::resource('forums', \App\Http\Controllers\ForumController::class);
|
Route::resource('forums', \App\Http\Controllers\ForumController::class);
|
||||||
Route::resource('topics', \App\Http\Controllers\TopicController::class);
|
Route::resource('topics', \App\Http\Controllers\TopicController::class);
|
||||||
|
|
||||||
|
Route::get('sections', [\App\Http\Controllers\UploadController::class, 'sections']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::group(['middleware' => ['admin']], function () {
|
Route::group(['middleware' => ['admin']], function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user