From df10de86d2615868ddaea18bfd293bc63e028c72 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 15 Sep 2022 01:13:14 +0800 Subject: [PATCH 01/59] change sticky promotion position --- nexus/Field/Field.php | 3 ++- public/details.php | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nexus/Field/Field.php b/nexus/Field/Field.php index b44f69b5..a467dc3b 100644 --- a/nexus/Field/Field.php +++ b/nexus/Field/Field.php @@ -426,8 +426,9 @@ JS; $rowByRowHtml .= tr($field['label'], $contentFormatted, 1); } } + $result = $rowByRowHtml; - if ($shouldRenderMixRow) { + if ($shouldRenderMixRow && $mixedRowContent) { $result .= tr($displayName, format_comment($mixedRowContent), 1); } return $result; diff --git a/public/details.php b/public/details.php index 74831a1d..d3914460 100644 --- a/public/details.php +++ b/public/details.php @@ -267,6 +267,9 @@ JS; print("\n"); // ---------------- end subtitle block -------------------// + //hook before desc + do_action('torrent_detail_before_desc', $row['id'], $CURUSER['id']); + /**************start custom fields****************/ echo $customField->renderOnTorrentDetailsPage($id); From 9723ffd98d59346bfe9608f27aa7e174139ab4dd Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 15 Sep 2022 01:36:49 +0800 Subject: [PATCH 02/59] update version number to 1.7.26 --- include/constants.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/constants.php b/include/constants.php index d26c4885..ff74f3bf 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ Date: Sat, 17 Sep 2022 14:59:46 +0800 Subject: [PATCH 03/59] add bonus exchange downloaded --- app/Console/Commands/PluginCronjob.php | 42 ++++ app/Console/Commands/Test.php | 6 +- app/Console/Kernel.php | 2 + .../Resources/System/PluginResource.php | 114 +++++++++++ .../PluginResource/Pages/ManagePlugins.php | 21 ++ app/Models/BonusLogs.php | 2 + app/Models/Plugin.php | 32 +++ app/Repositories/BaseRepository.php | 16 ++ app/Repositories/PluginRepository.php | 187 ++++++++++++++++++ ...2022_09_16_164224_create_plugins_table.php | 38 ++++ include/constants.php | 4 +- include/functions.php | 2 +- lang/chs/lang_mybonus.php | 5 + lang/chs/lang_settings.php | 6 + lang/cht/lang_mybonus.php | 5 + lang/cht/lang_settings.php | 6 + lang/en/lang_mybonus.php | 5 + lang/en/lang_settings.php | 6 + public/mybonus.php | 35 ++++ public/settings.php | 7 +- resources/lang/zh_CN/admin.php | 1 + resources/lang/zh_CN/plugin.php | 32 +++ .../plugin-resource/pages/plugins.blade.php | 3 + 23 files changed, 572 insertions(+), 5 deletions(-) create mode 100644 app/Console/Commands/PluginCronjob.php create mode 100644 app/Filament/Resources/System/PluginResource.php create mode 100644 app/Filament/Resources/System/PluginResource/Pages/ManagePlugins.php create mode 100644 app/Models/Plugin.php create mode 100644 app/Repositories/PluginRepository.php create mode 100644 database/migrations/2022_09_16_164224_create_plugins_table.php create mode 100644 resources/lang/zh_CN/plugin.php create mode 100644 resources/views/filament/resources/system/plugin-resource/pages/plugins.blade.php diff --git a/app/Console/Commands/PluginCronjob.php b/app/Console/Commands/PluginCronjob.php new file mode 100644 index 00000000..ba9c1e67 --- /dev/null +++ b/app/Console/Commands/PluginCronjob.php @@ -0,0 +1,42 @@ +option('action'); + $id = $this->option('id'); + $force = $this->option('force'); + $pluginRep = new PluginRepository(); + $pluginRep->cronjob($action, $id, $force); + $log = sprintf("[%s], action: %s, id: %s, force: %s run done !", nexus()->getRequestId(), $action, $id, $force); + $this->info($log); + do_log($log); + return 0; + } +} diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index dee5383c..52e44fa3 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -23,6 +23,7 @@ use App\Repositories\AgentAllowRepository; use App\Repositories\AttendanceRepository; use App\Repositories\ExamRepository; use App\Repositories\HitAndRunRepository; +use App\Repositories\PluginRepository; use App\Repositories\SearchBoxRepository; use App\Repositories\SearchRepository; use App\Repositories\TagRepository; @@ -87,7 +88,10 @@ class Test extends Command */ public function handle() { - $r = \Illuminate\Support\Facades\Cache::lock(); + $rep = new PluginRepository(); +// $rep->installCronjob(); + $r = $rep->getInstalledVersion('xiaomlove/nexusphp-post-like'); + dd($r); } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 93288ef9..0e2cec11 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -35,6 +35,8 @@ class Kernel extends ConsoleKernel $schedule->command('claim:settle')->hourly()->when(function () { return Carbon::now()->format('d') == '01'; })->withoutOverlapping(); + +// $schedule->command('plugin:cronjob')->everyMinute()->withoutOverlapping(); } /** diff --git a/app/Filament/Resources/System/PluginResource.php b/app/Filament/Resources/System/PluginResource.php new file mode 100644 index 00000000..c3ae5800 --- /dev/null +++ b/app/Filament/Resources/System/PluginResource.php @@ -0,0 +1,114 @@ +schema([ + Forms\Components\TextInput::make('package_name')->label(__('label.plugin.package_name')), + Forms\Components\TextInput::make('remote_url')->label(__('label.plugin.remote_url')), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('id'), + Tables\Columns\TextColumn::make('package_name')->label(__('plugin.labels.package_name')), + Tables\Columns\TextColumn::make('remote_url')->label(__('plugin.labels.remote_url')), + Tables\Columns\TextColumn::make('installed_version')->label(__('plugin.labels.installed_version')), + Tables\Columns\TextColumn::make('statusText')->label(__('label.status')), + ]) + ->filters([ + // + ]) + ->actions(self::getActions()) + ->bulkActions([ + Tables\Actions\DeleteBulkAction::make(), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ManagePlugins::route('/'), + ]; + } + + private static function getActions() + { + $actions = []; + $actions[] = Tables\Actions\EditAction::make(); + $actions[] = self::buildInstallAction(); + $actions[] = self::buildUpdateAction(); + $actions[] = Tables\Actions\DeleteAction::make('delete') + ->hidden(fn ($record) => $record->status == Plugin::STATUS_NOT_INSTALLED) + ->using(function ($record) { + $record->update(['status' => Plugin::STATUS_PRE_DELETE]); + }); + return $actions; + } + + private static function buildInstallAction() + { + return Tables\Actions\Action::make('install') + ->label(__('plugin.actions.install')) + ->icon('heroicon-o-arrow-down') + ->requiresConfirmation() + ->hidden(fn ($record) => $record->status == Plugin::STATUS_NORMAL) + ->action(function ($record) { + $record->update(['status' => Plugin::STATUS_PRE_INSTALL]); + }) + ; + } + + private static function buildUpdateAction() + { + return Tables\Actions\Action::make('update') + ->label(__('plugin.actions.update')) + ->icon('heroicon-o-arrow-up') + ->requiresConfirmation() + ->hidden(fn ($record) => in_array($record->status, [Plugin::STATUS_NOT_INSTALLED, Plugin::STATUS_PRE_UPDATE])) + ->action(function ($record) { + $record->update(['status' => Plugin::STATUS_PRE_UPDATE]); + }) + ; + } + +} diff --git a/app/Filament/Resources/System/PluginResource/Pages/ManagePlugins.php b/app/Filament/Resources/System/PluginResource/Pages/ManagePlugins.php new file mode 100644 index 00000000..c46a6317 --- /dev/null +++ b/app/Filament/Resources/System/PluginResource/Pages/ManagePlugins.php @@ -0,0 +1,21 @@ + ['text' => 'Cancel H&R'], @@ -40,6 +41,7 @@ class BonusLogs extends NexusModel self::BUSINESS_TYPE_NO_AD => ['text' => 'No ad'], self::BUSINESS_TYPE_GIFT_TO_LOW_SHARE_RATIO => ['text' => 'Gift to low share ratio'], self::BUSINESS_TYPE_LUCKY_DRAW => ['text' => 'Lucky draw'], + self::BUSINESS_TYPE_EXCHANGE_DOWNLOAD => ['text' => 'Exchange download'], ]; public static function getBonusForCancelHitAndRun() diff --git a/app/Models/Plugin.php b/app/Models/Plugin.php new file mode 100644 index 00000000..d18ff2c3 --- /dev/null +++ b/app/Models/Plugin.php @@ -0,0 +1,32 @@ + __('plugin.status.' . $attributes['status']) + ); + } +} diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 5771074f..d07c6517 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -55,4 +55,20 @@ class BaseRepository return User::query()->findOrFail(intval($user), $fields); } + protected function executeCommand($command, $format = 'string'): string|array + { + $append = " 2>&1"; + if (!str_ends_with($command, $append)) { + $command .= $append; + } + do_log("command: $command"); + $result = exec($command, $output, $result_code); + $outputString = implode("\n", $output); + do_log(sprintf('result_code: %s, result: %s, output: %s', $result_code, $result, $outputString)); + if ($result_code != 0) { + throw new \RuntimeException($outputString); + } + return $format == 'string' ? $outputString : $output; + } + } diff --git a/app/Repositories/PluginRepository.php b/app/Repositories/PluginRepository.php new file mode 100644 index 00000000..396f49ac --- /dev/null +++ b/app/Repositories/PluginRepository.php @@ -0,0 +1,187 @@ +doCronjob('install', $id, $force, Plugin::STATUS_PRE_INSTALL, Plugin::STATUS_INSTALLING); + } + if ($action == 'delete' || $action === null) { + $this->doCronjob('delete', $id, $force, Plugin::STATUS_PRE_DELETE, Plugin::STATUS_DELETING); + } + if ($action == 'update' || $action === null) { + $this->doCronjob('update', $id, $force, Plugin::STATUS_PRE_UPDATE, Plugin::STATUS_UPDATING); + } + } + + private function doCronjob($action, $id, $force, $preStatus, $doingStatus) + { + $query = Plugin::query(); + if (!$force) { + $query->where('status', $preStatus); + } + if ($id !== null) { + $query->where("id", $id); + } + $list = $query->get(); + if ($list->isEmpty()) { + do_log("No plugin need to be $action..."); + return; + } + $idArr = $list->pluck('id')->toArray(); + Plugin::query()->whereIn('id', $idArr)->update(['status' => $doingStatus]); + foreach ($list as $item) { + match ($action) { + 'install' => $this->doInstall($item), + 'update' => $this->doUpdate($item), + 'delete' => $this->doDelete($item), + default => throw new \InvalidArgumentException("Invalid action: $action") + }; + } + } + + public function doInstall(Plugin $plugin) + { + $packageName = $plugin->package_name; + try { + $this->execComposerConfig($plugin); + $this->execComposerRequire($plugin); + $output = $this->execPluginInstall($plugin); + $version = $this->getInstalledVersion($packageName); + do_log("success install plugin: $packageName version: $version"); + $update = [ + 'status' => Plugin::STATUS_NORMAL, + 'status_result' => $output, + 'installed_version' => $version + ]; + } catch (\Throwable $throwable) { + $update = [ + 'status' => Plugin::STATUS_INSTALL_FAILED, + 'status_result' => $throwable->getMessage() + ]; + do_log("fail install plugin: " . $packageName); + } finally { + $this->updateResult($plugin, $update); + } + + } + + public function doDelete(Plugin $plugin) + { + $packageName = $plugin->package_name; + $removeSuccess = true; + try { + $output = $this->execComposerRemove($plugin); + do_log("success remove plugin: $packageName"); + $update = [ + 'status' => Plugin::STATUS_NOT_INSTALLED, + 'status_result' => $output, + 'installed_version' => null, + ]; + } catch (\Throwable $throwable) { + $update = [ + 'status' => Plugin::STATUS_DELETE_FAILED, + 'status_result' => $throwable->getMessage() + ]; + $removeSuccess = false; + do_log("fail remove plugin: " . $packageName); + } finally { + if ($removeSuccess) { + $plugin->delete(); + } else { + $this->updateResult($plugin, $update); + } + } + + } + + public function doUpdate(Plugin $plugin) + { + $packageName = $plugin->package_name; + try { + $output = $this->execComposerUpdate($plugin); + $this->execPluginInstall($plugin); + $version = $this->getInstalledVersion($packageName); + do_log("success update plugin: $packageName to version: $version"); + $update = [ + 'status' => Plugin::STATUS_NORMAL, + 'status_result' => $output, + 'installed_version' => $version, + ]; + } catch (\Throwable $throwable) { + $update = [ + 'status' => Plugin::STATUS_UPDATE_FAILED, + 'status_result' => $throwable->getMessage() + ]; + do_log("fail update plugin: " . $packageName); + } finally { + $this->updateResult($plugin, $update); + } + + } + + private function getRepositoryKey(Plugin $plugin) + { + return str_replace("xiaomlove/nexusphp-", "", $plugin->package_name); + } + + private function execComposerConfig(Plugin $plugin) + { + $command = sprintf("composer config repositories.%s git %s", $this->getRepositoryKey($plugin), $plugin->remote_url); + do_log("[COMPOSER_CONFIG]: $command"); + return $this->executeCommand($command); + } + + private function execComposerRequire(Plugin $plugin) + { + $command = sprintf("composer require %s", $plugin->package_name); + do_log("[COMPOSER_REQUIRE]: $command"); + return $this->executeCommand($command); + } + + private function execComposerRemove(Plugin $plugin) + { + $command = sprintf("composer remove %s", $plugin->package_name); + do_log("[COMPOSER_REMOVE]: $command"); + return $this->executeCommand($command); + } + + private function execComposerUpdate(Plugin $plugin) + { + $command = sprintf("composer update %s", $plugin->package_name); + do_log("[COMPOSER_UPDATE]: $command"); + return $this->executeCommand($command); + } + + private function execPluginInstall(Plugin $plugin) + { + $command = sprintf("php artisan plugin install %s", $plugin->package_name); + do_log("[PLUGIN_INSTALL]: $command"); + return $this->executeCommand($command); + } + + private function updateResult(Plugin $plugin, array $update) + { + $update['status_result'] = $update['status_result'] . "\n\nREQUEST_ID: " . nexus()->getRequestId(); + do_log("[UPDATE]: " . json_encode($update)); + $plugin->update($update); + } + + public function getInstalledVersion($packageName) + { + $command = sprintf('composer info |grep -E %s', $packageName); + $result = $this->executeCommand($command); + $parts = preg_split("/[\s]+/", trim($result)); + $version = $parts[1]; + if (str_contains($version, 'dev')) { + $version .= " $parts[2]"; + } + return $version; + } + + +} diff --git a/database/migrations/2022_09_16_164224_create_plugins_table.php b/database/migrations/2022_09_16_164224_create_plugins_table.php new file mode 100644 index 00000000..b904aca8 --- /dev/null +++ b/database/migrations/2022_09_16_164224_create_plugins_table.php @@ -0,0 +1,38 @@ +id(); + $table->string('display_name')->nullable(true); + $table->string('package_name')->nullable(false)->unique(); + $table->string('remote_url')->nullable(true); + $table->string('installed_version')->nullable(true); + $table->text('description')->nullable(true); + $table->integer('status')->default(-1); + $table->text('status_result')->nullable(true); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('plugins'); + } +}; diff --git a/include/constants.php b/include/constants.php index ff74f3bf..42baac68 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ count(); foreach ($harems as $harem) { $result = calculate_seed_bonus($harem->id); - $addition += $result['all_bonus']; + $addition += $result['seed_bonus']; } do_log("[HAREM_ADDITION], user: $uid, haremsCount: $haremsCount ,addition: $addition"); return $addition; diff --git a/lang/chs/lang_mybonus.php b/lang/chs/lang_mybonus.php index 11ef47eb..28b45e47 100644 --- a/lang/chs/lang_mybonus.php +++ b/lang/chs/lang_mybonus.php @@ -6,6 +6,7 @@ $lang_mybonus = array 'std_karma_system_disabled' => "魔力值系统当前处于关闭中。", 'std_points_active' => "不过你的魔力值仍在计算中。", 'text_success_upload' => "祝贺你,你成功增加了上传值!", + 'text_success_download' => "祝贺你,你成功增加了下载值!", 'text_success_invites' => "祝贺你,你获得了1个新的邀请名额!", 'text_success_vip' => "祝贺你,你获得了一个月的", 'text_success_vip_two' => "资格!", @@ -74,8 +75,12 @@ $lang_mybonus = array 'text_not_enough_bonus' => "对不起,你没有足够的魔力值。还有,你怎么到这来的?", 'text_uploaded_one' => "1.0 GB上传量", 'text_uploaded_note' => "如果有足够的魔力值,你可以用它来换取上传量。交易完成后,你的魔力值会减少,上传量则会增加。", + 'text_download_note' => "如果有足够的魔力值,你可以用它来换取下载量。交易完成后,你的魔力值会减少,下载量则会增加。", 'text_uploaded_two' => "5.0 GB上传量", 'text_uploaded_three' => "10.0 GB上传量", + 'text_uploaded_four' => "100.0 GB上传量", + 'text_downloaded_ten_gb' => "10.0 GB 下载量", + 'text_downloaded_hundred_gb' => "100.0 GB 下载量", 'text_buy_invite' => "1个邀请名额", 'text_buy_invite_note' => "如果有足够的魔力值,你可以用它来换取邀请名额。交易完成后,你的魔力值会减少,邀请名额数则会增加。", 'text_custom_title' => "自定义头衔", diff --git a/lang/chs/lang_settings.php b/lang/chs/lang_settings.php index 9566cb22..da6f8585 100644 --- a/lang/chs/lang_settings.php +++ b/lang/chs/lang_settings.php @@ -773,6 +773,12 @@ $lang_settings = array 'text_offer_skip_approved_count_note' => '当通过的候选数大于等于此数值时,可直接发布不用提交候选。', 'row_torrent_delete' => '删除种子', 'text_torrent_delete_note' => '。删除种子', + 'row_hundred_gb_credit' => "100.0 GB 上传量", + 'text_hundred_gb_credit_note' => "个魔力值,如果他选择交换100.0 GB上传量。默认'10000'。", + 'row_ten_gb_download_credit' => "10.0 GB 下载量", + 'text_ten_gb_download_credit_note' => " 个魔力值,如果他选择交换10.0 GB下载量。默认'1000'。", + 'row_hundred_gb_download_credit' => "100.0 GB 下载量", + 'text_hundred_gb_download_credit_note' => " 个魔力值,如果他选择交换100.0 GB下载量。默认'8000'。", ); ?> diff --git a/lang/cht/lang_mybonus.php b/lang/cht/lang_mybonus.php index d7376a0b..fcce5ccf 100644 --- a/lang/cht/lang_mybonus.php +++ b/lang/cht/lang_mybonus.php @@ -6,6 +6,7 @@ $lang_mybonus = array 'std_karma_system_disabled' => "魔力值系統當前處於關閉中。", 'std_points_active' => "不過你的魔力值仍在計算中。", 'text_success_upload' => "祝賀你,你成功增加了上傳值!", + 'text_success_download' => "祝賀你,你成功增加了下載值!", 'text_success_invites' => "祝賀你,你獲得了1個新的邀請名額!", 'text_success_vip' => "祝賀你,你獲得了一個月的", 'text_success_vip_two' => "資格!", @@ -74,8 +75,12 @@ $lang_mybonus = array 'text_not_enough_bonus' => "對不起,你沒有足夠的魔力值。還有,你怎麼到這來的?", 'text_uploaded_one' => "1.0 GB上傳量", 'text_uploaded_note' => "如果有足夠的魔力值,你可以用它來換取上傳量。交易完成後,你的魔力值會減少,上傳量則會增加。", + 'text_download_note' => "如果有足夠的魔力值,你可以用它來換取下載量。交易完成後,你的魔力值會減少,下載量則會增加。", 'text_uploaded_two' => "5.0 GB上傳量", 'text_uploaded_three' => "10.0 GB上傳量", + 'text_uploaded_four' => "100.0 GB上傳量", + 'text_downloaded_ten_gb' => "10.0 GB 下載量", + 'text_downloaded_hundred_gb' => "100.0 GB 下載量", 'text_buy_invite' => "1個邀請名額", 'text_buy_invite_note' => "如果有足夠的魔力值,你可以用它來換取邀請名額。交易完成後,你的魔力值會減少,邀請名額數則會增加。", 'text_custom_title' => "自定義頭銜", diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index 6ec1fc42..af79ecf1 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -773,6 +773,12 @@ $lang_settings = array 'text_offer_skip_approved_count_note' => '當通過的候選數大於等於此數值時,可直接發布不用提交候選。', 'row_torrent_delete' => '移除種子', 'text_torrent_delete_note' => '。移除種子', + 'row_hundred_gb_credit' => "100.0 GB 上傳量", + 'text_hundred_gb_credit_note' => "個魔力值,如果他選擇交換100.0 GB上傳量。默認'10000'。", + 'row_ten_gb_download_credit' => "10.0 GB 下載量", + 'text_ten_gb_download_credit_note' => " 個魔力值,如果他選擇交換10.0 GB下載量。默認'1000'。", + 'row_hundred_gb_download_credit' => "100.0 GB 下載量", + 'text_hundred_gb_download_credit_note' => " 個魔力值,如果他選擇交換100.0 GB下載量。默認'8000'。", ); ?> diff --git a/lang/en/lang_mybonus.php b/lang/en/lang_mybonus.php index 8820f00f..b0b09edd 100644 --- a/lang/en/lang_mybonus.php +++ b/lang/en/lang_mybonus.php @@ -6,6 +6,7 @@ $lang_mybonus = array 'std_karma_system_disabled' => "Karma Bonus Point System is currently disabled. ", 'std_points_active' => "However your points is still active.", 'text_success_upload' => "Congratulations! You have just increased your Uploaded Amount!", + 'text_success_download' => "Congratulations! You have just increased your Downloaded Amount!", 'text_success_invites' => "Congratulations! You have got yourself 1 new invite!", 'text_success_vip' => "Congratulations! You have got yourself ", 'text_success_vip_two' => " status for one month!", @@ -74,8 +75,12 @@ $lang_mybonus = array 'text_not_enough_bonus' => "Sorry, you do not have enough bonus. BTW, how dou you get here?", 'text_uploaded_one' => "1.0 GB Uploaded", 'text_uploaded_note' => "With enough bonus points acquired, you are able to exchange them for an Upload Credit. The points are then removed from your Bonus Bank and the credit is added to your total uploaded amount.", + 'text_download_note' => "With enough bonus points acquired, you are able to exchange them for an Download Credit. The points are then removed from your Bonus Bank and the credit is added to your total downloaded amount.", 'text_uploaded_two' => "5.0 GB Uploaded", 'text_uploaded_three' => "10.0 GB Uploaded", + 'text_uploaded_four' => "100.0 GB Uploaded", + 'text_downloaded_ten_gb' => "10.0 GB Downloaded", + 'text_downloaded_hundred_gb' => "100.0 GB Downloaded", 'text_buy_invite' => "1 Invite", 'text_buy_invite_note' => "With enough bonus points acquired, you are able to exchange them for a few invites. The points are then removed from your Bonus Bank and the invitations are added to your invites amount.", 'text_custom_title' => "Custom Title!", diff --git a/lang/en/lang_settings.php b/lang/en/lang_settings.php index 9e0fc03b..c172cd12 100644 --- a/lang/en/lang_settings.php +++ b/lang/en/lang_settings.php @@ -773,6 +773,12 @@ $lang_settings = array 'text_offer_skip_approved_count_note' => 'When the number of approved offer is greater than or equal to this value, you can upload directly without submitting offers.', 'row_torrent_delete' => 'Delete torrent', 'text_torrent_delete_note' => '.Delete torrent', + 'row_hundred_gb_credit' => "100.0 GB uploading credit", + 'text_hundred_gb_credit_note' => " bonus points to exchange for 100.0 GB uploading credit. Default '10000'.", + 'row_ten_gb_download_credit' => "10.0 GB downloading credit", + 'text_ten_gb_download_credit_note' => " bonus points to exchange for 10.0 GB downloading credit. Default '1000'.", + 'row_hundred_gb_download_credit' => "100.0 GB downloading credit", + 'text_hundred_gb_download_credit_note' => " bonus points to exchange for 100.0 GB downloading credit. Default '8000'.", ); ?> diff --git a/public/mybonus.php b/public/mybonus.php index 5be81c7e..cbc9032a 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -39,6 +39,33 @@ function bonusarray($option = 0){ $bonus['description'] = $lang_mybonus['text_uploaded_note']; $results[] = $bonus; + //100.0 GB Uploaded + $bonus = array(); + $bonus['points'] = get_setting('bonus.hundredgbupload'); + $bonus['art'] = 'traffic'; + $bonus['menge'] = 107374182400; + $bonus['name'] = $lang_mybonus['text_uploaded_four']; + $bonus['description'] = $lang_mybonus['text_uploaded_note']; + $results[] = $bonus; + + //10.0 GB Downloaded + $bonus = array(); + $bonus['points'] = get_setting('bonus.tengbdownload'); + $bonus['art'] = 'traffic_downloaded'; + $bonus['menge'] = 10737418240; + $bonus['name'] = $lang_mybonus['text_downloaded_ten_gb']; + $bonus['description'] = $lang_mybonus['text_download_note']; + $results[] = $bonus; + + //100.0 GB Downloaded + $bonus = array(); + $bonus['points'] = get_setting('bonus.hundredgbdownload'); + $bonus['art'] = 'traffic_downloaded'; + $bonus['menge'] = 107374182400; + $bonus['name'] = $lang_mybonus['text_downloaded_hundred_gb']; + $bonus['description'] = $lang_mybonus['text_download_note']; + $results[] = $bonus; + //Invite $bonus = array(); $bonus['points'] = $oneinvite_bonus; @@ -246,6 +273,8 @@ unset($msg); if (isset($do)) { if ($do == "upload") $msg = $lang_mybonus['text_success_upload']; + if ($do == "download") + $msg = $lang_mybonus['text_success_download']; elseif ($do == "invite") $msg = $lang_mybonus['text_success_invites']; elseif ($do == "vip") @@ -538,6 +567,12 @@ if ($action == "exchange") { nexus_redirect("" . get_protocol_prefix() . "$BASEURL/mybonus.php?do=upload"); } } + if($art == "traffic_downloaded") { + $downloaded = $CURUSER['downloaded']; + $down = $downloaded + $bonusarray['menge']; + $bonusRep->consumeUserBonus($CURUSER['id'], $points, \App\Models\BonusLogs::BUSINESS_TYPE_EXCHANGE_DOWNLOAD, $points. " Points for download bonus.", ['downloaded' => $down]); + nexus_redirect("" . get_protocol_prefix() . "$BASEURL/mybonus.php?do=download"); + } //=== trade for one month VIP status ***note "SET class = '10'" change "10" to whatever your VIP class number is elseif($art == "class") { if (get_user_class() >= UC_VIP) { diff --git a/public/settings.php b/public/settings.php index d97ba88f..a7b746f0 100644 --- a/public/settings.php +++ b/public/settings.php @@ -97,7 +97,7 @@ elseif ($action == 'savesettings_bonus') // save bonus 'addcomment','pollvote','offervote', 'funboxvote','saythanks','receivethanks','funboxreward','onegbupload','fivegbupload', 'tengbupload', 'ratiolimit','dlamountlimit','oneinvite','customtitle','vipstatus','bonusgift', 'basictax', 'taxpercentage', 'prolinkpoint', 'prolinktime', 'attendance_initial', 'attendance_step', 'attendance_max', 'cancel_hr', 'attendance_card', - 'harem_addition' + 'harem_addition', 'hundredgbupload', 'tengbdownload', 'hundredgbdownload' ); GetVar($validConfig); $BONUS = []; @@ -582,6 +582,11 @@ elseif ($action == 'bonussettings'){ tr($lang_settings['row_one_gb_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_one_gb_credit_note'], 1); tr($lang_settings['row_five_gb_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_five_gb_credit_note'], 1); tr($lang_settings['row_ten_gb_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_ten_gb_credit_note'], 1); + tr($lang_settings['row_hundred_gb_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_hundred_gb_credit_note'], 1); + tr($lang_settings['row_ten_gb_download_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_ten_gb_download_credit_note'], 1); + tr($lang_settings['row_hundred_gb_download_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_hundred_gb_download_credit_note'], 1); + + tr($lang_settings['row_ratio_limit'],$lang_settings['text_user_with_ratio']."".$lang_settings['text_uploaded_amount_above']."".$lang_settings['text_ratio_limit_default'], 1); tr($lang_settings['row_buy_an_invite'],$lang_settings['text_it_costs_user']."".$lang_settings['text_buy_an_invite_note'], 1); tr($lang_settings['row_custom_title'],$lang_settings['text_it_costs_user']."".$lang_settings['text_custom_title_note'], 1); diff --git a/resources/lang/zh_CN/admin.php b/resources/lang/zh_CN/admin.php index ed68f5d7..546c835e 100644 --- a/resources/lang/zh_CN/admin.php +++ b/resources/lang/zh_CN/admin.php @@ -24,6 +24,7 @@ return [ 'torrent_deny_reason' => '拒绝原因', 'roles' => '角色', 'permissions' => '权限', + 'plugin' => '插件', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/zh_CN/plugin.php b/resources/lang/zh_CN/plugin.php new file mode 100644 index 00000000..23da8598 --- /dev/null +++ b/resources/lang/zh_CN/plugin.php @@ -0,0 +1,32 @@ + [ + 'install' => '安装', + 'delete' => '删除', + 'update' => '升级', + ], + 'labels' => [ + 'display_name' => '名称', + 'package_name' => '包名', + 'remote_url' => '仓库地址', + 'installed_version' => '已安装版本', + 'status' => '状态', + ], + 'status' => [ + \App\Models\Plugin::STATUS_NORMAL => '正常', + \App\Models\Plugin::STATUS_NOT_INSTALLED => '未安装', + + \App\Models\Plugin::STATUS_PRE_INSTALL => '准备安装', + \App\Models\Plugin::STATUS_INSTALLING => '安装中', + \App\Models\Plugin::STATUS_INSTALL_FAILED => '安装失败', + + \App\Models\Plugin::STATUS_PRE_UPDATE => '准备升级', + \App\Models\Plugin::STATUS_UPDATING => '升级中', + \App\Models\Plugin::STATUS_UPDATE_FAILED => '升级失败', + + \App\Models\Plugin::STATUS_PRE_DELETE => '准备删除', + \App\Models\Plugin::STATUS_DELETING => '删除中', + \App\Models\Plugin::STATUS_DELETE_FAILED => '删除失败', + ], +]; diff --git a/resources/views/filament/resources/system/plugin-resource/pages/plugins.blade.php b/resources/views/filament/resources/system/plugin-resource/pages/plugins.blade.php new file mode 100644 index 00000000..cd00dafb --- /dev/null +++ b/resources/views/filament/resources/system/plugin-resource/pages/plugins.blade.php @@ -0,0 +1,3 @@ + + + From 1a0ad86b326a7b690b576bc6042616306640d14a Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 17 Sep 2022 18:55:26 +0800 Subject: [PATCH 04/59] add torrent pos_state_until --- app/Models/Torrent.php | 15 +++++++++ ..._add_pos_state_until_to_torrents_table.php | 32 +++++++++++++++++++ include/cleanup.php | 22 +++++++++++++ include/functions.php | 20 ++++++++++++ public/edit.php | 3 +- public/takeedit.php | 20 ++++++++++-- public/takeupload.php | 25 +++++++++++++++ public/upload.php | 25 +++++++++++++++ .../jquery.datetimepicker.full.min.js | 1 + .../jquery.datetimepicker.min.css | 1 + 10 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 database/migrations/2022_09_17_150606_add_pos_state_until_to_torrents_table.php create mode 100644 public/vendor/jquery-datetimepicker/jquery.datetimepicker.full.min.js create mode 100644 public/vendor/jquery-datetimepicker/jquery.datetimepicker.min.css diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index aa7b762f..cce44462 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -256,6 +256,21 @@ class Torrent extends NexusModel return $result; } + public static function listPickInfo($onlyKeyValue = false, $valueField = 'text'): array + { + $result = self::$pickTypes; + $keyValue = []; + foreach ($result as $status => &$info) { + $text = nexus_trans('torrent.pick_info.' . $status); + $info['text'] = $text; + $keyValue[$status] = $info[$valueField]; + } + if ($onlyKeyValue) { + return $keyValue; + } + return $result; + } + public function getHrAttribute(): string { $hrMode = Setting::get('hr.mode'); diff --git a/database/migrations/2022_09_17_150606_add_pos_state_until_to_torrents_table.php b/database/migrations/2022_09_17_150606_add_pos_state_until_to_torrents_table.php new file mode 100644 index 00000000..7435ecc3 --- /dev/null +++ b/database/migrations/2022_09_17_150606_add_pos_state_until_to_torrents_table.php @@ -0,0 +1,32 @@ +dateTime('pos_state_until')->nullable(true)->after('pos_state'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('torrents', function (Blueprint $table) { + $table->dropColumn('pos_state_until'); + }); + } +}; diff --git a/include/cleanup.php b/include/cleanup.php index 3f2c22a3..9cba944e 100644 --- a/include/cleanup.php +++ b/include/cleanup.php @@ -462,6 +462,28 @@ function docleanup($forceAll = 0, $printProgress = false) { if ($printProgress) { printProgress($log); } + + //expire torrent sticky + $toBeExpirePosStates = [ + \App\Models\Torrent::POS_STATE_STICKY_FIRST, + \App\Models\Torrent::POS_STATE_STICKY_SECOND, + ]; + $update = [ + 'pos_state' => \App\Models\Torrent::POS_STATE_STICKY_NONE, + 'pos_state_until' => null, + ]; + \App\Models\Torrent::query() + ->whereIn('pos_state', $toBeExpirePosStates) + ->whereNotNull('pos_state_until') + ->where('pos_state_until', '<', now()) + ->update($update); + $log = "expire torrent pos state"; + do_log($log); + if ($printProgress) { + printProgress($log); + } + + //automatically pick hot if ($hotdays_torrent) { diff --git a/include/functions.php b/include/functions.php index d6ce3414..e60b3856 100644 --- a/include/functions.php +++ b/include/functions.php @@ -5872,4 +5872,24 @@ function calculate_harem_addition($uid) return $addition; } +function datetimepicker_input($name, $value = '', $label = '') +{ + \Nexus\Nexus::css('vendor/jquery-datetimepicker/jquery.datetimepicker.min.css', 'footer', true); + \Nexus\Nexus::js('vendor/jquery-datetimepicker/jquery.datetimepicker.full.min.js', 'footer', true); + $id = "datetime-picker-$name"; + $input = sprintf('%s', $label, $id, $name, $value); + $lang = get_langfolder_cookie(true); + if ($lang == 'zh_CN') { + $lang = 'zh'; + } + $lang = str_replace('_', '-', $lang); + $js = << diff --git a/public/edit.php b/public/edit.php index ae6720c1..f490bd8a 100644 --- a/public/edit.php +++ b/public/edit.php @@ -182,7 +182,8 @@ else { foreach (\App\Models\Torrent::listPosStates() as $key => $value) { $options[] = "".$value['text'].""; } - $pickcontent .= "".$lang_edit['row_torrent_position'].": "."   "; + $pickcontent .= "".$lang_edit['row_torrent_position'].": "."   "; + $pickcontent .= datetimepicker_input('pos_state_until', $row['pos_state_until'], nexus_trans('label.deadline') . ": "); } if(user_can('torrentmanage') && ($CURUSER["picker"] == 'yes' || get_user_class() >= \App\Models\User::CLASS_SYSOP)) { diff --git a/public/takeedit.php b/public/takeedit.php index 5278e0f4..3351ff86 100644 --- a/public/takeedit.php +++ b/public/takeedit.php @@ -143,9 +143,21 @@ if(user_can('torrentonpromotion')) } } } -if(user_can('torrentsticky') && isset($_POST['sel_posstate']) && isset(\App\Models\Torrent::$posStates[$_POST['sel_posstate']])) +if(user_can('torrentsticky')) { - $updateset[] = "pos_state = '" . $_POST['sel_posstate'] . "'"; + if (isset($_POST['pos_state']) && isset(\App\Models\Torrent::$posStates[$_POST['pos_state']])) { + $posStateUntil = null; + $posState = \App\Models\Torrent::POS_STATE_STICKY_NONE; + if (!empty($_POST['pos_state_until']) && $_POST['pos_state'] != \App\Models\Torrent::POS_STATE_STICKY_NONE) { + $posStateUntil = \Carbon\Carbon::parse($_POST['pos_state_until']); + if ($posStateUntil->gte(now())) { + $posState = $_POST['pos_state']; + } + } + $updateset[] = sprintf("pos_state = %s", sqlesc($posState)); + $updateset[] = sprintf("pos_state_until = %s", sqlesc($posStateUntil)); + } + } $pick_info = ""; @@ -202,7 +214,9 @@ $descriptionArr = format_description($descr); $cover = get_image_from_description($descriptionArr, true, false); $updateset[] = "cover = " . sqlesc($cover); -$affectedRows = sql_query("UPDATE torrents SET " . join(",", $updateset) . " WHERE id = $id") or sqlerr(__FILE__, __LINE__); +$sql = "UPDATE torrents SET " . join(",", $updateset) . " WHERE id = $id"; +do_log("[UPDATE_TORRENT]: $sql"); +$affectedRows = sql_query($sql) or sqlerr(__FILE__, __LINE__); $dateTimeStringNow = date("Y-m-d H:i:s"); diff --git a/public/takeupload.php b/public/takeupload.php index f1312c3d..3ba96463 100644 --- a/public/takeupload.php +++ b/public/takeupload.php @@ -342,6 +342,31 @@ $insert = [ if (isset($_POST['hr']) && isset(\App\Models\Torrent::$hrStatus[$_POST['hr']]) && user_can('torrent_hr')) { $insert['hr'] = $_POST['hr']; } +if(user_can('torrentsticky')) { + if (isset($_POST['pos_state']) && isset(\App\Models\Torrent::$posStates[$_POST['pos_state']])) { + $posStateUntil = null; + $posState = \App\Models\Torrent::POS_STATE_STICKY_NONE; + if (!empty($_POST['pos_state_until']) && $_POST['pos_state'] != \App\Models\Torrent::POS_STATE_STICKY_NONE) { + $posStateUntil = \Carbon\Carbon::parse($_POST['pos_state_until']); + if ($posStateUntil->gte(now())) { + $posState = $_POST['pos_state']; + } + } + $insert['pos_state'] = $posState; + $insert['pos_state_until'] = $posStateUntil; + } +} +if(user_can('torrentmanage') && ($CURUSER['picker'] == 'yes' || get_user_class() >= \App\Models\User::CLASS_SYSOP)) { + if (isset($_POST['picktype']) && isset(\App\Models\Torrent::$pickTypes[$_POST['picktype']])) { + $insert['picktype'] = $_POST['picktype']; + if ($insert['picktype'] == \App\Models\Torrent::PICK_NORMAL) { + $insert['picktime'] = null; + } else { + $insert['picktime'] = now()->toDateTimeString(); + } + } +} +do_log("[INSERT_TORRENT]: " . nexus_json_encode($insert)); $id = \Nexus\Database\NexusDB::insert('torrents', $insert); //$ret = sql_query("INSERT INTO torrents (filename, owner, visible, anonymous, name, size, numfiles, type, url, small_descr, descr, ori_descr, category, source, medium, codec, audiocodec, standard, processing, team, save_as, sp_state, added, last_action, nfo, info_hash, pt_gen, technical_info) VALUES (".sqlesc($fname).", ".sqlesc($CURUSER["id"]).", 'yes', ".sqlesc($anonymous).", ".sqlesc($torrent).", ".sqlesc($totallen).", ".count($filelist).", ".sqlesc($type).", ".sqlesc($url).", ".sqlesc($small_descr).", ".sqlesc($descr).", ".sqlesc($descr).", ".sqlesc($catid).", ".sqlesc($sourceid).", ".sqlesc($mediumid).", ".sqlesc($codecid).", ".sqlesc($audiocodecid).", ".sqlesc($standardid).", ".sqlesc($processingid).", ".sqlesc($teamid).", ".sqlesc($dname).", ".sqlesc($sp_state) . diff --git a/public/upload.php b/public/upload.php index ba97179f..3842f7b3 100644 --- a/public/upload.php +++ b/public/upload.php @@ -2,6 +2,7 @@ require_once("../include/bittorrent.php"); dbconn(); require_once(get_langfile_path()); +require_once(get_langfile_path('edit.php')); loggedinorreturn(); parked(); $userInfo = \App\Models\User::query()->findOrFail($CURUSER['id']); @@ -180,6 +181,30 @@ JS; } //===end + //pick + $pickcontent = ''; + if(user_can('torrentsticky')) + { + $options = []; + foreach (\App\Models\Torrent::listPosStates() as $key => $value) { + $options[] = "".$value['text'].""; + } + $pickcontent .= "".$lang_edit['row_torrent_position'].": "."   "; + $pickcontent .= datetimepicker_input('pos_state_until', '', nexus_trans('label.deadline') . ": "); + } + if(user_can('torrentmanage') && ($CURUSER["picker"] == 'yes' || get_user_class() >= \App\Models\User::CLASS_SYSOP)) + { + if ($pickcontent) $pickcontent .= '
'; + $pickcontent .= "".$lang_edit['row_recommended_movie'].": "."'; + } + if ($pickcontent) { + tr($lang_edit['row_pick'], $pickcontent, 1); + } + if(user_can('beanonymous')) { tr($lang_upload['row_show_uploader'], "".$lang_upload['checkbox_hide_uploader_note'], 1); diff --git a/public/vendor/jquery-datetimepicker/jquery.datetimepicker.full.min.js b/public/vendor/jquery-datetimepicker/jquery.datetimepicker.full.min.js new file mode 100644 index 00000000..7947c33a --- /dev/null +++ b/public/vendor/jquery-datetimepicker/jquery.datetimepicker.full.min.js @@ -0,0 +1 @@ +var DateFormatter;!function(){"use strict";var D,s,r,a,n;D=function(e,t){return"string"==typeof e&&"string"==typeof t&&e.toLowerCase()===t.toLowerCase()},s=function(e,t,a){var n=a||"0",r=e.toString();return r.length'),u=L('
'),d.append(u),l.addClass("xdsoft_scroller_box").append(d),p=function(e){var t=a(e).y-r+g;t<0&&(t=0),t+u[0].offsetHeight>h&&(t=h-u[0].offsetHeight),l.trigger("scroll_element.xdsoft_scroller",[c?t/c:0])},u.on("touchstart.xdsoft_scroller mousedown.xdsoft_scroller",function(e){i||l.trigger("resize_scroll.xdsoft_scroller",[y]),r=a(e).y,g=parseInt(u.css("marginTop"),10),h=d[0].offsetHeight,"mousedown"===e.type||"touchstart"===e.type?(D.ownerDocument&&L(D.ownerDocument.body).addClass("xdsoft_noselect"),L([D.ownerDocument.body,D.contentWindow]).on("touchend mouseup.xdsoft_scroller",function e(){L([D.ownerDocument.body,D.contentWindow]).off("touchend mouseup.xdsoft_scroller",e).off("mousemove.xdsoft_scroller",p).removeClass("xdsoft_noselect")}),L(D.ownerDocument.body).on("mousemove.xdsoft_scroller",p)):(t=!0,e.stopPropagation(),e.preventDefault())}).on("touchmove",function(e){t&&(e.preventDefault(),p(e))}).on("touchend touchcancel",function(){t=!1,g=0}),l.on("scroll_element.xdsoft_scroller",function(e,t){i||l.trigger("resize_scroll.xdsoft_scroller",[t,!0]),t=1'),e=L(''),g=L('
'),F=L('
'),C=L('
'),o=L('
'),u=o.find(".xdsoft_time_box").eq(0),P=L('
'),i=L(''),Y=L('
'),A=L('
'),s=!1,d=0;I.id&&_.attr("id",I.id),I.style&&_.attr("style",I.style),I.weeks&&_.addClass("xdsoft_showweeks"),I.rtl&&_.addClass("xdsoft_rtl"),_.addClass("xdsoft_"+I.theme),_.addClass(I.className),F.find(".xdsoft_month span").after(Y),F.find(".xdsoft_year span").after(A),F.find(".xdsoft_month,.xdsoft_year").on("touchstart mousedown.xdsoft",function(e){var t,a,n=L(this).find(".xdsoft_select").eq(0),r=0,o=0,i=n.is(":visible");for(F.find(".xdsoft_select").hide(),W.currentTime&&(r=W.currentTime[L(this).hasClass("xdsoft_month")?"getMonth":"getFullYear"]()),n[i?"hide":"show"](),t=n.find("div.xdsoft_option"),a=0;aI.touchMovedThreshold&&(this.touchMoved=!0)};function f(){var e,t=!1;return I.startDate?t=W.strToDate(I.startDate):(t=I.value||(O&&O.val&&O.val()?O.val():""))?(t=W.strToDateTime(t),I.yearOffset&&(t=new Date(t.getFullYear()-I.yearOffset,t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()))):I.defaultDate&&(t=W.strToDateTime(I.defaultDate),I.defaultTime&&(e=W.strtotime(I.defaultTime),t.setHours(e.getHours()),t.setMinutes(e.getMinutes()))),t&&W.isValidDate(t)?_.data("changed",!0):t="",t||0}function c(m){var h=function(e,t){var a=e.replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g,"\\$1").replace(/_/g,"{digit+}").replace(/([0-9]{1})/g,"{digit$1}").replace(/\{digit([0-9]{1})\}/g,"[0-$1_]{1}").replace(/\{digit[\+]\}/g,"[0-9_]{1}");return new RegExp(a).test(t)},g=function(e,t){if(!(e="string"==typeof e||e instanceof String?m.ownerDocument.getElementById(e):e))return!1;if(e.createTextRange){var a=e.createTextRange();return a.collapse(!0),a.moveEnd("character",t),a.moveStart("character",t),a.select(),!0}return!!e.setSelectionRange&&(e.setSelectionRange(t,t),!0)};m.mask&&O.off("keydown.xdsoft"),!0===m.mask&&(E.formatMask?m.mask=E.formatMask(m.format):m.mask=m.format.replace(/Y/g,"9999").replace(/F/g,"9999").replace(/m/g,"19").replace(/d/g,"39").replace(/H/g,"29").replace(/i/g,"59").replace(/s/g,"59")),"string"===L.type(m.mask)&&(h(m.mask,O.val())||(O.val(m.mask.replace(/[0-9]/g,"_")),g(O[0],0)),O.on("paste.xdsoft",function(e){var t=(e.clipboardData||e.originalEvent.clipboardData||window.clipboardData).getData("text"),a=this.value,n=this.selectionStart;return a=a.substr(0,n)+t+a.substr(n+t.length),n+=t.length,h(m.mask,a)?(this.value=a,g(this,n)):""===L.trim(a)?this.value=m.mask.replace(/[0-9]/g,"_"):O.trigger("error_input.xdsoft"),e.preventDefault(),!1}),O.on("keydown.xdsoft",function(e){var t,a=this.value,n=e.which,r=this.selectionStart,o=this.selectionEnd,i=r!==o;if(48<=n&&n<=57||96<=n&&n<=105||8===n||46===n){for(t=8===n||46===n?"_":String.fromCharCode(96<=n&&n<=105?n-48:n),8===n&&r&&!i&&(r-=1);;){var s=m.mask.substr(r,1),d=r",I.weeks&&(l+=""),e=0;e<7;e+=1)l+=""+I.i18n[R].dayOfWeekShort[(e+I.dayOfWeekStart)%7]+"";for(l+="",l+="",!1!==I.maxDate&&(h=W.strToDate(I.maxDate),h=new Date(h.getFullYear(),h.getMonth(),h.getDate(),23,59,59,999)),!1!==I.minDate&&(g=W.strToDate(I.minDate),g=new Date(g.getFullYear(),g.getMonth(),g.getDate())),!1!==I.minDateTime&&(p=W.strToDate(I.minDateTime),p=new Date(p.getFullYear(),p.getMonth(),p.getDate(),p.getHours(),p.getMinutes(),p.getSeconds())),!1!==I.maxDateTime&&(D=W.strToDate(I.maxDateTime),D=new Date(D.getFullYear(),D.getMonth(),D.getDate(),D.getHours(),D.getMinutes(),D.getSeconds())),!1!==D&&(u=31*(12*D.getFullYear()+D.getMonth())+D.getDate());c",v=!1,I.weeks&&(l+=""+o+"")),l+='
'+n+"
",f.getDay()===I.dayOfWeekStartPrev&&(l+="",v=!0),f.setDate(n+1)}l+="",C.html(l),F.find(".xdsoft_label span").eq(0).text(I.i18n[R].months[W.currentTime.getMonth()]),F.find(".xdsoft_label span").eq(1).text(W.currentTime.getFullYear()+I.yearOffset),M=k="";var x=0;if(!1!==I.minTime){var T=W.strtotime(I.minTime);x=60*T.getHours()+T.getMinutes()}var S=1440;if(!1!==I.maxTime){T=W.strtotime(I.maxTime);S=60*T.getHours()+T.getMinutes()}if(!1!==I.minDateTime){T=W.strToDateTime(I.minDateTime);if(E.formatDate(W.currentTime,I.formatDate)===E.formatDate(T,I.formatDate)){var M=60*T.getHours()+T.getMinutes();x'+E.formatDate(n,I.formatTime)+""},I.allowTimes&&L.isArray(I.allowTimes)&&I.allowTimes.length)for(c=0;c'+(c+I.yearOffset)+"";for(A.children().eq(0).html(H),c=parseInt(I.monthStart,10),H="";c<=parseInt(I.monthEnd,10);c+=1)H+='
'+I.i18n[R].months[c]+"
";Y.children().eq(0).html(H),L(_).trigger("generate.xdsoft")},10),e.stopPropagation()}).on("afterOpen.xdsoft",function(){var e,t,a,n;I.timepicker&&(P.find(".xdsoft_current").length?e=".xdsoft_current":P.find(".xdsoft_init_time").length&&(e=".xdsoft_init_time"),e?(t=u[0].clientHeight,(a=P[0].offsetHeight)-t<(n=P.find(e).index()*I.timeHeightInTimePicker+1)&&(n=a-t),u.trigger("scroll_element.xdsoft_scroller",[parseInt(n,10)/(a-t)])):u.trigger("scroll_element.xdsoft_scroller",[0]))}),n=0,C.on("touchend click.xdsoft","td",function(e){e.stopPropagation(),n+=1;var t=L(this),a=W.currentTime;if(null==a&&(W.currentTime=W.now(),a=W.currentTime),t.hasClass("xdsoft_disabled"))return!1;a.setDate(1),a.setFullYear(t.data("year")),a.setMonth(t.data("month")),a.setDate(t.data("date")),_.trigger("select.xdsoft",[a]),O.val(W.str()),I.onSelectDate&&L.isFunction(I.onSelectDate)&&I.onSelectDate.call(_,W.currentTime,_.data("input"),e),_.data("changed",!0),_.trigger("xchange.xdsoft"),_.trigger("changedatetime.xdsoft"),(1f+c?(u="bottom",a=f+c-e.top):a-=c):a+_[0].offsetHeight>f+c&&(a=e.top-_[0].offsetHeight+1),a<0&&(a=0),n+t.offsetWidth>d&&(n=d-t.offsetWidth)),o=_[0],h(o,function(e){if("relative"===I.contentWindow.getComputedStyle(e).getPropertyValue("position")&&d>=e.offsetWidth)return n-=(d-e.offsetWidth)/2,!1}),l={position:r,left:I.insideParent?t.offsetLeft:n,top:"",bottom:""},I.insideParent?l[u]=t.offsetTop+t.offsetHeight:l[u]=a,_.css(l)},_.on("open.xdsoft",function(e){var t=!0;I.onShow&&L.isFunction(I.onShow)&&(t=I.onShow.call(_,W.currentTime,_.data("input"),e)),!1!==t&&(_.show(),r(),L(I.contentWindow).off("resize.xdsoft",r).on("resize.xdsoft",r),I.closeOnWithoutClick&&L([I.ownerDocument.body,I.contentWindow]).on("touchstart mousedown.xdsoft",function e(){_.trigger("close.xdsoft"),L([I.ownerDocument.body,I.contentWindow]).off("touchstart mousedown.xdsoft",e)}))}).on("close.xdsoft",function(e){var t=!0;F.find(".xdsoft_month,.xdsoft_year").find(".xdsoft_select").hide(),I.onClose&&L.isFunction(I.onClose)&&(t=I.onClose.call(_,W.currentTime,_.data("input"),e)),!1===t||I.opened||I.inline||_.hide(),e.stopPropagation()}).on("toggle.xdsoft",function(){_.is(":visible")?_.trigger("close.xdsoft"):_.trigger("open.xdsoft")}).data("input",O),d=0,_.data("xdsoft_datetime",W),_.setOptions(I),W.setCurrentTime(f()),O.data("xdsoft_datetimepicker",_).on("open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart",function(){O.is(":disabled")||O.data("xdsoft_datetimepicker").is(":visible")&&I.closeOnInputClick||I.openOnFocus&&(clearTimeout(d),d=setTimeout(function(){O.is(":disabled")||(s=!0,W.setCurrentTime(f(),!0),I.mask&&c(I),_.trigger("open.xdsoft"))},100))}).on("keydown.xdsoft",function(e){var t,a=e.which;return-1!==[D].indexOf(a)&&I.enterLikeTab?(t=L("input:visible,textarea:visible,button:visible,a:visible"),_.trigger("close.xdsoft"),t.eq(t.index(this)+1).focus(),!1):-1!==[T].indexOf(a)?(_.trigger("close.xdsoft"),!0):void 0}).on("blur.xdsoft",function(){_.trigger("close.xdsoft")})},r=function(e){var t=e.data("xdsoft_datetimepicker");t&&(t.data("xdsoft_datetime",null),t.remove(),e.data("xdsoft_datetimepicker",null).off(".xdsoft"),L(I.contentWindow).off("resize.xdsoft"),L([I.contentWindow,I.ownerDocument.body]).off("mousedown.xdsoft touchstart"),e.unmousewheel&&e.unmousewheel())},L(I.ownerDocument).off("keydown.xdsoftctrl keyup.xdsoftctrl").off("keydown.xdsoftcmd keyup.xdsoftcmd").on("keydown.xdsoftctrl",function(e){e.keyCode===p&&(N=!0)}).on("keyup.xdsoftctrl",function(e){e.keyCode===p&&(N=!1)}).on("keydown.xdsoftcmd",function(e){91===e.keyCode&&!0}).on("keyup.xdsoftcmd",function(e){91===e.keyCode&&!1}),this.each(function(){var t,e=L(this).data("xdsoft_datetimepicker");if(e){if("string"===L.type(H))switch(H){case"show":L(this).select().focus(),e.trigger("open.xdsoft");break;case"hide":e.trigger("close.xdsoft");break;case"toggle":e.trigger("toggle.xdsoft");break;case"destroy":r(L(this));break;case"reset":this.value=this.defaultValue,this.value&&e.data("xdsoft_datetime").isValidDate(E.parseDate(this.value,I.format))||e.data("changed",!1),e.data("xdsoft_datetime").setCurrentTime(this.value);break;case"validate":e.data("input").trigger("blur.xdsoft");break;default:e[H]&&L.isFunction(e[H])&&(o=e[H](a))}else e.setOptions(H);return 0}"string"!==L.type(H)&&(!I.lazyInit||I.open||I.inline?n(L(this)):(t=L(this)).on("open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart",function e(){t.is(":disabled")||t.data("xdsoft_datetimepicker")||(clearTimeout(i),i=setTimeout(function(){t.data("xdsoft_datetimepicker")||n(t),t.off("open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart",e).trigger("open.xdsoft")},100))}))}),o},L.fn.datetimepicker.defaults=s};!function(e){"function"==typeof define&&define.amd?define(["jquery","jquery-mousewheel"],e):"object"==typeof exports?module.exports=e(require("jquery")):e(jQuery)}(datetimepickerFactory),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e:e(jQuery)}(function(c){var m,h,e=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],t="onwheel"in document||9<=document.documentMode?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],g=Array.prototype.slice;if(c.event.fixHooks)for(var a=e.length;a;)c.event.fixHooks[e[--a]]=c.event.mouseHooks;var p=c.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var e=t.length;e;)this.addEventListener(t[--e],n,!1);else this.onmousewheel=n;c.data(this,"mousewheel-line-height",p.getLineHeight(this)),c.data(this,"mousewheel-page-height",p.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var e=t.length;e;)this.removeEventListener(t[--e],n,!1);else this.onmousewheel=null;c.removeData(this,"mousewheel-line-height"),c.removeData(this,"mousewheel-page-height")},getLineHeight:function(e){var t=c(e),a=t["offsetParent"in c.fn?"offsetParent":"parent"]();return a.length||(a=c("body")),parseInt(a.css("fontSize"),10)||parseInt(t.css("fontSize"),10)||16},getPageHeight:function(e){return c(e).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};function n(e){var t,a=e||window.event,n=g.call(arguments,1),r=0,o=0,i=0,s=0,d=0;if((e=c.event.fix(a)).type="mousewheel","detail"in a&&(i=-1*a.detail),"wheelDelta"in a&&(i=a.wheelDelta),"wheelDeltaY"in a&&(i=a.wheelDeltaY),"wheelDeltaX"in a&&(o=-1*a.wheelDeltaX),"axis"in a&&a.axis===a.HORIZONTAL_AXIS&&(o=-1*i,i=0),r=0===i?o:i,"deltaY"in a&&(r=i=-1*a.deltaY),"deltaX"in a&&(o=a.deltaX,0===i&&(r=-1*o)),0!==i||0!==o){if(1===a.deltaMode){var u=c.data(this,"mousewheel-line-height");r*=u,i*=u,o*=u}else if(2===a.deltaMode){var l=c.data(this,"mousewheel-page-height");r*=l,i*=l,o*=l}if(t=Math.max(Math.abs(i),Math.abs(o)),(!h||tdiv>div{background:#f5f5f5;border-top:1px solid #ddd;color:#666;font-size:12px;text-align:center;border-collapse:collapse;cursor:pointer;border-bottom-width:0;height:25px;line-height:25px}.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div:first-child{border-top-width:0}.xdsoft_datetimepicker .xdsoft_today_button:hover,.xdsoft_datetimepicker .xdsoft_next:hover,.xdsoft_datetimepicker .xdsoft_prev:hover{opacity:1;-ms-filter:"alpha(opacity=100)"}.xdsoft_datetimepicker .xdsoft_label{display:inline;position:relative;z-index:9999;margin:0;padding:5px 3px;font-size:14px;line-height:20px;font-weight:bold;background-color:#fff;float:left;width:182px;text-align:center;cursor:pointer}.xdsoft_datetimepicker .xdsoft_label:hover>span{text-decoration:underline}.xdsoft_datetimepicker .xdsoft_label:hover i{opacity:1.0}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select{border:1px solid #ccc;position:absolute;right:0;top:30px;z-index:101;display:none;background:#fff;max-height:160px;overflow-y:hidden}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select.xdsoft_monthselect{right:-7px}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select.xdsoft_yearselect{right:2px}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select>div>.xdsoft_option:hover{color:#fff;background:#ff8000}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select>div>.xdsoft_option{padding:2px 10px 2px 5px;text-decoration:none !important}.xdsoft_datetimepicker .xdsoft_label>.xdsoft_select>div>.xdsoft_option.xdsoft_current{background:#3af;box-shadow:#178fe5 0 1px 3px 0 inset;color:#fff;font-weight:700}.xdsoft_datetimepicker .xdsoft_month{width:100px;text-align:right}.xdsoft_datetimepicker .xdsoft_calendar{clear:both}.xdsoft_datetimepicker .xdsoft_year{width:48px;margin-left:5px}.xdsoft_datetimepicker .xdsoft_calendar table{border-collapse:collapse;width:100%}.xdsoft_datetimepicker .xdsoft_calendar td>div{padding-right:5px}.xdsoft_datetimepicker .xdsoft_calendar th{height:25px}.xdsoft_datetimepicker .xdsoft_calendar td,.xdsoft_datetimepicker .xdsoft_calendar th{width:14.2857142%;background:#f5f5f5;border:1px solid #ddd;color:#666;font-size:12px;text-align:right;vertical-align:middle;padding:0;border-collapse:collapse;cursor:pointer;height:25px}.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar td,.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar th{width:12.5%}.xdsoft_datetimepicker .xdsoft_calendar th{background:#f1f1f1}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_today{color:#3af}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_default{background:#ffe9d2;box-shadow:#ffb871 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_mint{background:#c1ffc9;box-shadow:#00dd1c 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_default,.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current{background:#3af;box-shadow:#178fe5 0 1px 3px 0 inset;color:#fff;font-weight:700}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month,.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled,.xdsoft_datetimepicker .xdsoft_time_box>div>div.xdsoft_disabled{opacity:.5;-ms-filter:"alpha(opacity=50)";cursor:default}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month.xdsoft_disabled{opacity:.2;-ms-filter:"alpha(opacity=20)"}.xdsoft_datetimepicker .xdsoft_calendar td:hover,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div:hover{color:#fff !important;background:#ff8000 !important;box-shadow:none !important}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current.xdsoft_disabled:hover,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current.xdsoft_disabled:hover{background:#3af !important;box-shadow:#178fe5 0 1px 3px 0 inset !important;color:#fff !important}.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled:hover,.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_disabled:hover{color:inherit !important;background:inherit !important;box-shadow:inherit !important}.xdsoft_datetimepicker .xdsoft_calendar th{font-weight:700;text-align:center;color:#999;cursor:default}.xdsoft_datetimepicker .xdsoft_copyright{color:#ccc !important;font-size:10px;clear:both;float:none;margin-left:8px}.xdsoft_datetimepicker .xdsoft_copyright a{color:#eee !important}.xdsoft_datetimepicker .xdsoft_copyright a:hover{color:#aaa !important}.xdsoft_time_box{position:relative;border:1px solid #ccc}.xdsoft_scrollbar>.xdsoft_scroller{background:#ccc !important;height:20px;border-radius:3px}.xdsoft_scrollbar{position:absolute;width:7px;right:0;top:0;bottom:0;cursor:pointer}.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_scrollbar{left:0;right:auto}.xdsoft_scroller_box{position:relative}.xdsoft_datetimepicker.xdsoft_dark{box-shadow:0 5px 15px -5px rgba(255,255,255,0.506);background:#000;border-bottom:1px solid #444;border-left:1px solid #333;border-right:1px solid #333;border-top:1px solid #333;color:#ccc}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box{border-bottom:1px solid #222}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box>div>div{background:#0a0a0a;border-top:1px solid #222;color:#999}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label{background-color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label>.xdsoft_select{border:1px solid #333;background:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label>.xdsoft_select>div>.xdsoft_option:hover{color:#000;background:#007fff}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label>.xdsoft_select>div>.xdsoft_option.xdsoft_current{background:#c50;box-shadow:#b03e00 0 1px 3px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label i,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_prev,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_next,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_today_button{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUExQUUzOTA0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUExQUUzOTE0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQTFBRTM4RTQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQTFBRTM4RjQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp0VxGEAAAIASURBVHja7JrNSgMxEMebtgh+3MSLr1T1Xn2CHoSKB08+QmR8Bx9A8e7RixdB9CKCoNdexIugxFlJa7rNZneTbLIpM/CnNLsdMvNjM8l0mRCiQ9Ye61IKCAgZAUnH+mU3MMZaHYChBnJUDzWOFZdVfc5+ZFLbrWDeXPwbxIqrLLfaeS0hEBVGIRQCEiZoHQwtlGSByCCdYBl8g8egTTAWoKQMRBRBcZxYlhzhKegqMOageErsCHVkk3hXIFooDgHB1KkHIHVgzKB4ADJQ/A1jAFmAYhkQqA5TOBtocrKrgXwQA8gcFIuAIO8sQSA7hidvPwaQGZSaAYHOUWJABhWWw2EMIH9QagQERU4SArJXo0ZZL18uvaxejXt/Em8xjVBXmvFr1KVm/AJ10tRe2XnraNqaJvKE3KHuUbfK1E+VHB0q40/y3sdQSxY4FHWeKJCunP8UyDdqJZenT3ntVV5jIYCAh20vT7ioP8tpf6E2lfEMwERe+whV1MHjwZB7PBiCxcGQWwKZKD62lfGNnP/1poFAA60T7rF1UgcKd2id3KDeUS+oLWV8DfWAepOfq00CgQabi9zjcgJVYVD7PVzQUAUGAQkbNJTBICDhgwYTjDYD6XeW08ZKh+A4pYkzenOxXUbvZcWz7E8ykRMnIHGX1XPl+1m2vPYpL+2qdb8CDAARlKFEz/ZVkAAAAABJRU5ErkJggg==)}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th{background:#0a0a0a;border:1px solid #222;color:#999}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th{background:#0e0e0e}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_today{color:#c50}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_default{background:#ffe9d2;box-shadow:#ffb871 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_mint{background:#c1ffc9;box-shadow:#00dd1c 0 1px 4px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_default,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_current,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current{background:#c50;box-shadow:#b03e00 0 1px 3px 0 inset;color:#000}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td:hover,.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box>div>div:hover{color:#000 !important;background:#007fff !important}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th{color:#666}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright{color:#333 !important}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a{color:#111 !important}.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a:hover{color:#555 !important}.xdsoft_dark .xdsoft_time_box{border:1px solid #333}.xdsoft_dark .xdsoft_scrollbar>.xdsoft_scroller{background:#333 !important}.xdsoft_datetimepicker .xdsoft_save_selected{display:block;border:1px solid #ddd !important;margin-top:5px;width:100%;color:#454551;font-size:13px}.xdsoft_datetimepicker .blue-gradient-button{font-family:"museo-sans","Book Antiqua",sans-serif;font-size:12px;font-weight:300;color:#82878c;height:28px;position:relative;padding:4px 17px 4px 33px;border:1px solid #d7d8da;background:-moz-linear-gradient(top,#fff 0,#f4f8fa 73%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(73%,#f4f8fa));background:-webkit-linear-gradient(top,#fff 0,#f4f8fa 73%);background:-o-linear-gradient(top,#fff 0,#f4f8fa 73%);background:-ms-linear-gradient(top,#fff 0,#f4f8fa 73%);background:linear-gradient(to bottom,#fff 0,#f4f8fa 73%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff',endColorstr='#f4f8fa',GradientType=0)}.xdsoft_datetimepicker .blue-gradient-button:hover,.xdsoft_datetimepicker .blue-gradient-button:focus,.xdsoft_datetimepicker .blue-gradient-button:hover span,.xdsoft_datetimepicker .blue-gradient-button:focus span{color:#454551;background:-moz-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#f4f8fa),color-stop(73%,#FFF));background:-webkit-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:-o-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:-ms-linear-gradient(top,#f4f8fa 0,#FFF 73%);background:linear-gradient(to bottom,#f4f8fa 0,#FFF 73%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f8fa',endColorstr='#FFF',GradientType=0)} From cbd6f2c00d6c45c2b7e3848c5fb1dd64c77f1a57 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 17 Sep 2022 20:38:54 +0800 Subject: [PATCH 05/59] torrent detail show tags --- app/Repositories/TagRepository.php | 37 ++++++++++++++++++++---------- include/functions.php | 7 ++---- lang/chs/lang_details.php | 1 + lang/cht/lang_details.php | 1 + lang/en/lang_details.php | 1 + public/details.php | 7 ++++++ public/torrents.php | 7 +++--- 7 files changed, 40 insertions(+), 21 deletions(-) diff --git a/app/Repositories/TagRepository.php b/app/Repositories/TagRepository.php index 13a84e56..c871a526 100644 --- a/app/Repositories/TagRepository.php +++ b/app/Repositories/TagRepository.php @@ -11,6 +11,8 @@ class TagRepository extends BaseRepository { private static $orderByFieldIdString; + private static $allTags; + public function getList(array $params) { $query = $this->createBasicQuery(); @@ -61,20 +63,25 @@ class TagRepository extends BaseRepository return $html; } - public function renderSpan(Collection $tagKeyById, array $renderIdArr = [], $withFilterLink = false): string + public function renderSpan(array $renderIdArr = [], $withFilterLink = false): string { + if (empty(self::$allTags)) { + self::$allTags = self::createBasicQuery()->get(); + } $html = ''; - foreach ($renderIdArr as $tagId) { - $value = $tagKeyById->get($tagId); - if ($value) { - $item = sprintf( - "%s", - $value->color, $value->font_color, $value->border_radius, $value->font_size, $value->margin, $value->padding, $value->name - ); - if ($withFilterLink) { - $html .= sprintf('%s', $tagId, $item); - } else { - $html .= $item; + foreach (self::$allTags as $value) { + if (in_array($value->id, $renderIdArr) || (isset($renderIdArr[0]) && $renderIdArr[0] == '*')) { + $tagId = $value->id; + if ($value) { + $item = sprintf( + "%s", + $value->color, $value->font_color, $value->border_radius, $value->font_size, $value->margin, $value->padding, $value->name + ); + if ($withFilterLink) { + $html .= sprintf('%s', $tagId, $item); + } else { + $html .= $item; + } } } } @@ -141,5 +148,11 @@ class TagRepository extends BaseRepository return self::$orderByFieldIdString; } + public function listAll() + { + self::$allTags = self::createBasicQuery()->get(); + return self::$allTags; + } + } diff --git a/include/functions.php b/include/functions.php index e60b3856..ec4fbf02 100644 --- a/include/functions.php +++ b/include/functions.php @@ -3320,10 +3320,7 @@ function torrenttable($rows, $variant = "torrent", $searchBoxId = 0) { $torrentSeedingLeechingStatus = $torrent->listLeechingSeedingStatus($CURUSER['id'], $torrentIdArr); $tagRep = new \App\Repositories\TagRepository(); - $tagCollection = $tagRep->createBasicQuery()->get(); - $tagIdStr = $tagCollection->implode('id', ',') ?: '0'; - $torrentTagCollection = \App\Models\TorrentTag::query()->whereIn('torrent_id', $torrentIdArr)->orderByRaw("field(tag_id,$tagIdStr)")->get(); - $tagKeyById = $tagCollection->keyBy('id'); + $torrentTagCollection = \App\Models\TorrentTag::query()->whereIn('torrent_id', $torrentIdArr)->get(); $torrentTagResult = $torrentTagCollection->groupBy('torrent_id'); $showCover = false; $showSeedBoxIcon = get_setting('seed_box.enabled') == 'yes'; @@ -3573,7 +3570,7 @@ foreach ($rows as $row) */ $tagOwns = $torrentTagResult->get($id); if ($tagOwns) { - $tags = $tagRep->renderSpan($tagKeyById, $tagOwns->pluck('tag_id')->toArray()); + $tags = $tagRep->renderSpan($tagOwns->pluck('tag_id')->toArray()); } else { $tags = ''; } diff --git a/lang/chs/lang_details.php b/lang/chs/lang_details.php index f0f0b672..e9d12c43 100644 --- a/lang/chs/lang_details.php +++ b/lang/chs/lang_details.php @@ -239,6 +239,7 @@ $lang_details = array 'claim_label' => '认领种子', 'claim_confirm' => '确定要认领此种子吗?', 'action_approval' => '审核', + 'row_tags' => '标签', ); ?> diff --git a/lang/cht/lang_details.php b/lang/cht/lang_details.php index f963817f..30a723fe 100644 --- a/lang/cht/lang_details.php +++ b/lang/cht/lang_details.php @@ -238,6 +238,7 @@ $lang_details = array 'claim_label' => '認領種子', 'claim_confirm' => '確定要認領此種子嗎?', 'action_approval' => '審核', + 'row_tags' => '標簽', ); ?> diff --git a/lang/en/lang_details.php b/lang/en/lang_details.php index 53621957..7a193e4e 100644 --- a/lang/en/lang_details.php +++ b/lang/en/lang_details.php @@ -238,6 +238,7 @@ $lang_details = array 'claim_label' => 'Claim torrent', 'claim_confirm' => 'Are you sure to claim this torrent?', 'action_approval' => 'Approval', + 'row_tags' => 'Tags', ); ?> diff --git a/public/details.php b/public/details.php index d3914460..e1ca5a2a 100644 --- a/public/details.php +++ b/public/details.php @@ -126,6 +126,13 @@ if (!$row) { if ($smalldescription_main == 'yes') tr($lang_details['row_small_description'],htmlspecialchars(trim($row["small_descr"])),true); + //tag + $torrentTags = \App\Models\TorrentTag::query()->where('torrent_id', $row['id'])->get(); + if ($torrentTags->isNotEmpty()) { + $tagRep = new \App\Repositories\TagRepository(); + tr($lang_details['row_tags'], $tagRep->renderSpan($torrentTags->pluck('tag_id')->toArray()),true); + } + $size_info = "".$lang_details['text_size']."" . mksize($row["size"]); $type_info = "   ".$lang_details['row_type'].": ".$row["cat_name"]; $source_info = $medium_info = $codec_info = $audiocodec_info = $standard_info = $processing_info = $team_info = ''; diff --git a/public/torrents.php b/public/torrents.php index ace249b1..d83b43fe 100644 --- a/public/torrents.php +++ b/public/torrents.php @@ -10,8 +10,7 @@ parked(); * tags */ $tagRep = new \App\Repositories\TagRepository(); -$tagKeyById = $tagRep->createBasicQuery()->get()->keyBy('id'); -$renderKeyArr = $tagKeyById->keys()->toArray(); +$allTags = $tagRep->listAll(); $elasticsearchEnabled = nexus_env('ELASTICSEARCH_ENABLED'); //check searchbox @@ -1143,8 +1142,8 @@ if (!$Cache->get_page()){ } echo $Cache->next_row(); -if ($tagKeyById->isNotEmpty()) { - echo '' . $tagRep->renderSpan($tagKeyById, $renderKeyArr, true) . ''; +if ($allTags->isNotEmpty()) { + echo '' . $tagRep->renderSpan(['*'], true) . ''; } ?> From 2dd4b6a0bbfa7f6f6d1517c53c10c49eecf02298 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 17 Sep 2022 21:39:18 +0800 Subject: [PATCH 06/59] default exchange download bonus --- nexus/Install/settings.default.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index eeb0c938..fc9d2335 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -233,6 +233,9 @@ return array ( 'cancel_hr' => BonusLogs::DEFAULT_BONUS_CANCEL_ONE_HIT_AND_RUN, 'attendance_card' => BonusLogs::DEFAULT_BONUS_BUY_ATTENDANCE_CARD, 'harem_addition' => 0, + 'hundredgbupload' => 10000, + 'tengbdownload' => 1000, + 'hundredgbdownload' => 8000, ), 'account' => array ( From 29fc44e5551b73d40297c3d0ddbcf0183aad266e Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 17 Sep 2022 23:34:58 +0800 Subject: [PATCH 07/59] cancel gift bonus limit --- public/mybonus.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/public/mybonus.php b/public/mybonus.php index cbc9032a..64f50363 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -96,7 +96,7 @@ function bonusarray($option = 0){ //Bonus Gift $bonus = array(); - $bonus['points'] = 25; + $bonus['points'] = 100; $bonus['art'] = 'gift_1'; $bonus['menge'] = 0; $bonus['name'] = $lang_mybonus['text_bonus_gift']; @@ -339,8 +339,8 @@ for ($i=0; $i < count($allBonus); $i++) print("

".$bonusarray['name']."

".$bonusarray['description']."

".$lang_mybonus['text_enter_titile'].$otheroption_title.$lang_mybonus['text_click_exchange']."".number_format($bonusarray['points']).""); } elseif ($bonusarray['art'] == 'gift_1'){ //for Give A Karma Gift - $otheroption = "
".$lang_mybonus['text_username']."".$lang_mybonus['text_to_be_given']."".$lang_mybonus['text_karma_points']."
".$lang_mybonus['text_message']."
"; - print("

".$bonusarray['name']."

".$bonusarray['description']."

".$lang_mybonus['text_enter_receiver_name']."
$otheroption".$lang_mybonus['text_min']."25
".$lang_mybonus['text_max']."10,000"); + $otheroption = "
".$lang_mybonus['text_username']."".$lang_mybonus['text_to_be_given']."".$lang_mybonus['text_karma_points']."
".$lang_mybonus['text_message']."
"; + print("

".$bonusarray['name']."

".$bonusarray['description']."

".$lang_mybonus['text_enter_receiver_name']."
$otheroption".$lang_mybonus['text_min']."100"); } elseif ($bonusarray['art'] == 'gift_2'){ //charity giving $otheroption = "
".$lang_mybonus['text_ratio_below']."".$lang_mybonus['text_and_downloaded_above']." 10 GB".$lang_mybonus['text_to_be_given']."".$lang_mybonus['text_karma_points']."
"; @@ -663,10 +663,15 @@ if ($action == "exchange") { $usernamegift = sqlesc(trim($_POST["username"])); $res = sql_query("SELECT id, bonuscomment FROM users WHERE username=" . $usernamegift); $arr = mysql_fetch_assoc($res); + if (empty($arr)) { + stdmsg($lang_mybonus['text_error'], $lang_mybonus['text_receiver_not_exists'], 0); + stdfoot(); + die; + } $useridgift = $arr['id']; $userseedbonus = $arr['seedbonus']; $receiverbonuscomment = $arr['bonuscomment']; - if ($points < 25 || $points > 10000) { + if (!is_numeric($points) || $points < $bonusarray['points']) { //write_log("User " . $CURUSER["username"] . "," . $CURUSER["ip"] . " is hacking bonus system",'mod'); stdmsg($lang_mybonus['text_error'], $lang_mybonus['bonus_amount_not_allowed']); stdfoot(); @@ -689,11 +694,6 @@ if ($action == "exchange") { stdfoot(); die; } - if (!$useridgift){ - stdmsg($lang_mybonus['text_error'], $lang_mybonus['text_receiver_not_exists'], 0); - stdfoot(); - die; - } // sql_query("UPDATE users SET seedbonus = seedbonus - $points, bonuscomment = ".sqlesc($bonuscomment)." WHERE id = ".sqlesc($userid)) or sqlerr(__FILE__, __LINE__); $bonusRep->consumeUserBonus($CURUSER['id'], $points, \App\Models\BonusLogs::BUSINESS_TYPE_GIFT_TO_SOMEONE, $points2 . " Points as gift to ".htmlspecialchars(trim($_POST["username"]))); From 464880f1fb02069af78caab8e0d5cd133d333d4f Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 18 Sep 2022 03:33:13 +0800 Subject: [PATCH 08/59] [admin] set torrent pos_state_until --- .../Resources/Torrent/TorrentResource.php | 6 ++++- app/Models/Torrent.php | 22 ++++++++++++++----- app/Repositories/TorrentRepository.php | 15 +++++++++++-- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/app/Filament/Resources/Torrent/TorrentResource.php b/app/Filament/Resources/Torrent/TorrentResource.php index bc046f67..49f14881 100644 --- a/app/Filament/Resources/Torrent/TorrentResource.php +++ b/app/Filament/Resources/Torrent/TorrentResource.php @@ -155,13 +155,17 @@ class TorrentResource extends Resource ->label(__('label.torrent.pos_state')) ->options(Torrent::listPosStates(true)) ->required() + , + Forms\Components\DateTimePicker::make('pos_state_until') + ->label(__('label.deadline')) + , ]) ->icon('heroicon-o-arrow-circle-up') ->action(function (Collection $records, array $data) { $idArr = $records->pluck('id')->toArray(); try { $torrentRep = new TorrentRepository(); - $torrentRep->setPosState($idArr, $data['pos_state']); + $torrentRep->setPosState($idArr, $data['pos_state'], $data['pos_state_until']); } catch (\Exception $exception) { do_log($exception->getMessage() . $exception->getTraceAsString(), 'error'); Filament::notify('danger', class_basename($exception)); diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index cce44462..49726ed1 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Repositories\TagRepository; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Casts\Attribute; use JeroenG\Explorer\Application\Explored; use Laravel\Scout\Searchable; @@ -15,7 +16,7 @@ class Torrent extends NexusModel 'size', 'added', 'type', 'numfiles', 'owner', 'nfo', 'sp_state', 'promotion_time_type', 'promotion_until', 'anonymous', 'url', 'pos_state', 'cache_stamp', 'picktype', 'picktime', 'last_reseed', 'pt_gen', 'technical_info', 'leechers', 'seeders', 'cover', 'last_action', - 'times_completed', 'approval_status', 'banned', 'visible', + 'times_completed', 'approval_status', 'banned', 'visible', 'pos_state_until', ]; private static $globalPromotionState; @@ -30,11 +31,13 @@ class Torrent extends NexusModel 'added' => 'datetime', 'pt_gen' => 'array', 'promotion_until' => 'datetime', + 'pos_state_until' => 'datetime', ]; public static $commentFields = [ 'id', 'name', 'added', 'visible', 'banned', 'owner', 'sp_state', 'pos_state', 'hr', 'picktype', 'picktime', - 'last_action', 'leechers', 'seeders', 'times_completed', 'views', 'size', 'cover', 'anonymous', 'approval_status' + 'last_action', 'leechers', 'seeders', 'times_completed', 'views', 'size', 'cover', 'anonymous', 'approval_status', + 'pos_state_until' ]; public static $basicRelations = [ @@ -193,11 +196,18 @@ class Torrent extends NexusModel return $spState; } - protected function posStateText(): Attribute + protected function getPosStateTextAttribute() { - return new Attribute( - get: fn($value, $attributes) => nexus_trans('torrent.pos_state_' . $attributes['pos_state']) - ); + $text = nexus_trans('torrent.pos_state_' . $this->pos_state); + if ($this->pos_state != Torrent::POS_STATE_STICKY_NONE) { + if ($this->pos_state_until) { + $append = format_datetime($this->pos_state_until); + } else { + $append = nexus_trans('label.permanent'); + } + $text .= "($append)"; + } + return $text; } protected function approvalStatusText(): Attribute diff --git a/app/Repositories/TorrentRepository.php b/app/Repositories/TorrentRepository.php index 0f10aa2b..fe91ad6d 100644 --- a/app/Repositories/TorrentRepository.php +++ b/app/Repositories/TorrentRepository.php @@ -598,11 +598,22 @@ class TorrentRepository extends BaseRepository } - public function setPosState($id, $posState): int + public function setPosState($id, $posState, $posStateUntil = null): int { user_can('torrentsticky', true); + if ($posState == Torrent::POS_STATE_STICKY_NONE) { + $posStateUntil = null; + } + if ($posStateUntil && Carbon::parse($posStateUntil)->lte(now())) { + $posState = Torrent::POS_STATE_STICKY_NONE; + $posStateUntil = null; + } + $update = [ + 'pos_state' => $posState, + 'pos_state_until' => $posStateUntil, + ]; $idArr = Arr::wrap($id); - return Torrent::query()->whereIn('id', $idArr)->update(['pos_state' => $posState]); + return Torrent::query()->whereIn('id', $idArr)->update($update); } public function buildUploadFieldInput($name, $value, $noteText, $btnText): string From 47493b1a2651e2d5c148bd58a3954eeac971aa2e Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 18 Sep 2022 17:20:51 +0800 Subject: [PATCH 09/59] backup add transfer option --- app/Console/Commands/BackupDatabase.php | 6 ++- app/Console/Commands/BackupWeb.php | 7 ++-- app/Console/Commands/Test.php | 5 +-- app/Repositories/ToolRepository.php | 52 ++++++++++++++++--------- include/constants.php | 2 +- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/app/Console/Commands/BackupDatabase.php b/app/Console/Commands/BackupDatabase.php index 9b8825fa..3c3bb059 100644 --- a/app/Console/Commands/BackupDatabase.php +++ b/app/Console/Commands/BackupDatabase.php @@ -12,7 +12,7 @@ class BackupDatabase extends Command * * @var string */ - protected $signature = 'backup:database'; + protected $signature = 'backup:database {--transfer=}'; /** * The console command description. @@ -39,7 +39,9 @@ class BackupDatabase extends Command public function handle() { $rep = new ToolRepository(); - $result = $rep->backupDatabase(); + $transfer = $this->option('transfer'); + $this->info("transfer: $transfer"); + $result = $rep->backupDatabase($transfer); $log = sprintf('[%s], %s, result: %s', nexus()->getRequestId(), __METHOD__, var_export($result, true)); $this->info($log); do_log($log); diff --git a/app/Console/Commands/BackupWeb.php b/app/Console/Commands/BackupWeb.php index fd09dbeb..097f469f 100644 --- a/app/Console/Commands/BackupWeb.php +++ b/app/Console/Commands/BackupWeb.php @@ -12,7 +12,7 @@ class BackupWeb extends Command * * @var string */ - protected $signature = 'backup:web {--method=}'; + protected $signature = 'backup:web {--method=} {--transfer=}'; /** * The console command description. @@ -39,9 +39,10 @@ class BackupWeb extends Command public function handle() { $method = $this->option('method'); - $this->info("method: $method"); + $transfer = $this->option('transfer'); + $this->info("method: $method, transfer: $transfer"); $rep = new ToolRepository(); - $result = $rep->backupWeb($method); + $result = $rep->backupWeb($method, $transfer); $log = sprintf('[%s], %s, result: %s', nexus()->getRequestId(), __METHOD__, var_export($result, true)); $this->info($log); do_log($log); diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 52e44fa3..b84d6d05 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -88,9 +88,8 @@ class Test extends Command */ public function handle() { - $rep = new PluginRepository(); -// $rep->installCronjob(); - $r = $rep->getInstalledVersion('xiaomlove/nexusphp-post-like'); + $rep = new ToolRepository(); + $r = $rep->transfer('C:\Users\CHENYU~1\AppData\Local\Temp/nexusphp.v1.5.beta5.20120707.web.20220918.053953.zip', 0); dd($r); } diff --git a/app/Repositories/ToolRepository.php b/app/Repositories/ToolRepository.php index eaf51a18..a63182ea 100644 --- a/app/Repositories/ToolRepository.php +++ b/app/Repositories/ToolRepository.php @@ -24,7 +24,7 @@ class ToolRepository extends BaseRepository { const BACKUP_EXCLUDES = ['vendor', 'node_modules', '.git', '.idea', '.settings', '.DS_Store', '.github']; - public function backupWeb($method = null): array + public function backupWeb($method = null, $transfer = false): array { $webRoot = base_path(); $dirName = basename($webRoot); @@ -76,10 +76,13 @@ class ToolRepository extends BaseRepository $result_code = 0; do_log("No tar command, use zip."); } - return compact('result_code', 'filename'); + if (!$transfer) { + return compact('result_code', 'filename'); + } + return $this->transfer($filename, $result_code); } - public function backupDatabase(): array + public function backupDatabase($transfer = false): array { $connectionName = config('database.default'); $config = config("database.connections.$connectionName"); @@ -93,10 +96,13 @@ class ToolRepository extends BaseRepository "command: %s, output: %s, result_code: %s, result: %s, filename: %s", $command, json_encode($output), $result_code, $result, $filename )); - return compact('result_code', 'filename'); + if (!$transfer) { + return compact('result_code', 'filename'); + } + return $this->transfer($filename, $result_code); } - public function backupAll($method = null): array + public function backupAll($method = null, $transfer = false): array { $backupWeb = $this->backupWeb($method); if ($backupWeb['result_code'] != 0) { @@ -134,8 +140,10 @@ class ToolRepository extends BaseRepository $result_code = 0; do_log("No tar command, use zip."); } - return compact('result_code', 'filename'); - + if (!$transfer) { + return compact('result_code', 'filename'); + } + return $this->transfer($filename, $result_code); } /** @@ -178,27 +186,33 @@ class ToolRepository extends BaseRepository } $backupResult = $this->backupAll(); do_log("Backup all result: " . json_encode($backupResult)); - if ($backupResult['result_code'] != 0) { - throw new \RuntimeException("Backup all fail."); - } - $filename = $backupResult['filename']; + $transferResult = $this->transfer($backupResult['filename'], $backupResult['result_code'], $setting); + $backupResult['transfer_result'] = $transferResult; + do_log("[BACKUP_ALL_DONE]: " . json_encode($backupResult)); + return $backupResult; + } + public function transfer($filename, $result_code, $setting = null): array + { + if ($result_code != 0) { + throw new \RuntimeException("file: $filename backup fail!"); + } + $result = compact('filename', 'result_code'); + if (empty($setting)) { + $setting = Setting::get('backup'); + } $saveResult = $this->saveToGoogleDrive($setting, $filename); do_log("[BACKUP_GOOGLE_DRIVE]: $saveResult"); - $backupResult['google_drive'] = $saveResult; + $result['google_drive'] = $saveResult; $saveResult = $this->saveToFtp($setting, $filename); do_log("[BACKUP_FTP]: $saveResult"); - $backupResult['ftp'] = $saveResult; + $result['ftp'] = $saveResult; $saveResult = $this->saveToSftp($setting, $filename); do_log("[BACKUP_SFTP]: $saveResult"); - $backupResult['sftp'] = $saveResult; - - do_log("[BACKUP_ALL_DONE]: " . json_encode($backupResult)); - - return $backupResult; - + $result['sftp'] = $saveResult; + return $result; } private function saveToGoogleDrive(array $setting, $filename): bool|string diff --git a/include/constants.php b/include/constants.php index 42baac68..77346b6d 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ Date: Sun, 18 Sep 2022 17:40:07 +0800 Subject: [PATCH 10/59] fix admin setting can not clear value --- .../Resources/System/SettingResource/Pages/EditSetting.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php index c65d8386..92bda9d3 100644 --- a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php +++ b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php @@ -58,9 +58,6 @@ class EditSetting extends Page implements Forms\Contracts\HasForms $data = []; foreach ($formData as $prefix => $parts) { foreach ($parts as $name => $value) { - if (is_null($value)) { - continue; - } if (in_array($name, $notAutoloadNames)) { $autoload = 'no'; } else { From b305ce7380733e0a3cdddbb8ef3deeb59910d6e4 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 19 Sep 2022 16:27:04 +0800 Subject: [PATCH 11/59] custom fields add priority + display --- app/Models/SearchBox.php | 17 +++ app/Models/TorrentCustomField.php | 15 +++ app/Models/TorrentCustomFieldValue.php | 15 +++ app/Repositories/BaseRepository.php | 5 +- ...isplay_to_torrents_custom_fields_table.php | 33 ++++++ include/constants.php | 2 +- lang/chs/lang_fields.php | 3 +- lang/cht/lang_fields.php | 3 +- lang/en/lang_fields.php | 3 +- nexus/Field/Field.php | 103 +++++++++++++----- public/details.php | 2 +- public/edit.php | 32 +++++- public/fields.php | 1 + public/takeedit.php | 17 +-- public/takeupload.php | 17 +-- public/upload.php | 25 ++++- resources/lang/en/label.php | 1 + resources/lang/zh_CN/label.php | 1 + resources/lang/zh_CN/nexus.php | 1 + resources/lang/zh_TW/label.php | 1 + 20 files changed, 225 insertions(+), 72 deletions(-) create mode 100644 app/Models/TorrentCustomField.php create mode 100644 app/Models/TorrentCustomFieldValue.php create mode 100644 database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php diff --git a/app/Models/SearchBox.php b/app/Models/SearchBox.php index 57aa575e..5a5ddff7 100644 --- a/app/Models/SearchBox.php +++ b/app/Models/SearchBox.php @@ -2,6 +2,8 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; + class SearchBox extends NexusModel { protected $table = 'searchbox'; @@ -33,6 +35,21 @@ class SearchBox extends NexusModel return $result; } + public function getCustomFieldsAttribute($value): array + { + if (!is_array($value)) { + return explode(',', $value); + } + } + + public function setCustomFieldsAttribute($value) + { + if (is_array($value)) { + $this->attributes['custom_fields'] = implode(',', $value); + } + } + + public function categories(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(Category::class, 'mode'); diff --git a/app/Models/TorrentCustomField.php b/app/Models/TorrentCustomField.php new file mode 100644 index 00000000..98068da2 --- /dev/null +++ b/app/Models/TorrentCustomField.php @@ -0,0 +1,15 @@ +privacy == "strong" || ($torrent && $torrent->anonymous == 'yes' && $user->id == $torrent->owner)) { //用户强私密,或者种子作者匿名而当前项作者刚好为种子作者 + $anonymousText = nexus_trans('label.anonymous'); if($authenticator->class >= $canViewAnonymousClass || $user->id == $authenticator->id) { //但当前用户权限可以查看匿名者,或当前用户查看自己的数据,显示个匿名,后边加真实用户名 - return sprintf('匿名(%s)', $username); + return sprintf('%s(%s)', $anonymousText, $username); } else { - return '匿名'; + return $anonymousText; } } else { return $username; diff --git a/database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php b/database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php new file mode 100644 index 00000000..315d4abe --- /dev/null +++ b/database/migrations/2022_09_19_043749_add_display_to_torrents_custom_fields_table.php @@ -0,0 +1,33 @@ +text('display')->nullable(true)->after('help'); + $table->integer('priority')->default(0)->after('display'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('torrents_custom_fields', function (Blueprint $table) { + $table->dropColumn('display', 'priority'); + }); + } +}; diff --git a/include/constants.php b/include/constants.php index 77346b6d..b83eced9 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ '横向多选', 'field_type_select' => '下拉单选', 'field_type_image' => '图片', + 'col_display' => '自定义展示', -]; \ No newline at end of file +]; diff --git a/lang/cht/lang_fields.php b/lang/cht/lang_fields.php index 8e3eea26..096544b9 100644 --- a/lang/cht/lang_fields.php +++ b/lang/cht/lang_fields.php @@ -25,5 +25,6 @@ $lang_fields = [ 'field_type_radio' => '橫向單選', 'field_type_checkbox' => '橫向多選', 'field_type_select' => '下拉單選', + 'col_display' => '自定義展示', -]; \ No newline at end of file +]; diff --git a/lang/en/lang_fields.php b/lang/en/lang_fields.php index d3bddc60..f0829af1 100644 --- a/lang/en/lang_fields.php +++ b/lang/en/lang_fields.php @@ -26,5 +26,6 @@ $lang_fields = [ 'field_type_checkbox' => 'Horizontal multiple select', 'field_type_select' => 'Vertical single select', 'field_type_image' => 'Image', + 'col_display' => 'Custom display', -]; \ No newline at end of file +]; diff --git a/nexus/Field/Field.php b/nexus/Field/Field.php index a467dc3b..8ca7cc18 100644 --- a/nexus/Field/Field.php +++ b/nexus/Field/Field.php @@ -2,6 +2,10 @@ namespace Nexus\Field; +use App\Models\SearchBox; +use App\Models\TorrentCustomField; +use App\Models\TorrentCustomFieldValue; +use Elasticsearch\Endpoints\Search; use Nexus\Database\NexusDB; class Field @@ -86,7 +90,7 @@ class Field function buildFieldForm(array $row = []) { - global $lang_fields, $lang_functions; + global $lang_fields, $lang_functions, $lang_catmanage; $trName = tr($lang_fields['col_name'] . '*', '  ' . $lang_fields['col_name_help'], 1, '', true); $trLabel = tr($lang_fields['col_label'] . '*', '', 1, '', true); $trType = tr($lang_fields['col_type'] . '*', $this->radio('type', $this->getTypeRadioOptions(), $row['type'] ?? null), 1, '', true); @@ -94,6 +98,9 @@ class Field $trHelp = tr($lang_fields['col_help'], '', 1, '', true); $trOptions = tr($lang_fields['col_options'], '
' . $lang_fields['col_options_help'], 1, '', true); $trIsSingleRow = tr($lang_fields['col_is_single_row'] . '*', $this->radio('is_single_row', ['0' => $lang_functions['text_no'], '1' => $lang_functions['text_yes']], $row['is_single_row'] ?? null), 1, '', true); + $trPriority = tr(nexus_trans('label.priority') . '*', '', 1, '', true); + $trDisplay = tr($lang_fields['col_display'], '
' . $lang_catmanage['row_custom_field_display_help'], 1, '', true); + $id = $row['id'] ?? 0; $form = << @@ -109,6 +116,8 @@ class Field {$trHelp} {$trOptions} {$trIsSingleRow} + {$trPriority} + {$trDisplay}
@@ -126,7 +135,7 @@ HTML; $perPage = 10; $total = get_row_count('torrents_custom_fields'); list($paginationTop, $paginationBottom, $limit) = pager($perPage, $total, "?"); - $sql = "select * from torrents_custom_fields order by id asc $limit"; + $sql = "select * from torrents_custom_fields order by priority desc $limit"; $res = sql_query($sql); $header = [ 'id' => $lang_fields['col_id'], @@ -135,6 +144,7 @@ HTML; 'type_text' => $lang_fields['col_type'], 'required_text' => $lang_fields['col_required'], 'is_single_row_text' => $lang_fields['col_is_single_row'], + 'priority' => nexus_trans('label.priority'), 'action' => $lang_fields['col_action'], ]; $rows = []; @@ -203,6 +213,8 @@ HEAD; $attributes['help'] = $data['help'] ?? ''; $attributes['options'] = trim($data['options'] ?? ''); + $attributes['display'] = trim($data['display'] ?? ''); + $attributes['priority'] = trim($data['priority'] ?? '0'); $now = date('Y-m-d H:i:s'); $attributes['updated_at'] = $now; $table = 'torrents_custom_fields'; @@ -252,24 +264,29 @@ HEAD; } - public function renderOnUploadPage($torrentId = 0) + public function renderOnUploadPage($torrentId = 0, $searchBoxId) { - global $browsecatmode; - $searchBox = NexusDB::getOne('searchbox', "id = $browsecatmode"); + $searchBox = NexusDB::getOne('searchbox', "id = $searchBoxId"); if (empty($searchBox)) { - throw new \RuntimeException("Invalid search box: $browsecatmode"); + throw new \RuntimeException("Invalid search box: $searchBoxId"); } - $customValues = $this->listTorrentCustomField($torrentId); - $sql = sprintf('select * from torrents_custom_fields where id in (%s)', $searchBox['custom_fields'] ?: 0); + $customValues = $this->listTorrentCustomField($torrentId, $searchBoxId); + $sql = sprintf('select * from torrents_custom_fields where id in (%s) order by priority desc', $searchBox['custom_fields'] ?: 0); $res = sql_query($sql); $html = ''; while ($row = mysql_fetch_assoc($res)) { - $name = "custom_fields[{$row['id']}]"; + $name = "custom_fields[$searchBoxId][{$row['id']}]"; $currentValue = $customValues[$row['id']]['custom_field_value'] ?? ''; + $requireText = ''; + if ($row['required']) { + $requireText = "*"; + } + $trLabel = $row['label'] . $requireText; + $trRelation = "mode_$searchBoxId"; if ($row['type'] == self::TYPE_TEXT) { - $html .= tr($row['label'], sprintf('', $name, $currentValue, '99%'), 1); + $html .= tr($trLabel, sprintf('', $name, $currentValue, '99%'), 1, $trRelation); } elseif ($row['type'] == self::TYPE_TEXTAREA) { - $html .= tr($row['label'], sprintf('', $name, '99%', $currentValue), 1); + $html .= tr($trLabel, sprintf('', $name, '99%', $currentValue), 1, $trRelation); } elseif ($row['type'] == self::TYPE_RADIO || $row['type'] == self::TYPE_CHECKBOX) { if ($row['type'] == self::TYPE_CHECKBOX) { $name .= '[]'; @@ -293,7 +310,7 @@ HEAD; $row['type'], $name, $value, $checked, $label ); } - $html .= tr($row['label'], $part, 1); + $html .= tr($trLabel, $part, 1, $trRelation); } elseif ($row['type'] == self::TYPE_SELECT) { $part = ''; - $html .= tr($row['label'], $part, 1); + $html .= tr($trLabel, $part, 1, $trRelation); } elseif ($row['type'] == self::TYPE_IMAGE) { $callbackFunc = "preview_custom_field_image_" . $row['id']; $iframeId = "iframe_$callbackFunc"; @@ -351,18 +368,14 @@ HEAD; } JS; - $html .= tr($row['label'], $y, 1); + $html .= tr($trLabel, $y, 1, $trRelation, true); } } return $html; } - public function listTorrentCustomField($torrentId, $searchBoxId = 0) + public function listTorrentCustomField($torrentId, $searchBoxId) { - global $browsecatmode; - if ($searchBoxId <= 0) { - $searchBoxId = $browsecatmode; - } //suppose torrentId is array $isArray = true; $torrentIdArr = $torrentId; @@ -371,7 +384,7 @@ JS; $torrentIdArr = [$torrentId]; } $torrentIdStr = implode(',', $torrentIdArr); - $res = sql_query("select f.*, v.custom_field_value, v.torrent_id from torrents_custom_field_values v inner join torrents_custom_fields f on v.custom_field_id = f.id inner join searchbox box on box.id = $searchBoxId and find_in_set(f.id, box.custom_fields) where torrent_id in ($torrentIdStr)"); + $res = sql_query("select f.*, v.custom_field_value, v.torrent_id from torrents_custom_field_values v inner join torrents_custom_fields f on v.custom_field_id = f.id inner join searchbox box on box.id = $searchBoxId and find_in_set(f.id, box.custom_fields) where torrent_id in ($torrentIdStr) order by f.priority desc"); $values = []; $result = []; while ($row = mysql_fetch_assoc($res)) { @@ -402,12 +415,11 @@ JS; return $isArray ? $result : ($result[$torrentId] ?? []); } - public function renderOnTorrentDetailsPage($torrentId) + public function renderOnTorrentDetailsPage($torrentId, $searchBoxId) { - global $browsecatmode; - $displayName = get_searchbox_value($browsecatmode, 'custom_fields_display_name'); - $customFields = $this->listTorrentCustomField($torrentId); - $mixedRowContent = get_searchbox_value($browsecatmode, 'custom_fields_display'); + $displayName = get_searchbox_value($searchBoxId, 'custom_fields_display_name'); + $customFields = $this->listTorrentCustomField($torrentId, $searchBoxId); + $mixedRowContent = get_searchbox_value($searchBoxId, 'custom_fields_display'); $rowByRowHtml = ''; $shouldRenderMixRow = false; foreach ($customFields as $field) { @@ -422,8 +434,15 @@ JS; $mixedRowContent = str_replace("<%{$field['name']}.label%>", $field['label'], $mixedRowContent); $mixedRowContent = str_replace("<%{$field['name']}.value%>", $contentNotFormatted, $mixedRowContent); if ($field['is_single_row']) { - $contentFormatted = $this->formatCustomFieldValue($field, true); - $rowByRowHtml .= tr($field['label'], $contentFormatted, 1); + if (!empty($field['display'])) { + $customFieldDisplay = $field['display']; + $customFieldDisplay = str_replace("<%{$field['name']}.label%>", $field['label'], $customFieldDisplay); + $customFieldDisplay = str_replace("<%{$field['name']}.value%>", $contentNotFormatted, $customFieldDisplay); + $rowByRowHtml .= tr($field['label'], format_comment($customFieldDisplay, false), 1); + } else { + $contentFormatted = $this->formatCustomFieldValue($field, true); + $rowByRowHtml .= tr($field['label'], $contentFormatted, 1); + } } } @@ -443,13 +462,13 @@ JS; switch ($customFieldWithValue['type']) { case self::TYPE_TEXT: case self::TYPE_TEXTAREA: - $result .= $doFormatComment ? format_comment($fieldValue) : $fieldValue; + $result .= $doFormatComment ? format_comment($fieldValue, false) : $fieldValue; break; case self::TYPE_IMAGE: if (substr($fieldValue, 0, 4) == 'http') { $result .= $doFormatComment ? formatImg($fieldValue, true, 700, 0, "attach{$customFieldWithValue['id']}") : $fieldValue; } else { - $result .= $doFormatComment ? format_comment($fieldValue) : $fieldValue; + $result .= $doFormatComment ? format_comment($fieldValue, false) : $fieldValue; } break; case self::TYPE_RADIO: @@ -492,6 +511,32 @@ JS; } + public function saveFieldValues($searchBoxId, $torrentId, array $data) + { + $searchBox = SearchBox::query()->findOrFail($searchBoxId); + $enabledFields = TorrentCustomField::query()->find($searchBox->custom_fields); + $insert = []; + $now = now(); + foreach ($enabledFields as $field) { + if (empty($data[$field->id])) { + if ($field->required) { +// throw new \InvalidArgumentException(nexus_trans("nexus.require_argument", ['argument' => $field->label])); + do_log("Field: {$field->label} required, but empty"); + } + continue; + } + $insert[] = [ + 'torrent_id' => $torrentId, + 'custom_field_id' => $field->id, + 'custom_field_value' => $data[$field->id], + 'created_at' => $now, + 'updated_at' => $now, + ]; + } + TorrentCustomFieldValue::query()->where('torrent_id', $torrentId)->delete(); + TorrentCustomFieldValue::query()->insert($insert); + } + } diff --git a/public/details.php b/public/details.php index e1ca5a2a..5ed0672c 100644 --- a/public/details.php +++ b/public/details.php @@ -278,7 +278,7 @@ JS; do_action('torrent_detail_before_desc', $row['id'], $CURUSER['id']); /**************start custom fields****************/ - echo $customField->renderOnTorrentDetailsPage($id); + echo $customField->renderOnTorrentDetailsPage($id, $row['search_box_id']); /**************end custom fields****************/ diff --git a/public/edit.php b/public/edit.php index f490bd8a..a2a64a57 100644 --- a/public/edit.php +++ b/public/edit.php @@ -67,8 +67,6 @@ else { echo $ptGen->renderUploadPageFormInput($row['pt_gen']); } - $customField->renderOnUploadPage($id); - if ($enablenfo_main=='yes') tr($lang_edit['row_nfo_file'], "".$lang_edit['radio_keep_current']. "".$lang_edit['radio_remove']. @@ -81,7 +79,7 @@ else { tr($lang_functions['text_technical_info'], '
' . $lang_functions['text_technical_info_help_text'], 1); } - $s = ""; $cats = genrelist($sectionmode); foreach ($cats as $subrow) { @@ -93,7 +91,7 @@ else { $s .= "\n"; if ($allowmove){ - $s2 = "\n"; $cats2 = genrelist($othermode); foreach ($cats2 as $subrow) { $s2 .= "
', '', '  '); $s = str_replace($originalBbTagArray, $replaceXhtmlTagArray, $s); @@ -2484,6 +2491,7 @@ $cssupdatedate=($cssupdatedate ? "?".htmlspecialchars($cssupdatedate) : ""); " type="text/css" /> " type="text/css" /> + getSubtitles(); // dd($videos, $audios, $subtitles); if (empty($videos) && empty($audios) && empty($subtitles)) { -// return ''; - return sprintf('
%s
', $this->mediaInfo); + return sprintf('
%s
', $this->mediaInfo); } $result = ''; + $cols = 0; if (!empty($videos)) { + $cols++; $result .= $this->buildTdTable($videos); } if (!empty($audios)) { + $cols++; $result .= $this->buildTdTable($audios); } if (!empty($subtitles)) { + $cols++; $result .= $this->buildTdTable($subtitles); } - $result .= '
'; + $result .= ''; + $rawMediaInfo = sprintf('[spoiler=%s][raw]
%s
[/raw][/spoiler]', nexus_trans('torrent.show_hide_media_info'), $this->mediaInfo); + $result .= sprintf('%s', $cols, format_comment($rawMediaInfo, false)); + $result .= ''; return $result; } @@ -189,7 +195,8 @@ class TechnicalInformation $table .= sprintf('%s: %s', $key, $value); $table .= ''; } - $table .= ''; + $table .= ''; + $table .= ''; return sprintf('%s', $table); } diff --git a/public/styles/nexus.css b/public/styles/nexus.css new file mode 100644 index 00000000..fb9ec30c --- /dev/null +++ b/public/styles/nexus.css @@ -0,0 +1,62 @@ +img.hitandrun { + width: 35px; + height: 12px; + background: url(icons.gif) no-repeat -100px -171px; + margin-left: 0.5em; +} +.spoiler-title { + line-height: 28px; + color: #4d6c99; + cursor: pointer; + font-weight: 700; + background-color: rgba(77, 108, 153, 0.1); + display: inline-block; + padding: 0 10px; +} +.spoiler-content { + display: inline-block; + height: 0; + overflow: hidden; + transition: height 0.3s ease; +} +.layui-layer { + color: black; +} +.layer-form { + padding: 10px 15px; +} +.layer-form .form-control-row input{ + padding: 4px; +} +.layer-form .form-control-row .label{ + margin-bottom: 4px; +} +.rainbow { + text-align: center; + text-decoration: underline; + /*font-size: 32px;*/ + /*font-family: monospace;*/ + /*letter-spacing: 5px;*/ + background: linear-gradient(to right, #6666ff, #0099ff , #00ff00, #ff3399, #6666ff); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + animation: rainbow_animation 6s ease-in-out infinite; + background-size: 400% 100%; +} + +@keyframes rainbow_animation { + 0%,100% { + background-position: 0 0; + } + + 50% { + background-position: 100% 0; + } +} +.nexus-media-info-raw { + padding: 0 0.5rem; +} +.nexus-media-info-raw .spoiler-title-box{ + text-align: center; +} diff --git a/public/styles/sprites.css b/public/styles/sprites.css index e975e89a..7e2f3ae1 100644 --- a/public/styles/sprites.css +++ b/public/styles/sprites.css @@ -474,59 +474,3 @@ img.sltbar height:10px; background:url(bar.gif) repeat-x 0 -116px; } -img.hitandrun { - width: 35px; - height: 12px; - background: url(icons.gif) no-repeat -100px -171px; - margin-left: 0.5em; -} -.spoiler-title { - line-height: 40px; - color: #4d6c99; - cursor: pointer; - font-weight: 700; - background-color: rgba(77, 108, 153, 0.1); - display: inline-block; - padding: 0 10px; -} -.spoiler-content { - display: inline-block; - height: 0; - overflow: hidden; - transition: height 0.3s ease; -} -.layui-layer { - color: black; -} -.layer-form { - padding: 10px 15px; -} -.layer-form .form-control-row input{ - padding: 4px; -} -.layer-form .form-control-row .label{ - margin-bottom: 4px; -} -.rainbow { - text-align: center; - text-decoration: underline; - /*font-size: 32px;*/ - /*font-family: monospace;*/ - /*letter-spacing: 5px;*/ - background: linear-gradient(to right, #6666ff, #0099ff , #00ff00, #ff3399, #6666ff); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - animation: rainbow_animation 6s ease-in-out infinite; - background-size: 400% 100%; -} - -@keyframes rainbow_animation { - 0%,100% { - background-position: 0 0; - } - - 50% { - background-position: 100% 0; - } -} diff --git a/resources/lang/en/torrent.php b/resources/lang/en/torrent.php index 3c52d255..907d2e0d 100644 --- a/resources/lang/en/torrent.php +++ b/resources/lang/en/torrent.php @@ -75,4 +75,5 @@ return [ 'deny_comment_show' => 'Denied, reason: :reason', 'logs_label' => 'Approval logs' ], + 'show_hide_media_info' => 'Show/Hide raw MediaInfo', ]; diff --git a/resources/lang/zh_CN/torrent.php b/resources/lang/zh_CN/torrent.php index 96ff4895..4870f6de 100644 --- a/resources/lang/zh_CN/torrent.php +++ b/resources/lang/zh_CN/torrent.php @@ -75,4 +75,5 @@ return [ 'deny_comment_show' => '审核不通过,原因::reason', 'logs_label' => '审核记录', ], + 'show_hide_media_info' => '显示/隐藏原始 MediaInfo', ]; diff --git a/resources/lang/zh_TW/torrent.php b/resources/lang/zh_TW/torrent.php index 23246c22..e2d99a49 100644 --- a/resources/lang/zh_TW/torrent.php +++ b/resources/lang/zh_TW/torrent.php @@ -75,4 +75,5 @@ return [ 'deny_comment_show' => '審核不通過,原因::reason', 'logs_label' => '審核記錄' ], + 'show_hide_media_info' => '顯示/隱藏原始 MediaInfo', ]; From 30a8fb131bf25dd18529f3d6b43dcbcf3257c850 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 19 Sep 2022 18:52:05 +0800 Subject: [PATCH 13/59] media info td no border --- public/styles/nexus.css | 1 + 1 file changed, 1 insertion(+) diff --git a/public/styles/nexus.css b/public/styles/nexus.css index fb9ec30c..75a76d3c 100644 --- a/public/styles/nexus.css +++ b/public/styles/nexus.css @@ -56,6 +56,7 @@ img.hitandrun { } .nexus-media-info-raw { padding: 0 0.5rem; + border: none; } .nexus-media-info-raw .spoiler-title-box{ text-align: center; From 1aad5314baa2bdf47d01c132fd9df818a8712006 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 19 Sep 2022 21:00:47 +0800 Subject: [PATCH 14/59] fix pos_state no until --- public/takeedit.php | 15 ++++++++------- public/takeupload.php | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/public/takeedit.php b/public/takeedit.php index 21d68d21..56f8cf1d 100644 --- a/public/takeedit.php +++ b/public/takeedit.php @@ -146,13 +146,14 @@ if(user_can('torrentonpromotion')) if(user_can('torrentsticky')) { if (isset($_POST['pos_state']) && isset(\App\Models\Torrent::$posStates[$_POST['pos_state']])) { - $posStateUntil = null; - $posState = \App\Models\Torrent::POS_STATE_STICKY_NONE; - if (!empty($_POST['pos_state_until']) && $_POST['pos_state'] != \App\Models\Torrent::POS_STATE_STICKY_NONE) { - $posStateUntil = \Carbon\Carbon::parse($_POST['pos_state_until']); - if ($posStateUntil->gte(now())) { - $posState = $_POST['pos_state']; - } + $posStateUntil = $_POST['pos_state_until'] ?: null; + $posState = $_POST['pos_state']; + if ($posState == \App\Models\Torrent::POS_STATE_STICKY_NONE) { + $posStateUntil = null; + } + if ($posStateUntil && \Carbon\Carbon::parse($posStateUntil)->lte(now())) { + $posState = \App\Models\Torrent::POS_STATE_STICKY_NONE; + $posStateUntil = null; } $updateset[] = sprintf("pos_state = %s", sqlesc($posState)); $updateset[] = sprintf("pos_state_until = %s", sqlesc($posStateUntil)); diff --git a/public/takeupload.php b/public/takeupload.php index 571f8f59..70830baf 100644 --- a/public/takeupload.php +++ b/public/takeupload.php @@ -344,13 +344,14 @@ if (isset($_POST['hr']) && isset(\App\Models\Torrent::$hrStatus[$_POST['hr']]) & } if(user_can('torrentsticky')) { if (isset($_POST['pos_state']) && isset(\App\Models\Torrent::$posStates[$_POST['pos_state']])) { - $posStateUntil = null; - $posState = \App\Models\Torrent::POS_STATE_STICKY_NONE; - if (!empty($_POST['pos_state_until']) && $_POST['pos_state'] != \App\Models\Torrent::POS_STATE_STICKY_NONE) { - $posStateUntil = \Carbon\Carbon::parse($_POST['pos_state_until']); - if ($posStateUntil->gte(now())) { - $posState = $_POST['pos_state']; - } + $posStateUntil = $_POST['pos_state_until'] ?: null; + $posState = $_POST['pos_state']; + if ($posState == \App\Models\Torrent::POS_STATE_STICKY_NONE) { + $posStateUntil = null; + } + if ($posStateUntil && \Carbon\Carbon::parse($posStateUntil)->lte(now())) { + $posState = \App\Models\Torrent::POS_STATE_STICKY_NONE; + $posStateUntil = null; } $insert['pos_state'] = $posState; $insert['pos_state_until'] = $posStateUntil; From 407b8379a2b6a1b112a558ce18eacdf516c0e649 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 19 Sep 2022 23:04:48 +0800 Subject: [PATCH 15/59] fix secondicon source can not be selected --- public/catmanage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/public/catmanage.php b/public/catmanage.php index d0db9a55..9593e9cc 100644 --- a/public/catmanage.php +++ b/public/catmanage.php @@ -784,6 +784,7 @@ elseif($action == 'submit') $updateset[] = "name=".sqlesc($name); $updateset[] = "image=".sqlesc($image); $updateset[] = "class_name=".sqlesc($class_name); + $updateset[] = "source=".sqlesc($source); $updateset[] = "medium=".sqlesc($medium); $updateset[] = "codec=".sqlesc($codec); $updateset[] = "standard=".sqlesc($standard); From e7211b64924c01797c7ea1ab404c5c468b06de3d Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Tue, 20 Sep 2022 00:01:45 +0800 Subject: [PATCH 16/59] fix media info pre width --- app/Repositories/BaseRepository.php | 3 +-- public/styles/nexus.css | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Repositories/BaseRepository.php b/app/Repositories/BaseRepository.php index 3b78b474..03f7fd92 100644 --- a/app/Repositories/BaseRepository.php +++ b/app/Repositories/BaseRepository.php @@ -22,11 +22,10 @@ class BaseRepository protected function handleAnonymous($username, User $user, User $authenticator, Torrent $torrent = null) { - $canViewAnonymousClass = Setting::get('authority.viewanonymous'); if($user->privacy == "strong" || ($torrent && $torrent->anonymous == 'yes' && $user->id == $torrent->owner)) { //用户强私密,或者种子作者匿名而当前项作者刚好为种子作者 $anonymousText = nexus_trans('label.anonymous'); - if($authenticator->class >= $canViewAnonymousClass || $user->id == $authenticator->id) { + if(user_can('viewanonymous', false, $authenticator->id) || $user->id == $authenticator->id) { //但当前用户权限可以查看匿名者,或当前用户查看自己的数据,显示个匿名,后边加真实用户名 return sprintf('%s(%s)', $anonymousText, $username); } else { diff --git a/public/styles/nexus.css b/public/styles/nexus.css index 75a76d3c..7038afea 100644 --- a/public/styles/nexus.css +++ b/public/styles/nexus.css @@ -61,3 +61,6 @@ img.hitandrun { .nexus-media-info-raw .spoiler-title-box{ text-align: center; } +.nexus-media-info-raw pre { + white-space: break-spaces; +} From dd36d6a6544d1f2b644e961352f78b8011c09171 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Tue, 20 Sep 2022 18:47:33 +0800 Subject: [PATCH 17/59] add role filter to bulk message --- .../Resources/System/ExamResource.php | 4 +- public/increment-bulk.php | 2 +- public/staffmess.php | 44 +++++++++++-------- public/take-increment-bulk.php | 2 +- public/takestaffmess.php | 12 ++++- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/app/Filament/Resources/System/ExamResource.php b/app/Filament/Resources/System/ExamResource.php index 51369b67..3f0bc949 100644 --- a/app/Filament/Resources/System/ExamResource.php +++ b/app/Filament/Resources/System/ExamResource.php @@ -85,7 +85,7 @@ class ExamResource extends Resource Forms\Components\Section::make(__('label.exam.section_time'))->schema([ Forms\Components\DateTimePicker::make('begin')->label(__('label.begin')), - Forms\Components\DateTimePicker::make('end')->label(__('label.begin')), + Forms\Components\DateTimePicker::make('end')->label(__('label.end')), Forms\Components\TextInput::make('duration') ->integer() ->columnSpan(['sm' => 2]) @@ -118,7 +118,7 @@ class ExamResource extends Resource Tables\Columns\TextColumn::make('name')->searchable()->label(__('label.name')), Tables\Columns\TextColumn::make('indexFormatted')->label(__('label.exam.index_formatted'))->html(), Tables\Columns\TextColumn::make('begin')->label(__('label.begin')), - Tables\Columns\TextColumn::make('end')->label(__('label.begin')), + Tables\Columns\TextColumn::make('end')->label(__('label.end')), Tables\Columns\TextColumn::make('durationText')->label(__('label.duration')), Tables\Columns\TextColumn::make('filterFormatted')->label(__('label.exam.filter_formatted'))->html(), Tables\Columns\BooleanColumn::make('is_discovered')->label(__('label.exam.is_discovered')), diff --git a/public/increment-bulk.php b/public/increment-bulk.php index a2c5f723..dd60d4b0 100644 --- a/public/increment-bulk.php +++ b/public/increment-bulk.php @@ -64,7 +64,7 @@ $classes = array_chunk(\App\Models\User::$classes, 4, true); - + Subject Reason diff --git a/public/staffmess.php b/public/staffmess.php index 699c31a2..ac297e90 100644 --- a/public/staffmess.php +++ b/public/staffmess.php @@ -24,35 +24,43 @@ if ($_GET["returnto"] || $_SERVER["HTTP_REFERER"]) -The message has ben sent. +The message has ben sent. -Send to:
- - '); - foreach ($chunk as $class => $info) { - printf('', $class, $info['text']); - } - printf(''); - } - ?> -
- + Send to class: + + + '); + foreach ($chunk as $class => $info) { + printf('', $class, $info['text']); + } + printf(''); + } + ?> +
+ -Subject - + -
Sender:   + Subject + + + + Message + + + +
Sender:     System
- + > diff --git a/public/take-increment-bulk.php b/public/take-increment-bulk.php index 85a45968..9a570566 100644 --- a/public/take-increment-bulk.php +++ b/public/take-increment-bulk.php @@ -37,7 +37,7 @@ $conditions = []; if (!empty($_POST['classes'])) { $conditions[] = "class IN (" . implode(', ', $_POST['classes']) . ")"; } -$conditions = apply_filter("increment_bulk_query_conditions", $conditions, $_POST); +$conditions = apply_filter("role_query_conditions", $conditions, $_POST); if (empty($conditions)) { stderr("Error","No valid filter"); } diff --git a/public/takestaffmess.php b/public/takestaffmess.php index e30f6f25..57d86e64 100644 --- a/public/takestaffmess.php +++ b/public/takestaffmess.php @@ -28,11 +28,19 @@ $subject = trim($_POST['subject']); $size = 10000; $page = 1; set_time_limit(300); -$classStr = implode(",", $updateset); +$conditions = []; +if (!empty($_POST['classes'])) { + $conditions[] = "class IN (" . implode(', ', $_POST['classes']) . ")"; +} +$conditions = apply_filter("role_query_conditions", $conditions, $_POST); +if (empty($conditions)) { + stderr("Error","No valid filter"); +} +$whereStr = implode(' OR ', $conditions); while (true) { $msgValues = []; $offset = ($page - 1) * $size; - $query = sql_query("SELECT id FROM users WHERE class IN ($classStr) and `enabled` = 'yes' and `status` = 'confirmed' limit $offset, $size"); + $query = sql_query("SELECT id FROM users WHERE ($whereStr) and `enabled` = 'yes' and `status` = 'confirmed' limit $offset, $size"); while($dat=mysql_fetch_assoc($query)) { $msgValues[] = sprintf('(%s, %s, %s, %s, %s)', $sender_id, $dat['id'], $dt, sqlesc($subject), sqlesc($msg)); From e94c7340e47f1fd04bced3a3ea2c1ac35414b0c8 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Tue, 20 Sep 2022 19:39:10 +0800 Subject: [PATCH 18/59] searchbox record support filter by ip --- .../Resources/System/SeedBoxRecordResource.php | 13 ++++++++++++- include/constants.php | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/Filament/Resources/System/SeedBoxRecordResource.php b/app/Filament/Resources/System/SeedBoxRecordResource.php index 893e2c08..14565204 100644 --- a/app/Filament/Resources/System/SeedBoxRecordResource.php +++ b/app/Filament/Resources/System/SeedBoxRecordResource.php @@ -15,6 +15,7 @@ use Filament\Tables; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; use phpDocumentor\Reflection\DocBlock\Tags\See; +use PhpIP\IP; class SeedBoxRecordResource extends Resource { @@ -60,7 +61,17 @@ class SeedBoxRecordResource extends Resource Tables\Columns\TextColumn::make('bandwidth')->label(__('label.seed_box_record.bandwidth')), Tables\Columns\TextColumn::make('ip') ->label(__('label.seed_box_record.ip')) - ->searchable() + ->searchable(true, function (Builder $query, $search) { + try { + $ip = IP::create($search); + $ipNumeric = $ip->numeric(); + return $query->orWhere(function (Builder $query) use ($ipNumeric) { + return $query->where('ip_begin_numeric', '<=', $ipNumeric)->where('ip_end_numeric', '>=', $ipNumeric); + }); + } catch (\Exception $exception) { + do_log("Invalid IP: $search, error: " . $exception->getMessage()); + } + }) ->formatStateUsing(fn ($record) => $record->ip ?: sprintf('%s ~ %s', $record->ip_begin, $record->ip_end)), Tables\Columns\TextColumn::make('comment')->label(__('label.comment')), Tables\Columns\BadgeColumn::make('status') diff --git a/include/constants.php b/include/constants.php index b83eced9..1ed4c7b5 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ Date: Sun, 25 Sep 2022 16:33:52 +0800 Subject: [PATCH 19/59] official additioin + zero bonus --- .../SettingResource/Pages/EditSetting.php | 1 + app/Models/User.php | 4 +- app/Repositories/TagRepository.php | 15 +++++ include/cleanup.php | 32 +++++++--- include/cleanup_cli.php | 3 +- include/constants.php | 4 +- include/functions.php | 51 +++++++++------ include/globalfunctions.php | 6 ++ lang/chs/lang_mybonus.php | 9 ++- lang/chs/lang_settings.php | 9 +++ lang/cht/lang_mybonus.php | 10 ++- lang/cht/lang_settings.php | 9 +++ lang/en/lang_mybonus.php | 9 ++- lang/en/lang_settings.php | 9 +++ nexus/Install/settings.default.php | 2 + public/mybonus.php | 62 ++++++++++++++----- public/pic/bonusformulaa.svg | 2 + public/settings.php | 19 +++++- resources/lang/en/nexus.php | 2 + resources/lang/zh_CN/nexus.php | 1 + resources/lang/zh_TW/nexus.php | 2 + 21 files changed, 206 insertions(+), 55 deletions(-) create mode 100644 public/pic/bonusformulaa.svg diff --git a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php index 92bda9d3..95b8f914 100644 --- a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php +++ b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php @@ -6,6 +6,7 @@ use App\Filament\OptionsTrait; use App\Filament\Resources\System\SettingResource; use App\Models\HitAndRun; use App\Models\Setting; +use App\Models\Tag; use Filament\Facades\Filament; use Filament\Forms\ComponentContainer; use Filament\Forms\Concerns\InteractsWithForms; diff --git a/app/Models/User.php b/app/Models/User.php index 4fa1ccd1..e6f21f62 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -211,7 +211,7 @@ class User extends Authenticatable implements FilamentUser, HasName 'id', 'username', 'email', 'class', 'status', 'added', 'avatar', 'uploaded', 'downloaded', 'seedbonus', 'seedtime', 'leechtime', 'invited_by', 'enabled', 'seed_points', 'last_access', 'invites', - 'lang', 'attendance_card', 'privacy', 'noad', 'downloadpos', + 'lang', 'attendance_card', 'privacy', 'noad', 'downloadpos', 'donoruntil', 'donor' ]; public static function getDefaultUserAttributes(): array @@ -535,4 +535,6 @@ class User extends Authenticatable implements FilamentUser, HasName } + + } diff --git a/app/Repositories/TagRepository.php b/app/Repositories/TagRepository.php index c871a526..2353101d 100644 --- a/app/Repositories/TagRepository.php +++ b/app/Repositories/TagRepository.php @@ -154,5 +154,20 @@ class TagRepository extends BaseRepository return self::$allTags; } + public function buildSelect($name, $value): string + { + $list = $this->listAll(); + $select = sprintf(''; + return $select; + } + } diff --git a/include/cleanup.php b/include/cleanup.php index 9cba944e..a9410767 100644 --- a/include/cleanup.php +++ b/include/cleanup.php @@ -265,22 +265,36 @@ function docleanup($forceAll = 0, $printProgress = false) { if (mysql_num_rows($res) > 0) { $haremAdditionFactor = get_setting('bonus.harem_addition'); + $officialAdditionFactor = get_setting('bonus.official_addition'); while ($arr = mysql_fetch_assoc($res)) //loop for different users { + $userInfo = get_user_row($arr['userid']); + $isDonor = is_donor($userInfo); $seedBonusResult = calculate_seed_bonus($arr['userid']); - $dividend = 3600 / $autoclean_interval_one; - $all_bonus = $seedBonusResult['all_bonus'] / $dividend; - $seed_points = $seedBonusResult['seed_points'] / $dividend; - $bonusLog = "[CLEANUP_CALCULATE_SEED_BONUS], user: {$arr['userid']}, seedBonusResult: " . nexus_json_encode($seedBonusResult) . ", all_bonus: $all_bonus, seed_points: $seed_points"; - if ($haremAdditionFactor > 0) { - $haremAddition = calculate_harem_addition($arr['userid']) * $haremAdditionFactor / $dividend; - $all_bonus += $haremAddition; - $bonusLog .= ", haremAddition: $haremAddition, new all_bonus: $all_bonus"; + $bonusLog = "[CLEANUP_CALCULATE_SEED_BONUS], user: {$arr['userid']}, seedBonusResult: " . nexus_json_encode($seedBonusResult); + $all_bonus = $seedBonusResult['seed_bonus']; + $bonusLog .= ", all_bonus: $all_bonus"; + if ($isDonor) { + $all_bonus = $all_bonus * $donortimes_bonus; + $bonusLog .= ", isDonor, donortimes_bonus: $donortimes_bonus, all_bonus: $all_bonus"; } + if ($officialAdditionFactor > 0) { + $officialAddition = $seedBonusResult['official_bonus'] * $officialAdditionFactor; + $all_bonus += $officialAddition; + $bonusLog .= ", officialAdditionFactor: $officialAdditionFactor, official_bonus: {$seedBonusResult['official_bonus']}, officialAddition: $officialAddition, all_bonus: $all_bonus"; + } + if ($haremAdditionFactor > 0) { + $haremBonus = calculate_harem_addition($arr['userid']); + $haremAddition = $haremBonus * $haremAdditionFactor; + $all_bonus += $haremAddition; + $bonusLog .= ", haremAdditionFactor: $haremAdditionFactor, haremBonus: $haremBonus, haremAddition: $haremAddition, all_bonus: $all_bonus"; + } + $dividend = 3600 / $autoclean_interval_one; + $all_bonus = $all_bonus / $dividend; + $seed_points = $seedBonusResult['seed_points'] / $dividend; $sql = "update users set seed_points = ifnull(seed_points, 0) + $seed_points, seedbonus = seedbonus + $all_bonus where id = {$arr["userid"]}"; do_log("$bonusLog, query: $sql"); sql_query($sql); - } } $log = 'calculate seeding bonus'; diff --git a/include/cleanup_cli.php b/include/cleanup_cli.php index 1118c783..e1b4152a 100644 --- a/include/cleanup_cli.php +++ b/include/cleanup_cli.php @@ -23,13 +23,14 @@ if (isset($_SERVER['argv'][1])) { $force = $_SERVER['argv'][1] ? 1 : 0; } $logPrefix = "[CLEANUP_CLI]"; +$begin = time(); try { if ($force) { $result = docleanup(1, true); } else { $result = autoclean(true); } - $log = "$logPrefix, DONE: $result"; + $log = "$logPrefix, DONE: $result, cost time in seconds: " . (time() - $begin); do_log($log); printProgress($log); } catch (\Exception $exception) { diff --git a/include/constants.php b/include/constants.php index 1ed4c7b5..35c9e939 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ $maxseeding_bonus) $count = $maxseeding_bonus; - $all_bonus = $seed_bonus = $seed_points = $valuetwo * atan($A / $l_bonus) + ($perseeding_bonus * $count); - $is_donor_info = \Nexus\Database\NexusDB::getOne('users', "id = $uid", "donor, donoruntil"); - $is_donor_until = $is_donor_info['donoruntil']; - $is_donor = $is_donor_info['donor'] == 'yes' && ($is_donor_until === null || $is_donor_until == '0000-00-00 00:00:00' || $is_donor_until >= date('Y-m-d H:i:s')); - $is_donor = intval($is_donor); - $log = "$logPrefix, original bonus: $all_bonus, is_donor: $is_donor, donortimes_bonus: $donortimes_bonus"; - if ($is_donor && $donortimes_bonus > 0) { - $all_bonus = $all_bonus * $donortimes_bonus; - $log .= ", do multiple, all_bonus: $all_bonus"; - } - $result = compact('seed_points','seed_bonus', 'all_bonus', 'A', 'count', 'torrent_peer_count'); - do_log("$log, result: " . json_encode($result)); + $seed_bonus = $seed_points = $valuetwo * atan($A / $l_bonus) + ($perseeding_bonus * $count); + $official_bonus = $valuetwo * atan($official_a / $l_bonus) + ($perseeding_bonus * $count); + $result = compact('seed_points','seed_bonus', 'A', 'count', 'torrent_peer_count', 'official_a', 'official_bonus'); + $result['donor_times'] = $donortimes_bonus; + $result['official_additional_factor'] = $officialAdditionalFactor; + do_log("$logPrefix, result: " . json_encode($result)); return $result; } diff --git a/include/globalfunctions.php b/include/globalfunctions.php index 242256f7..09b50ebf 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -730,6 +730,7 @@ function get_user_row($id) } else { $arr['__is_rainbow'] = 0; } + $arr['__is_donor'] = is_donor($arr); return apply_filter("user_row", $arr); }); @@ -1031,3 +1032,8 @@ function user_can($permission, $fail = false, $uid = 0): bool } throw new \App\Exceptions\InsufficientPermissionException(); } + +function is_donor(array $userInfo): bool +{ + return $userInfo['donor'] == 'yes' && ($userInfo['donoruntil'] === null || $userInfo['donoruntil'] == '0000-00-00 00:00:00' || $userInfo['donoruntil'] >= date('Y-m-d H:i:s')); +} diff --git a/lang/chs/lang_mybonus.php b/lang/chs/lang_mybonus.php index 28b45e47..f6b04e0f 100644 --- a/lang/chs/lang_mybonus.php +++ b/lang/chs/lang_mybonus.php @@ -91,12 +91,13 @@ $lang_mybonus = array 'text_bonus_gift_note' => "可能你不需要魔力值,为什么不把它送给那些需要的人呢?你可以把自己的魔力值作为礼物送给别人。交易完成后,你的魔力值会减少,礼物接收者的魔力值则会增加。同时,接收者会收到一条关于你的馈赠的短讯。", 'text_error' => "错误", 'text_ratio_too_high' => "分享率已很高", - 'text_bonus_formula_one' => "每小时获得的魔力值点数由下面的公式给出
    \"A
    \"B
+ 'text_bonus_formula_one' => "每小时获得的魔力值点数由下面的公式给出

    
    
式中
  • A为中间变量
  • Ti为第i个种子的生存时间, 即自种子发布起到现在所经过的时间, 单位是周
  • T0为参数。T0 = ", 'text_bonus_formula_two' => "
  • Si为第i个种子的大小,单位是GB
  • Ni为第i个种子当前的做种者数
  • N0为参数。N0 = ", 'text_bonus_formula_three' => "
  • B为1小时中用户获得的做种魔力值点数
  • B0为参数,代表用户1小时获得魔力值的上限。B0 = ", 'text_bonus_formula_four' => "
  • L为参数。L = ", 'text_bonus_formula_five' => "
简言之,为做种人数少、文件体积大的种子做种能获得更多魔力值。", + 'text_bonus_formula_wi' => "
  • Wi为第i个种子的权重系数,默认为 1,零魔种子为 ", 'text_user_with_ratio_above' => "分享率高于", 'text_and_uploaded_amount_above' => "且上传量大于", 'text_cannot_exchange_uploading' => "GB的用户不能换取更多的上传量。", @@ -137,13 +138,17 @@ $lang_mybonus = array 'text_success_buy_attendance_card' => '成功购买了一张补签卡。', 'text_harem_addition_get' => '当前后宫加成每小时获得 %s 魔力', 'reward_type' => '奖励类型', - 'addition' => '加成', + 'factor' => '系数', 'got_bonus' => '获得魔力', 'total' => '合计', 'reward_type_basic' => '基本奖励', 'reward_type_harem_addition' => '后宫加成', 'bonus_base' => '基础魔力', 'lock_text' => '系统限制 %s 秒内只能点击交换按钮一次!', + 'text_get_by_seeding_official' => '官种每小时将额外得到如下的魔力值', + 'official_calculate_method' => '官种奖励计算公式同上,只是仅针对官种进行计算', + 'official_tag_bonus_additional_factor' => '最终奖励为计算所得官种奖励乘以官种系数,当前官种系数为: ', + 'reward_type_official_addition' => '官种加成', ); ?> diff --git a/lang/chs/lang_settings.php b/lang/chs/lang_settings.php index da6f8585..8ba8e403 100644 --- a/lang/chs/lang_settings.php +++ b/lang/chs/lang_settings.php @@ -218,6 +218,7 @@ $lang_settings = array 'text_bonus_formula_four' => "。默认为'4'", 'text_bonus_formula_five' => "Si为第i个种子的大小,单位是GB", 'text_bonus_formula_six' => "Ni为第i个种子当前的做种者数
  • N0为参数。N0 = ", + 'text_bonus_formula_zero_bonus_factor' => "Wi为第i个种子权重系数。默认为 1,零魔种子为 ", 'text_bonus_formula_seven' => "。默认为'7'", 'text_bonus_formula_eight' => "B为1小时中用户获得的做种魔力值点数", 'text_bonus_formula_nine' => "B0为参数,代表用户1小时获得魔力值的上限。B0 = ", @@ -779,6 +780,14 @@ $lang_settings = array 'text_ten_gb_download_credit_note' => " 个魔力值,如果他选择交换10.0 GB下载量。默认'1000'。", 'row_hundred_gb_download_credit' => "100.0 GB 下载量", 'text_hundred_gb_download_credit_note' => " 个魔力值,如果他选择交换100.0 GB下载量。默认'8000'。", + 'row_official_addition' => '官种加成', + 'text_user_would_get_by_official' => '用户将获得官种正常魔力值的', + 'text_addition_addition_note' => '倍作为奖励(系数,如填入 0.01,官种获得 100 魔力则奖励用户 100 * 0.01 = 1)', + 'zero_bonus_factor_default' => '。默认为:0.2', + 'row_official_tag' => '官种标签', + 'text_official_tag_note' => '。带此标签的种子为官种', + 'row_zero_bonus_tag' => '零魔标签', + 'text_zero_bonus_tag_note' => '。带此标签的种子为零魔种子', ); ?> diff --git a/lang/cht/lang_mybonus.php b/lang/cht/lang_mybonus.php index fcce5ccf..e77b7aad 100644 --- a/lang/cht/lang_mybonus.php +++ b/lang/cht/lang_mybonus.php @@ -91,12 +91,13 @@ $lang_mybonus = array 'text_bonus_gift_note' => "可能你不需要魔力值,為什麼不把它送給那些需要的人呢?你可以把自己的魔力值作為禮物送給別人。交易完成後,你的魔力值會減少,禮物接收者的魔力值則會增加。同時,接收者會收到一條關於你的饋贈的短訊。", 'text_error' => "錯誤", 'text_ratio_too_high' => "分享率已很高", - 'text_bonus_formula_one' => "每小時獲得的魔力值點數由下面的公式給出
        \"A
        \"B
    + 'text_bonus_formula_one' => "每小時獲得的魔力值點數由下面的公式給出

        
        
    式中
    • A為中間變量
    • Ti為第i個種子的生存時間, 即自種子發布起到現在所經過的時間, 單位是周
    • T0為參數。T0 = ", 'text_bonus_formula_two' => "
    • Si為第i個種子的大小,單位是GB
    • Ni為第i個種子當前的做種者數
    • N0為參數。N0 = ", 'text_bonus_formula_three' => "
    • B為1小時中用戶獲得的做種魔力值點數
    • B0為參數,代表用戶1小時獲得魔力值的上限。B0 = ", 'text_bonus_formula_four' => "
    • L為參數。L = ", 'text_bonus_formula_five' => "
    簡言之,為做種人數少、文件體積大的種子做種能獲得更多魔力值。", + 'text_bonus_formula_wi' => "
  • Wi為第i個種子的權重系數,默認為 1,零魔種子為 ", 'text_user_with_ratio_above' => "分享率高于", 'text_and_uploaded_amount_above' => "且上傳量大于", 'text_cannot_exchange_uploading' => "GB的用戶不能換取更多的上傳量。", @@ -137,13 +138,18 @@ $lang_mybonus = array 'text_success_buy_attendance_card' => '成功購買了一張補簽卡。', 'text_harem_addition_get' => '當前後宮加成每小時獲得 %s 魔力', 'reward_type' => '獎勵類型', - 'addition' => '加成', + 'factor' => '系數', 'got_bonus' => '獲得魔力', 'total' => '合計', 'reward_type_basic' => '基本獎勵', 'reward_type_harem_addition' => '後宮加成', 'bonus_base' => '基礎魔力', 'lock_text' => '系統限製 %s 秒內只能點擊交換按鈕一次!', + 'text_get_by_seeding_official' => '官種每小時將額外得到如下的魔力值', + 'official_calculate_method' => '官種獎勵計算公式同上,只是僅針對官種進行計算', + 'official_tag_bonus_additional_factor' => '最終獎勵為計算所得官種獎勵乘以官種系數,當前官種系數為: ', + 'reward_type_official_addition' => '官種加成', + ); ?> diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index af79ecf1..b498d177 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -218,6 +218,7 @@ $lang_settings = array 'text_bonus_formula_four' => "。預設為'4'", 'text_bonus_formula_five' => "Si為第i個種子的大小,單位是GB", 'text_bonus_formula_six' => "Ni為第i個種子目前的做種者數
  • N0為參數。N0 = ", + 'text_bonus_formula_zero_bonus_factor' => "Wi為第i個種子權重系數。默認為 1,零魔種子為 ", 'text_bonus_formula_seven' => "。預設為'7'", 'text_bonus_formula_eight' => "B為1小時中用戶獲得的做種魔力值點數", 'text_bonus_formula_nine' => "B0為參數,代表用戶1小時獲得魔力值的上限。B0 = ", @@ -779,6 +780,14 @@ $lang_settings = array 'text_ten_gb_download_credit_note' => " 個魔力值,如果他選擇交換10.0 GB下載量。默認'1000'。", 'row_hundred_gb_download_credit' => "100.0 GB 下載量", 'text_hundred_gb_download_credit_note' => " 個魔力值,如果他選擇交換100.0 GB下載量。默認'8000'。", + 'row_official_addition' => '官種加成', + 'text_user_would_get_by_official' => '用戶將獲得官種正常魔力值的', + 'text_addition_addition_note' => '倍作為獎勵(系數,如填入 0.01,官種獲得 100 魔力則獎勵用戶 100 * 0.01 = 1)', + 'zero_bonus_factor_default' => '。默認為:0.2', + 'row_official_tag' => '官種標簽', + 'text_official_tag_note' => '。帶此標簽的種子為官種', + 'row_zero_bonus_tag' => '零魔標簽', + 'text_zero_bonus_tag_note' => '。帶此標簽的種子為零魔種子', ); ?> diff --git a/lang/en/lang_mybonus.php b/lang/en/lang_mybonus.php index b0b09edd..995ae057 100644 --- a/lang/en/lang_mybonus.php +++ b/lang/en/lang_mybonus.php @@ -91,12 +91,13 @@ $lang_mybonus = array 'text_bonus_gift_note' => "Well perhaps you don't need the upload credit, but you know somebody that could use the Karma boost! You are now able to give your Karma credits as a gift! The points are then removed from your Bonus Bank and added to the account of a user of your choice! And they receive a PM with all the info as well as who it came from...", 'text_error' => "Error", 'text_ratio_too_high' => "Your ratio is high", - 'text_bonus_formula_one' => "The number of karma points gained per hour is given by the following formula
        \"A
        \"B
    + 'text_bonus_formula_one' => "The number of karma points gained per hour is given by the following formula

        
        
    where
    • A is an intermediate variable
    • Ti is the ith torrent's Time Alive (TA), i.e. time elapsed since the torrent was uploaded, in weeks
    • T0 is a parameter. T0 = ", 'text_bonus_formula_two' => "
    • Si is the ith torrent's size, in GB
    • Ni is the number of current seeders of the ith torrent
    • N0 is a parameter. N0 = ", 'text_bonus_formula_three' => "
    • B is the number of karma points gained by seeding in an hour
    • B0 is a parameter, which stands for the maximum bonus points per hour a user can get by seeding. B0 = ", 'text_bonus_formula_four' => "
    • L is a parameter. L = ", 'text_bonus_formula_five' => "
    In a nutshell, you can get more bonus by seeding less-seeded and larger torrents.", + 'text_bonus_formula_wi' => "
  • Wi is the ith torrent's weight, default is 1, zero torrent is ", 'text_user_with_ratio_above' => "User with ratio above ", 'text_and_uploaded_amount_above' => " and uploaded amount above ", 'text_cannot_exchange_uploading' => " GB cannot exchange for more uploading credit.", @@ -137,13 +138,17 @@ where
    • A is an intermediate variable
    • Ti is the i< 'text_success_buy_attendance_card' => 'Success buy 1 attendance card.', 'text_harem_addition_get' => 'Current harem addition gains %s bonus per hour', 'reward_type' => 'Reward type', - 'addition' => 'Addition', + 'factor' => 'Factor', 'got_bonus' => 'Got bonus', 'total' => 'Total', 'reward_type_basic' => 'Basic reward', 'reward_type_harem_addition' => 'Harem addition', 'bonus_base' => 'Base bonus', 'lock_text' => 'The system limits you to one click on the exchange button within %s seconds!', + 'text_get_by_seeding_official' => 'The official torrents will receive the following additional bonus value per hour', + 'official_calculate_method' => 'The formula for calculating the official reward is the same as above, but only for the official type', + 'official_tag_bonus_additional_factor' => 'The final reward is the calculated official type reward multiplied by the official type factor, the current official type factor is: ', + 'reward_type_official_addition' => 'Official addition', ); ?> diff --git a/lang/en/lang_settings.php b/lang/en/lang_settings.php index c172cd12..a67f96c4 100644 --- a/lang/en/lang_settings.php +++ b/lang/en/lang_settings.php @@ -218,6 +218,7 @@ $lang_settings = array 'text_bonus_formula_four' => ". Default '4'", 'text_bonus_formula_five' => "Si is the ith torrent's size, in GB", 'text_bonus_formula_six' => "Ni is the number of current seeders of the ith torrent
    • N0 is a parameter. N0 = ", + 'text_bonus_formula_zero_bonus_factor' => "Wi is the ith torrent's weight. Default is 1, zero torrent is ", 'text_bonus_formula_seven' => ". Default '7'", 'text_bonus_formula_eight' => "B is the number of karma points gained by seeding in an hour", 'text_bonus_formula_nine' => "B0 is a parameter, which standards for the maximum bonus points per hour a user can get by seeding. B0 = ", @@ -779,6 +780,14 @@ $lang_settings = array 'text_ten_gb_download_credit_note' => " bonus points to exchange for 10.0 GB downloading credit. Default '1000'.", 'row_hundred_gb_download_credit' => "100.0 GB downloading credit", 'text_hundred_gb_download_credit_note' => " bonus points to exchange for 100.0 GB downloading credit. Default '8000'.", + 'row_official_addition' => 'Official addition', + 'text_user_would_get_by_official' => 'The user will receive the normal bonus value of the official torrent', + 'text_addition_addition_note' => 'times as reward (factor, e.g. fill in 0.01, if official torrens gets 100 bonus then reward user 100 * 0.01 = 1)', + 'zero_bonus_factor_default' => '. Default is: 0.2', + 'row_official_tag' => 'Official tag', + 'text_official_tag_note' => '. Torrents with this tag are official torrents', + 'row_zero_bonus_tag' => 'Zero bonus tag', + 'text_zero_bonus_tag_note' => '. Torrents with this tag are zero bonus torrents', ); ?> diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index fc9d2335..33514956 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -236,6 +236,8 @@ return array ( 'hundredgbupload' => 10000, 'tengbdownload' => 1000, 'hundredgbdownload' => 8000, + 'official_addition' => '0.5', + 'zero_bonus_factor' => '0.2', ), 'account' => array ( diff --git a/public/mybonus.php b/public/mybonus.php index 64f50363..9d78b7cc 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -420,7 +420,7 @@ print("

      ".$lang_mybonus['text_get_by_seeding']."

      "); print("
        "); if ($perseeding_bonus > 0) print("
      • ".$perseeding_bonus.$lang_mybonus['text_point'].add_s($perseeding_bonus).$lang_mybonus['text_for_seeding_torrent'].$maxseeding_bonus.$lang_mybonus['text_torrent'].add_s($maxseeding_bonus).")
      • "); -print("
      • ".$lang_mybonus['text_bonus_formula_one'].$tzero_bonus.$lang_mybonus['text_bonus_formula_two'].$nzero_bonus.$lang_mybonus['text_bonus_formula_three'].$bzero_bonus.$lang_mybonus['text_bonus_formula_four'].$l_bonus.$lang_mybonus['text_bonus_formula_five']."
      • "); +print("
      • ".$lang_mybonus['text_bonus_formula_one'].$tzero_bonus.$lang_mybonus['text_bonus_formula_two'].$nzero_bonus.$lang_mybonus['text_bonus_formula_wi'].get_setting('bonus.zero_bonus_factor').$lang_mybonus['text_bonus_formula_three'].$bzero_bonus.$lang_mybonus['text_bonus_formula_four'].$l_bonus.$lang_mybonus['text_bonus_formula_five']."
      • "); if ($donortimes_bonus) print("
      • ".$lang_mybonus['text_donors_always_get'].$donortimes_bonus.$lang_mybonus['text_times_of_bonus']."
      • "); @@ -450,11 +450,10 @@ print("
      "); // $all_bonus = $valuetwo * atan($A / $l_bonus) + ($perseeding_bonus * $count); $seedBonusResult = calculate_seed_bonus($CURUSER['id']); -$all_bonus = $seedBonusResult['all_bonus']; $A = $seedBonusResult['A']; - $percent = $all_bonus * 100 / ($bzero_bonus + $perseeding_bonus * $maxseeding_bonus); - print("
      ".$lang_mybonus['text_you_are_currently_getting'].round($all_bonus,3).$lang_mybonus['text_point'].add_s($all_bonus).$lang_mybonus['text_per_hour']." (A = ".round($A,1).")
      \n"; } $banstable .= "
      "); + $percent = $seedBonusResult['seed_bonus'] * 100 / ($bzero_bonus + $perseeding_bonus * $maxseeding_bonus); + print("
      ".$lang_mybonus['text_you_are_currently_getting'].round($seedBonusResult['seed_bonus'],3).$lang_mybonus['text_point'].add_s($seedBonusResult['seed_bonus']).$lang_mybonus['text_per_hour']." (A = ".round($A,1).")
      "); if ($percent <= 30) $loadpic = "loadbarred"; elseif ($percent <= 60) $loadpic = "loadbaryellow"; @@ -462,26 +461,57 @@ $A = $seedBonusResult['A']; $width = $percent * 4; print("\"".$percent."%\"
      "); -$factor = get_setting('bonus.harem_addition'); -$addition = calculate_harem_addition($CURUSER['id']); -$totalBonus = number_format($all_bonus + $addition * $factor, 3); + $officialAdditionalFactor = get_setting('bonus.official_addition'); + if ($officialAdditionalFactor > 0) { + print("

      ".$lang_mybonus['text_get_by_seeding_official']."

      "); + print("
        "); + print("
      • ".$lang_mybonus['official_calculate_method']."
      • "); + print("
      • ".$lang_mybonus['official_tag_bonus_additional_factor'].$officialAdditionalFactor."
      • "); + print("
      "); + } + +$haremFactor = get_setting('bonus.harem_addition'); +$haremAddition = calculate_harem_addition($CURUSER['id']); +$isDonor = is_donor($CURUSER); +$baseBonusFactor = 1; +if ($isDonor) { + $baseBonusFactor = $donortimes_bonus; +} +$totalBonus = number_format($seedBonusResult['seed_bonus'] * $baseBonusFactor + $haremAddition * $haremFactor + $seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3); +$rowSpan = 1; +if ($haremFactor > 0) { + $rowSpan++; +} +if ($officialAdditionalFactor > 0) { + $rowSpan++; +} $summaryTable = ''; -$summaryTable .= ''; +$summaryTable .= ''; $summaryTable .= sprintf( - '', + '', $lang_mybonus['reward_type_basic'], - round($all_bonus,3), - '-', - round($all_bonus,3), + number_format($seedBonusResult['seed_bonus'],3), + $baseBonusFactor, + number_format($seedBonusResult['seed_bonus'],3), + $rowSpan, $totalBonus ); -if ($factor > 0) { +if ($haremFactor > 0) { $summaryTable .= sprintf( '', $lang_mybonus['reward_type_harem_addition'], - number_format($addition, 3), - number_format($factor * 100, 2) . '%', - number_format($addition * $factor, 3) + number_format($haremAddition, 3), + $haremFactor, + number_format($haremAddition * $haremFactor, 3) + ); +} +if ($officialAdditionalFactor > 0) { + $summaryTable .= sprintf( + '', + $lang_mybonus['reward_type_official_addition'], + number_format($seedBonusResult['official_bonus'], 3), + $officialAdditionalFactor, + number_format($seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3) ); } diff --git a/public/pic/bonusformulaa.svg b/public/pic/bonusformulaa.svg new file mode 100644 index 00000000..6b95be41 --- /dev/null +++ b/public/pic/bonusformulaa.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/settings.php b/public/settings.php index a7b746f0..3652c942 100644 --- a/public/settings.php +++ b/public/settings.php @@ -97,7 +97,7 @@ elseif ($action == 'savesettings_bonus') // save bonus 'addcomment','pollvote','offervote', 'funboxvote','saythanks','receivethanks','funboxreward','onegbupload','fivegbupload', 'tengbupload', 'ratiolimit','dlamountlimit','oneinvite','customtitle','vipstatus','bonusgift', 'basictax', 'taxpercentage', 'prolinkpoint', 'prolinktime', 'attendance_initial', 'attendance_step', 'attendance_max', 'cancel_hr', 'attendance_card', - 'harem_addition', 'hundredgbupload', 'tengbdownload', 'hundredgbdownload' + 'harem_addition', 'hundredgbupload', 'tengbdownload', 'hundredgbdownload', 'official_addition', 'official_tag', 'zero_bonus_tag', 'zero_bonus_factor', ); GetVar($validConfig); $BONUS = []; @@ -562,7 +562,18 @@ elseif ($action == 'bonussettings'){ print(""); tr($lang_settings['row_donor_gets_double'], $lang_settings['text_donor_gets']."".$lang_settings['text_times_as_many'],1); tr($lang_settings['row_basic_seeding_bonus'], $lang_settings['text_user_would_get']."".$lang_settings['text_bonus_points']."".$lang_settings['text_torrents_default'], 1); - tr($lang_settings['row_seeding_formula'], $lang_settings['text_bonus_formula_one']."
          \"A
          \"B
      ".$lang_settings['text_where']."
      • ".$lang_settings['text_bonus_formula_two']."
      • ".$lang_settings['text_bonus_formula_three']."".$lang_settings['text_bonus_formula_four']."
      • ".$lang_settings['text_bonus_formula_five']."
      • ".$lang_settings['text_bonus_formula_six']."".$lang_settings['text_bonus_formula_seven']."
      • ".$lang_settings['text_bonus_formula_eight']."
      • ".$lang_settings['text_bonus_formula_nine']."".$lang_settings['text_bonus_formula_ten']."
      • ".$lang_settings['text_bonus_formula_eleven']."".$lang_settings['text_bonus_formula_twelve']."
      \n", 1); + + $formulaLiArr = []; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_two']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_three']."".$lang_settings['text_bonus_formula_four']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_five']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_six']."".$lang_settings['text_bonus_formula_seven']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_zero_bonus_factor']."".$lang_settings['zero_bonus_factor_default']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_eight']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_nine']."".$lang_settings['text_bonus_formula_ten']."
    • "; + $formulaLiArr[] = "
    • ".$lang_settings['text_bonus_formula_eleven']."".$lang_settings['text_bonus_formula_twelve']."
    • "; + tr($lang_settings['row_seeding_formula'], $lang_settings['text_bonus_formula_one']."

          
          \"B
      ".$lang_settings['text_where']."
        ".implode("", $formulaLiArr)."
      ", 1); + print(""); tr($lang_settings['row_uploading_torrent'],$lang_settings['text_user_would_get']."".$lang_settings['text_uploading_torrent_note'], 1); tr($lang_settings['row_uploading_subtitle'],$lang_settings['text_user_would_get']."".$lang_settings['text_uploading_subtitle_note'], 1); @@ -576,7 +587,11 @@ elseif ($action == 'bonussettings'){ tr($lang_settings['row_funbox_stuff_reward'],$lang_settings['text_user_would_get']."".$lang_settings['text_funbox_stuff_reward_note'], 1); tr($lang_settings['row_promotion_link_click'],$lang_settings['text_user_would_get']."".$lang_settings['text_promotion_link_note_one']."".$lang_settings['text_promotion_link_note_two'], 1); tr($lang_settings['row_harem_addition'],$lang_settings['text_user_would_get_by_harem']."".$lang_settings['text_harem_addition_note'], 1); + tr($lang_settings['row_official_addition'],$lang_settings['text_user_would_get_by_official']."".$lang_settings['text_addition_addition_note'], 1); + $tagRep = new \App\Repositories\TagRepository(); + tr($lang_settings['row_official_tag'], $tagRep->buildSelect('official_tag', $BONUS["official_tag"] ?? '') . $lang_settings['text_official_tag_note'], 1); + tr($lang_settings['row_zero_bonus_tag'], $tagRep->buildSelect('zero_bonus_tag', $BONUS["zero_bonus_tag"] ?? '') . $lang_settings['text_zero_bonus_tag_note'], 1); print(""); tr($lang_settings['row_one_gb_credit'],$lang_settings['text_it_costs_user']."".$lang_settings['text_one_gb_credit_note'], 1); diff --git a/resources/lang/en/nexus.php b/resources/lang/en/nexus.php index d924ff86..8637dd30 100644 --- a/resources/lang/en/nexus.php +++ b/resources/lang/en/nexus.php @@ -2,4 +2,6 @@ return [ 'invalid_argument' => 'Invalid argument', + 'require_argument' => ':argument cannot be empty', + 'select_one_please' => 'Please select one', ]; diff --git a/resources/lang/zh_CN/nexus.php b/resources/lang/zh_CN/nexus.php index 3f518814..5b4c8ffa 100644 --- a/resources/lang/zh_CN/nexus.php +++ b/resources/lang/zh_CN/nexus.php @@ -3,4 +3,5 @@ return [ 'invalid_argument' => '参数错误', 'require_argument' => ':argument 不能为空', + 'select_one_please' => '请选择一项', ]; diff --git a/resources/lang/zh_TW/nexus.php b/resources/lang/zh_TW/nexus.php index 69a3f32b..6bc71b91 100644 --- a/resources/lang/zh_TW/nexus.php +++ b/resources/lang/zh_TW/nexus.php @@ -2,4 +2,6 @@ return [ 'invalid_argument' => '參數錯誤', + 'require_argument' => ':argument 不能為空', + 'select_one_please' => '請選擇一項', ]; From 5a187540b1d1732ea5042a2d3a326535cad96963 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 25 Sep 2022 16:49:56 +0800 Subject: [PATCH 20/59] show official addition only when had set official tag --- include/functions.php | 2 +- public/mybonus.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/functions.php b/include/functions.php index 0533b6a6..6cf786f5 100644 --- a/include/functions.php +++ b/include/functions.php @@ -5837,7 +5837,7 @@ function calculate_seed_bonus($uid, $torrentIdArr = null): array $tagGrouped[$tagItem['torrent_id']][$tagItem['tag_id']] = 1; } } - $officialTag = \App\Models\Setting::get('system.official_tag'); + $officialTag = \App\Models\Setting::get('bonus.official_tag'); $officialAdditionalFactor = \App\Models\Setting::get('bonus.official_addition'); $zeroBonusTag = \App\Models\Setting::get('bonus.zero_bonus_tag'); $zeroBonusFactor = \App\Models\Setting::get('bonus.zero_bonus_factor'); diff --git a/public/mybonus.php b/public/mybonus.php index 9d78b7cc..926648ce 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -461,8 +461,9 @@ $A = $seedBonusResult['A']; $width = $percent * 4; print("\"".$percent."%\"
      '.$lang_mybonus['reward_type'].''.$lang_mybonus['bonus_base'].''.$lang_mybonus['addition'].''.$lang_mybonus['got_bonus'].''.$lang_mybonus['total'].'
      '.$lang_mybonus['reward_type'].''.$lang_mybonus['bonus_base'].''.$lang_mybonus['factor'].''.$lang_mybonus['got_bonus'].''.$lang_mybonus['total'].'
      %s%s%s%s%s
      %s%s%s%s%s
      %s%s%s%s
      %s%s%s%s
      ".$lang_settings['text_bonus_by_seeding']."
      ".$lang_settings['text_misc_ways_get_bonus']."
      ".$lang_settings['text_things_cost_bonus']."
      "); - $officialAdditionalFactor = get_setting('bonus.official_addition'); - if ($officialAdditionalFactor > 0) { + $officialAdditionalFactor = get_setting('bonus.official_addition', 0); + $officialTag = get_setting('bonus.official_tag'); + if ($officialAdditionalFactor > 0 && $officialTag) { print("

      ".$lang_mybonus['text_get_by_seeding_official']."

      "); print("
        "); print("
      • ".$lang_mybonus['official_calculate_method']."
      • "); @@ -482,7 +483,7 @@ $rowSpan = 1; if ($haremFactor > 0) { $rowSpan++; } -if ($officialAdditionalFactor > 0) { +if ($officialAdditionalFactor > 0 && $officialTag) { $rowSpan++; } $summaryTable = ''; @@ -505,7 +506,7 @@ if ($haremFactor > 0) { number_format($haremAddition * $haremFactor, 3) ); } -if ($officialAdditionalFactor > 0) { +if ($officialAdditionalFactor > 0 && $officialTag) { $summaryTable .= sprintf( '', $lang_mybonus['reward_type_official_addition'], From c3321d0afc50ac9ce455029a30f4411ec486696f Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 25 Sep 2022 17:17:08 +0800 Subject: [PATCH 21/59] official addition do not include the minimum --- include/functions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/functions.php b/include/functions.php index 6cf786f5..41451cf0 100644 --- a/include/functions.php +++ b/include/functions.php @@ -5867,7 +5867,8 @@ function calculate_seed_bonus($uid, $torrentIdArr = null): array if ($count > $maxseeding_bonus) $count = $maxseeding_bonus; $seed_bonus = $seed_points = $valuetwo * atan($A / $l_bonus) + ($perseeding_bonus * $count); - $official_bonus = $valuetwo * atan($official_a / $l_bonus) + ($perseeding_bonus * $count); + //Official addition don't think about the minimum value + $official_bonus = $valuetwo * atan($official_a / $l_bonus); $result = compact('seed_points','seed_bonus', 'A', 'count', 'torrent_peer_count', 'official_a', 'official_bonus'); $result['donor_times'] = $donortimes_bonus; $result['official_additional_factor'] = $officialAdditionalFactor; From 3ea23d337bd94a4a7949984078cabba51de3726e Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 26 Sep 2022 17:42:51 +0800 Subject: [PATCH 22/59] improve mybonus page + upload deny when approval deny too much --- include/constants.php | 2 +- include/functions.php | 2 +- lang/chs/lang_mybonus.php | 6 +- lang/chs/lang_settings.php | 2 + lang/chs/lang_upload.php | 1 + lang/cht/lang_mybonus.php | 7 ++- lang/cht/lang_settings.php | 2 + lang/cht/lang_upload.php | 1 + lang/en/lang_mybonus.php | 6 +- lang/en/lang_settings.php | 2 + lang/en/lang_upload.php | 1 + nexus/Install/settings.default.php | 1 + public/mybonus.php | 96 +++++++++++++----------------- public/settings.php | 4 +- public/upload.php | 7 ++- 15 files changed, 77 insertions(+), 63 deletions(-) diff --git a/include/constants.php b/include/constants.php index 35c9e939..4bf2abdc 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ count(); foreach ($harems as $harem) { $result = calculate_seed_bonus($harem->id); - $addition += $result['seed_bonus']; + $addition += $result['seed_points']; } do_log("[HAREM_ADDITION], user: $uid, haremsCount: $haremsCount ,addition: $addition"); return $addition; diff --git a/lang/chs/lang_mybonus.php b/lang/chs/lang_mybonus.php index f6b04e0f..4f7f4b6b 100644 --- a/lang/chs/lang_mybonus.php +++ b/lang/chs/lang_mybonus.php @@ -145,10 +145,14 @@ $lang_mybonus = array 'reward_type_harem_addition' => '后宫加成', 'bonus_base' => '基础魔力', 'lock_text' => '系统限制 %s 秒内只能点击交换按钮一次!', - 'text_get_by_seeding_official' => '官种每小时将额外得到如下的魔力值', + 'text_get_by_seeding_official' => '官种加成每小时将额外得到如下的魔力值', 'official_calculate_method' => '官种奖励计算公式同上,只是仅针对官种进行计算', 'official_tag_bonus_additional_factor' => '最终奖励为计算所得官种奖励乘以官种系数,当前官种系数为: ', 'reward_type_official_addition' => '官种加成', + 'text_get_by_harem' => '后宫加成每小时将额外得到如下的魔力值', + 'harem_additional_desc' => '后宫只考虑直属后宫。每个后宫加成值可在此查看', + 'harem_additional_factor' => '所得奖励为全部后宫的时魔(不考虑加成)之和,乘以后宫加成系数,当前值为:', + 'text_bonus_summary' => '每小时获得的合计魔力值', ); ?> diff --git a/lang/chs/lang_settings.php b/lang/chs/lang_settings.php index 8ba8e403..e87e3cc6 100644 --- a/lang/chs/lang_settings.php +++ b/lang/chs/lang_settings.php @@ -788,6 +788,8 @@ $lang_settings = array 'text_official_tag_note' => '。带此标签的种子为官种', 'row_zero_bonus_tag' => '零魔标签', 'text_zero_bonus_tag_note' => '。带此标签的种子为零魔种子', + 'row_upload_deny_approval_deny_count' => '拒绝发布审核不通过数', + 'text_upload_deny_approval_deny_count_note' => "当审核不通过的种子数大于等于此数值时,不允许发布。设置为 '0' 不使用此规则", ); ?> diff --git a/lang/chs/lang_upload.php b/lang/chs/lang_upload.php index 773cc5af..172beca0 100644 --- a/lang/chs/lang_upload.php +++ b/lang/chs/lang_upload.php @@ -41,6 +41,7 @@ $lang_upload = array 'text_english_title' => "英文名:", 'text_titles_note' => "(如果英文名不存在,使用拼音或不填写)", 'fill_quality' => '填写质量', + 'approval_deny_reach_upper_limit' => '当前审核被拒绝的种子数:%s 达到上限,不允许发布。', ); ?> diff --git a/lang/cht/lang_mybonus.php b/lang/cht/lang_mybonus.php index e77b7aad..c71668e2 100644 --- a/lang/cht/lang_mybonus.php +++ b/lang/cht/lang_mybonus.php @@ -145,11 +145,14 @@ $lang_mybonus = array 'reward_type_harem_addition' => '後宮加成', 'bonus_base' => '基礎魔力', 'lock_text' => '系統限製 %s 秒內只能點擊交換按鈕一次!', - 'text_get_by_seeding_official' => '官種每小時將額外得到如下的魔力值', + 'text_get_by_seeding_official' => '官種加成每小時將額外得到如下的魔力值', 'official_calculate_method' => '官種獎勵計算公式同上,只是僅針對官種進行計算', 'official_tag_bonus_additional_factor' => '最終獎勵為計算所得官種獎勵乘以官種系數,當前官種系數為: ', 'reward_type_official_addition' => '官種加成', - + 'text_get_by_harem' => '後宮加成每小時將額外得到如下的魔力值', + 'harem_additional_desc' => '後宮只考慮直屬後宮。每個後宮加成值可在此查看', + 'harem_additional_factor' => '所得獎勵為全部後宮的時魔(不考慮加成)之和,乘以後宮加成系數,當前值為:', + 'text_bonus_summary' => '每小時獲得的合計魔力值', ); ?> diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index b498d177..e0190c52 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -788,6 +788,8 @@ $lang_settings = array 'text_official_tag_note' => '。帶此標簽的種子為官種', 'row_zero_bonus_tag' => '零魔標簽', 'text_zero_bonus_tag_note' => '。帶此標簽的種子為零魔種子', + 'row_upload_deny_approval_deny_count' => '拒絕發布審核不通過數', + 'text_upload_deny_approval_deny_count_note' => "當審核不通過的種子數大於等於此數值時,不允許發布。設置為 '0' 不使用此規則", ); ?> diff --git a/lang/cht/lang_upload.php b/lang/cht/lang_upload.php index 705d00ca..d8e870b1 100644 --- a/lang/cht/lang_upload.php +++ b/lang/cht/lang_upload.php @@ -41,6 +41,7 @@ $lang_upload = array 'text_english_title' => "英文名:", 'text_titles_note' => "(如果英文名不存在,請使用拼音或不填寫)", 'fill_quality' => '填寫質量', + 'approval_deny_reach_upper_limit' => '當前審核被拒絕的種子數:%s 達到上限,不允許發布。', ); ?> diff --git a/lang/en/lang_mybonus.php b/lang/en/lang_mybonus.php index 995ae057..f42e096d 100644 --- a/lang/en/lang_mybonus.php +++ b/lang/en/lang_mybonus.php @@ -97,7 +97,7 @@ where
        • A is an intermediate variable
        • Ti is the i< 'text_bonus_formula_three' => "
        • B is the number of karma points gained by seeding in an hour
        • B0 is a parameter, which stands for the maximum bonus points per hour a user can get by seeding. B0 = ", 'text_bonus_formula_four' => "
        • L is a parameter. L = ", 'text_bonus_formula_five' => "
        In a nutshell, you can get more bonus by seeding less-seeded and larger torrents.", - 'text_bonus_formula_wi' => "
      • Wi is the ith torrent's weight, default is 1, zero torrent is ", + 'text_bonus_formula_wi' => "
      • Wi is the ith torrent's weight, default is 1, zero bonus torrent is ", 'text_user_with_ratio_above' => "User with ratio above ", 'text_and_uploaded_amount_above' => " and uploaded amount above ", 'text_cannot_exchange_uploading' => " GB cannot exchange for more uploading credit.", @@ -149,6 +149,10 @@ where
        • A is an intermediate variable
        • Ti is the i< 'official_calculate_method' => 'The formula for calculating the official reward is the same as above, but only for the official type', 'official_tag_bonus_additional_factor' => 'The final reward is the calculated official type reward multiplied by the official type factor, the current official type factor is: ', 'reward_type_official_addition' => 'Official addition', + 'text_get_by_harem' => 'The harem addition will give the following additional bonus value per hour', + 'harem_additional_desc' => "Only direct harems will be considered for the harem. Each harem's bonus addition value can be viewed here", + 'harem_additional_factor' => 'The reward obtained is the sum of the hourly bonus of all the harems (regardless of the addition), multiplied by the harem bonus factor, with the current value of ', + 'text_bonus_summary' => 'Total bonus gained per hour', ); ?> diff --git a/lang/en/lang_settings.php b/lang/en/lang_settings.php index a67f96c4..d83efd55 100644 --- a/lang/en/lang_settings.php +++ b/lang/en/lang_settings.php @@ -788,6 +788,8 @@ $lang_settings = array 'text_official_tag_note' => '. Torrents with this tag are official torrents', 'row_zero_bonus_tag' => 'Zero bonus tag', 'text_zero_bonus_tag_note' => '. Torrents with this tag are zero bonus torrents', + 'row_upload_deny_approval_deny_count' => 'Refuse to upload approval deny count', + 'text_upload_deny_approval_deny_count_note' => "When the number of torrents approval deny is greater than or equal to this value, publishing is not allowed. Set to '0' to not use this rule", ); ?> diff --git a/lang/en/lang_upload.php b/lang/en/lang_upload.php index 341b9f8f..ae6125d1 100644 --- a/lang/en/lang_upload.php +++ b/lang/en/lang_upload.php @@ -41,6 +41,7 @@ $lang_upload = array 'text_english_title' => "English Name:", 'text_titles_note' => "(If no English Name exists, use pinyin or leave it blank)", 'fill_quality' => 'Fill quality', + 'approval_deny_reach_upper_limit' => 'The number of torrents whose current approval was denied: %s reached the upper limit and is not allowed to be upload.', ); ?> diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index 33514956..1b45c121 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -92,6 +92,7 @@ return array ( 'show_top_uploader' => 'no', 'imdb_language' => 'en-US', 'offer_skip_approved_count' => 5, + 'upload_deny_approval_deny_count' => 2, ), 'smtp' => array ( diff --git a/public/mybonus.php b/public/mybonus.php index 926648ce..e7ac933d 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -426,51 +426,10 @@ if ($donortimes_bonus) print("
        "); -// $sqrtof2 = sqrt(2); -// $logofpointone = log(0.1); -// $valueone = $logofpointone / $tzero_bonus; -// $pi = 3.141592653589793; -// $valuetwo = $bzero_bonus * ( 2 / $pi); -// $valuethree = $logofpointone / ($nzero_bonus - 1); -// $timenow = strtotime(date("Y-m-d H:i:s")); -// $sectoweek = 7*24*60*60; -// $A = 0; -// $count = 0; -// $torrentres = sql_query("select torrents.id, torrents.added, torrents.size, torrents.seeders from torrents LEFT JOIN peers ON peers.torrent = torrents.id WHERE peers.userid = $CURUSER[id] AND peers.seeder ='yes' GROUP BY torrents.id") or sqlerr(__FILE__, __LINE__); -// while ($torrent = mysql_fetch_array($torrentres)) -// { -// $weeks_alive = ($timenow - strtotime($torrent['added'])) / $sectoweek; -// $gb_size = $torrent['size'] / 1073741824; -// $temp = (1 - exp($valueone * $weeks_alive)) * $gb_size * (1 + $sqrtof2 * exp($valuethree * ($torrent['seeders'] - 1))); -// $A += $temp; -// $count++; -// } -// if ($count > $maxseeding_bonus) -// $count = $maxseeding_bonus; -// $all_bonus = $valuetwo * atan($A / $l_bonus) + ($perseeding_bonus * $count); - $seedBonusResult = calculate_seed_bonus($CURUSER['id']); $A = $seedBonusResult['A']; - - $percent = $seedBonusResult['seed_bonus'] * 100 / ($bzero_bonus + $perseeding_bonus * $maxseeding_bonus); - print("
        ".$lang_mybonus['text_you_are_currently_getting'].round($seedBonusResult['seed_bonus'],3).$lang_mybonus['text_point'].add_s($seedBonusResult['seed_bonus']).$lang_mybonus['text_per_hour']." (A = ".round($A,1).")
      • %s%s%s%s
        "); - - if ($percent <= 30) $loadpic = "loadbarred"; - elseif ($percent <= 60) $loadpic = "loadbaryellow"; - else $loadpic = "loadbargreen"; - $width = $percent * 4; - print("\"".$percent."%\"
        "); - - $officialAdditionalFactor = get_setting('bonus.official_addition', 0); - $officialTag = get_setting('bonus.official_tag'); - if ($officialAdditionalFactor > 0 && $officialTag) { - print("

        ".$lang_mybonus['text_get_by_seeding_official']."

        "); - print("
          "); - print("
        • ".$lang_mybonus['official_calculate_method']."
        • "); - print("
        • ".$lang_mybonus['official_tag_bonus_additional_factor'].$officialAdditionalFactor."
        • "); - print("
        "); - } - +$officialAdditionalFactor = get_setting('bonus.official_addition', 0); +$officialTag = get_setting('bonus.official_tag'); $haremFactor = get_setting('bonus.harem_addition'); $haremAddition = calculate_harem_addition($CURUSER['id']); $isDonor = is_donor($CURUSER); @@ -478,13 +437,28 @@ $baseBonusFactor = 1; if ($isDonor) { $baseBonusFactor = $donortimes_bonus; } -$totalBonus = number_format($seedBonusResult['seed_bonus'] * $baseBonusFactor + $haremAddition * $haremFactor + $seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3); +$baseBonus = $seedBonusResult['seed_bonus'] * $baseBonusFactor; +$totalBonus = number_format( $baseBonus + $haremAddition * $haremFactor + $seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3); + + +$percent = $seedBonusResult['seed_bonus'] * 100 / ($bzero_bonus + $perseeding_bonus * $maxseeding_bonus); +print("
        ".$lang_mybonus['text_you_are_currently_getting'].round($seedBonusResult['seed_bonus'],3).$lang_mybonus['text_point'].add_s($seedBonusResult['seed_bonus']).$lang_mybonus['text_per_hour']." (A = ".round($A,1).")
        "); + +if ($percent <= 30) $loadpic = "loadbarred"; +elseif ($percent <= 60) $loadpic = "loadbaryellow"; +else $loadpic = "loadbargreen"; +$width = $percent * 4; +print("\"".$percent."%\"
        "); + $rowSpan = 1; +$hasHaremAddition = $hasOfficialAddition = false; if ($haremFactor > 0) { $rowSpan++; + $hasHaremAddition = true; } if ($officialAdditionalFactor > 0 && $officialTag) { $rowSpan++; + $hasOfficialAddition = true; } $summaryTable = ''; $summaryTable .= ''; @@ -493,20 +467,17 @@ $summaryTable .= sprintf( $lang_mybonus['reward_type_basic'], number_format($seedBonusResult['seed_bonus'],3), $baseBonusFactor, - number_format($seedBonusResult['seed_bonus'],3), + number_format($baseBonus,3), $rowSpan, $totalBonus ); -if ($haremFactor > 0) { - $summaryTable .= sprintf( - '', - $lang_mybonus['reward_type_harem_addition'], - number_format($haremAddition, 3), - $haremFactor, - number_format($haremAddition * $haremFactor, 3) - ); -} -if ($officialAdditionalFactor > 0 && $officialTag) { + +if ($hasOfficialAddition) { + print("

        ".$lang_mybonus['text_get_by_seeding_official']."

        "); + print("
          "); + print("
        • ".$lang_mybonus['official_calculate_method']."
        • "); + print("
        • ".$lang_mybonus['official_tag_bonus_additional_factor'].$officialAdditionalFactor."
        • "); + print("
        "); $summaryTable .= sprintf( '', $lang_mybonus['reward_type_official_addition'], @@ -516,8 +487,23 @@ if ($officialAdditionalFactor > 0 && $officialTag) { ); } +if ($hasHaremAddition) { + print("

        ".$lang_mybonus['text_get_by_harem']."

        "); + print("
          "); + print("
        • ".sprintf($lang_mybonus['harem_additional_desc'], $CURUSER['id'])."
        • "); + print("
        • ".$lang_mybonus['harem_additional_factor'].$haremFactor."
        • "); + print("
        "); + $summaryTable .= sprintf( + '', + $lang_mybonus['reward_type_harem_addition'], + number_format($haremAddition, 3), + $haremFactor, + number_format($haremAddition * $haremFactor, 3) + ); +} $summaryTable .= '
        '.$lang_mybonus['reward_type'].''.$lang_mybonus['bonus_base'].''.$lang_mybonus['factor'].''.$lang_mybonus['got_bonus'].''.$lang_mybonus['total'].'
        %s%s%s%s
        %s%s%s%s
        %s%s%s%s
        '; +print("

        ".$lang_mybonus['text_bonus_summary']."

        "); print '
        '.$summaryTable.'
        '; print("

        ".$lang_mybonus['text_other_things_get_bonus']."

        "); diff --git a/public/settings.php b/public/settings.php index 3652c942..453dc372 100644 --- a/public/settings.php +++ b/public/settings.php @@ -41,7 +41,8 @@ if ($action == 'savesettings_main') // save main 'showpolls','showstats','showlastxtorrents', 'showtrackerload','showshoutbox','showfunbox','showoffer','sptime','showhelpbox','enablebitbucket', 'smalldescription','altname','extforum','extforumurl','defaultlang','defstylesheet', 'donation','spsct','browsecat','specialcat','waitsystem', 'maxdlsystem','bitbucket','torrentnameprefix', 'showforumstats','verification','invite_count','invite_timeout', 'seeding_leeching_time_calc_start', - 'startsubid', 'logo', 'showlastxforumposts', 'enable_technical_info', 'site_language_enabled', 'show_top_uploader', 'imdb_language', 'offer_skip_approved_count' + 'startsubid', 'logo', 'showlastxforumposts', 'enable_technical_info', 'site_language_enabled', 'show_top_uploader', 'imdb_language', 'offer_skip_approved_count', + 'upload_deny_approval_deny_count' ); GetVar($validConfig); $MAIN = []; @@ -871,6 +872,7 @@ JS; tr($lang_settings['row_offer_vote_timeout']," ".$lang_settings['text_offer_vote_timeout_note'], 1); tr($lang_settings['row_offer_upload_timeout']," ".$lang_settings['text_offer_upload_timeout_note'], 1); tr($lang_settings['row_offer_skip_approved_count']," ".$lang_settings['text_offer_skip_approved_count_note'], 1); + tr($lang_settings['row_upload_deny_approval_deny_count']," ".$lang_settings['text_upload_deny_approval_deny_count_note'], 1); tr($lang_settings['row_max_subtitle_size']," ". $lang_settings['text_max_subtitle_size_note'], 1); tr($lang_settings['row_posts_per_page']," ".$lang_settings['text_posts_per_page_note'], 1); diff --git a/public/upload.php b/public/upload.php index f686d8cb..633cd7c0 100644 --- a/public/upload.php +++ b/public/upload.php @@ -14,10 +14,15 @@ if ($enableoffer == 'yes') else $has_allowed_offer = 0; $uploadfreely = user_can_upload("torrents"); $offerSkipApprovedCount = get_setting('main.offer_skip_approved_count'); -do_log("uploadfreely: $uploadfreely, has_allowed_offer: $has_allowed_offer, offerSkipApprovedCount: $offerSkipApprovedCount"); +$uploadDenyApprovalDenyCount = get_setting('main.upload_deny_approval_deny_count'); +$approvalDenyCount = \App\Models\Torrent::query()->where('owner', $CURUSER['id'])->where('approval_status', \App\Models\Torrent::APPROVAL_STATUS_DENY)->count(); +do_log("uploadfreely: $uploadfreely, has_allowed_offer: $has_allowed_offer, offerSkipApprovedCount: $offerSkipApprovedCount, uploadDenyApprovalDenyCount: $uploadDenyApprovalDenyCount, approvalDenyCount: $approvalDenyCount"); $allowtorrents = ($has_allowed_offer || $uploadfreely || ($userInfo->offer_allowed_count >= $offerSkipApprovedCount)); $allowspecial = user_can_upload("music"); +if ($uploadDenyApprovalDenyCount > 0 && $approvalDenyCount >= $uploadDenyApprovalDenyCount) { + stderr($lang_upload['std_sorry'],sprintf($lang_upload['approval_deny_reach_upper_limit'], $uploadDenyApprovalDenyCount),false); +} if (!$allowtorrents && !$allowspecial) stderr($lang_upload['std_sorry'],$lang_upload['std_please_offer'],false); $allowtwosec = ($allowtorrents && $allowspecial); From 10588537b17696ac697b76f92e559ebbad873142 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Tue, 27 Sep 2022 22:06:05 +0800 Subject: [PATCH 23/59] fix suggest xss + nfo view style default --- app/Models/Torrent.php | 10 ++++++++-- include/constants.php | 2 +- include/functions.php | 6 +++++- lang/chs/lang_settings.php | 1 + lang/cht/lang_settings.php | 1 + lang/en/lang_settings.php | 1 + nexus/Install/settings.default.php | 1 + public/details.php | 4 ++-- public/settings.php | 14 +++++++++++++- public/torrents.php | 2 +- public/viewnfo.php | 10 ++++++---- 11 files changed, 40 insertions(+), 12 deletions(-) diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 49726ed1..5f259a8b 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -19,8 +19,6 @@ class Torrent extends NexusModel 'times_completed', 'approval_status', 'banned', 'visible', 'pos_state_until', ]; - private static $globalPromotionState; - const VISIBLE_YES = 'yes'; const VISIBLE_NO = 'no'; @@ -156,6 +154,14 @@ class Torrent extends NexusModel ], ]; + const NFO_VIEW_STYLE_DOS = 'magic'; + const NFO_VIEW_STYLE_WINDOWS = 'latin-1'; + + public static array $nfoViewStyles = [ + self::NFO_VIEW_STYLE_DOS => ['text' => 'DOS-vy'], + self::NFO_VIEW_STYLE_WINDOWS => ['text' => 'Windows-vy'], + ]; + public function getPickInfoAttribute() { $info = self::$pickTypes[$this->picktype] ?? null; diff --git a/include/constants.php b/include/constants.php index 4bf2abdc..c16d9eb8 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ '。带此标签的种子为零魔种子', 'row_upload_deny_approval_deny_count' => '拒绝发布审核不通过数', 'text_upload_deny_approval_deny_count_note' => "当审核不通过的种子数大于等于此数值时,不允许发布。设置为 '0' 不使用此规则", + 'row_nfo_view_style_default' => 'NFO 默认查看样式', ); ?> diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index e0190c52..ee0df495 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -790,6 +790,7 @@ $lang_settings = array 'text_zero_bonus_tag_note' => '。帶此標簽的種子為零魔種子', 'row_upload_deny_approval_deny_count' => '拒絕發布審核不通過數', 'text_upload_deny_approval_deny_count_note' => "當審核不通過的種子數大於等於此數值時,不允許發布。設置為 '0' 不使用此規則", + 'row_nfo_view_style_default' => 'NFO 默認查看樣式', ); ?> diff --git a/lang/en/lang_settings.php b/lang/en/lang_settings.php index d83efd55..10168383 100644 --- a/lang/en/lang_settings.php +++ b/lang/en/lang_settings.php @@ -790,6 +790,7 @@ $lang_settings = array 'text_zero_bonus_tag_note' => '. Torrents with this tag are zero bonus torrents', 'row_upload_deny_approval_deny_count' => 'Refuse to upload approval deny count', 'text_upload_deny_approval_deny_count_note' => "When the number of torrents approval deny is greater than or equal to this value, publishing is not allowed. Set to '0' to not use this rule", + 'row_nfo_view_style_default' => 'NFO view style default', ); ?> diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index 1b45c121..99330be6 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -347,6 +347,7 @@ return array ( 'claim_reach_standard_uploaded' => \App\Models\Claim::STANDARD_UPLOADED_TIMES, 'approval_status_icon_enabled' => 'no', 'approval_status_none_visible' => 'yes', + 'nfo_view_style_default' => \App\Models\Torrent::NFO_VIEW_STYLE_DOS, ), 'attachment' => array ( diff --git a/public/details.php b/public/details.php index 5ed0672c..9aa204f6 100644 --- a/public/details.php +++ b/public/details.php @@ -300,10 +300,10 @@ JS; if (user_can('viewnfo') && $CURUSER['shownfo'] != 'no' && $row["nfosz"] > 0){ if (!$nfo = $Cache->get_value('nfo_block_torrent_id_'.$id)){ - $nfo = code($row["nfo"], $view == "magic"); + $nfo = code($row["nfo"], get_setting('torrent.nfo_view_style_default')); $Cache->cache_value('nfo_block_torrent_id_'.$id, $nfo, 604800); } - tr("\"Show/Hide\" ".$lang_details['text_nfo']."
        ". $lang_details['text_view_nfo']. "", "
        ".$nfo."
        \n", 1); + tr("\"Show/Hide\" ".$lang_details['text_nfo']."
        ". $lang_details['text_view_nfo']. "", "
        ".$nfo."
        \n", 1); } if ($imdb_id && $showextinfo['imdb'] == 'yes' && $CURUSER['showimdb'] != 'no') diff --git a/public/settings.php b/public/settings.php index 453dc372..7b70aa36 100644 --- a/public/settings.php +++ b/public/settings.php @@ -156,7 +156,8 @@ elseif($action == 'savesettings_torrent') // save account 'twoupbecome','twoupfreebecome', 'twouphalfleechbecome','normalbecome','uploaderdouble','deldeadtorrent', 'randomthirtypercentdown', 'thirtypercentleechbecome', 'expirethirtypercentleech', 'sticky_first_level_background_color', 'sticky_second_level_background_color', 'download_support_passkey', 'claim_enabled', 'claim_torrent_ttl', 'claim_torrent_user_counts_up_limit', 'claim_user_torrent_counts_up_limit', 'claim_remove_deduct_user_bonus', - 'claim_give_up_deduct_user_bonus', 'claim_bonus_multiplier', 'claim_reach_standard_seed_time', 'claim_reach_standard_uploaded', 'approval_status_icon_enabled', 'approval_status_none_visible' + 'claim_give_up_deduct_user_bonus', 'claim_bonus_multiplier', 'claim_reach_standard_seed_time', 'claim_reach_standard_uploaded', 'approval_status_icon_enabled', 'approval_status_none_visible', + 'nfo_view_style_default', ); $validConfig = apply_filter('setting_valid_config', $validConfig); GetVar($validConfig); @@ -710,6 +711,17 @@ elseif ($action == 'torrentsettings') yesorno($lang_settings['row_download_support_passkey'], 'download_support_passkey', $TORRENT["download_support_passkey"], $lang_settings['text_download_support_passkey_note']); yesorno($lang_settings['row_approval_status_icon_enabled'], 'approval_status_icon_enabled', $TORRENT["approval_status_icon_enabled"], $lang_settings['text_approval_status_icon_enabled_note']); yesorno($lang_settings['row_approval_status_none_visible'], 'approval_status_none_visible', $TORRENT["approval_status_none_visible"], $lang_settings['text_approval_status_none_visible_note']); + + $nfoViewStyleRadio = ''; + $name = 'nfo_view_style_default'; + foreach (\App\Models\Torrent::$nfoViewStyles as $style => $info) { + $nfoViewStyleRadio .= sprintf( + '', + $name, $style, $TORRENT[$name] == $style ? ' checked' : '', $info['text'] + ); + } + tr($lang_settings['row_' . $name], $nfoViewStyleRadio, 1); + yesorno($lang_settings['row_promotion_rules'], 'prorules', $TORRENT["prorules"], $lang_settings['text_promotion_rules_note']); tr($lang_settings['row_random_promotion'], $lang_settings['text_random_promotion_note_one']."
        • ".$lang_settings['text_halfleech_chance_becoming']."
        • ".$lang_settings['text_free_chance_becoming']."
        • ".$lang_settings['text_twoup_chance_becoming']."
        • ".$lang_settings['text_freetwoup_chance_becoming']."
        • ".$lang_settings['text_twouphalfleech_chance_becoming']."
        • ".$lang_settings['text_thirtypercentleech_chance_becoming']."
        ".$lang_settings['text_random_promotion_note_two'], 1); tr($lang_settings['row_large_torrent_promotion'], $lang_settings['text_torrent_larger_than']."".$lang_settings['text_gb_promoted_to']."".$lang_settings['text_by_system_upon_uploading']."
        ".$lang_settings['text_large_torrent_promotion_note'], 1); diff --git a/public/torrents.php b/public/torrents.php index d83b43fe..4ab1e8b7 100644 --- a/public/torrents.php +++ b/public/torrents.php @@ -1129,7 +1129,7 @@ if (!$Cache->get_page()){ $hotsearch = ""; while ($searchrow = mysql_fetch_assoc($searchres)) { - $hotsearch .= "" . $searchrow["keywords"] . "  "; + $hotsearch .= "" . htmlspecialchars($searchrow["keywords"]) . "  "; $hotcount += mb_strlen($searchrow["keywords"],"UTF-8"); if ($hotcount > 60) break; diff --git a/public/viewnfo.php b/public/viewnfo.php index c63fcd91..9efee758 100644 --- a/public/viewnfo.php +++ b/public/viewnfo.php @@ -27,12 +27,14 @@ if ($view == "latin-1" || $view == "fonthack") { // Do not convert from ibm-437, read bytes as is. // NOTICE: TBSource specifies Latin-1 encoding in include/bittorrent.php: // stdhead() -$nfo = htmlspecialchars(($a["nfo"])); +//$nfo = htmlspecialchars(($a["nfo"])); +$nfo = code($a["nfo"], $view); } else { // Convert from ibm-437 to html unicode entities. // take special care of Swedish letters if in magic view. -$nfo = code($a["nfo"], $view == "magic"); +//$nfo = code($a["nfo"], $view == "magic"); +$nfo = code($a["nfo"], $view); } stdhead($lang_viewnfo['head_view_nfo']); @@ -65,14 +67,14 @@ if ($view == "fonthack") { // Please notice: MS LineDraw's glyphs are included in the Courier New font // as of Courier New version 2.0, but uses the correct mappings instead. // http://support.microsoft.com/kb/q179422/ -print("
        ");
        +print("
        ");
         }
         else {
         // IE6.0 need to know which font to use, Mozilla can figure it out in its own
         // (windows firefox at least)
         // Anything else than 'Courier New' looks pretty broken.
         // 'Lucida Console', 'FixedSys'
        -print("
        ");
        +print("
        ");
         }
         // Writes the (eventually modified) nfo data to output, first formating urls.
         print(format_urls($nfo));
        
        From 65ba6442b1473e2bd17e7eb916a08c5b4fae0022 Mon Sep 17 00:00:00 2001
        From: xiaomlove 
        Date: Tue, 27 Sep 2022 22:25:23 +0800
        Subject: [PATCH 24/59] fix testip
        
        ---
         public/testip.php | 2 +-
         1 file changed, 1 insertion(+), 1 deletion(-)
        
        diff --git a/public/testip.php b/public/testip.php
        index 341b2684..90606199 100644
        --- a/public/testip.php
        +++ b/public/testip.php
        @@ -29,7 +29,7 @@ if ($ip)
         	    $banstable .= "
      $first$last$comment
      \n"; - stderr("Result", "
      The IP address ". htmlspecialchars($ip) ." is banned:

      ". htmlspecialchars($banstable) ."

      "); + stderr("Result", "
      The IP address ". $ip ." is banned:

      ". $banstable ."

      ", false); } } stdhead(); From 6de5cb2f2167cecc236b0c3229ab3bac3d51d52c Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 1 Oct 2022 00:11:22 +0800 Subject: [PATCH 25/59] support plugin nexusphp-hit-and-run --- app/Console/Commands/Test.php | 4 +- .../SettingResource/Pages/EditSetting.php | 23 ++-- app/Models/HitAndRun.php | 53 +++++++- app/Models/SearchBox.php | 23 ++++ app/Models/Torrent.php | 3 +- app/Repositories/HitAndRunRepository.php | 114 +++++++++++++----- app/Repositories/TrackerRepository.php | 3 +- include/constants.php | 2 +- include/functions.php | 9 +- nexus/Imdb/Imdb.php | 3 +- public/announce.php | 9 +- public/details.php | 2 +- public/edit.php | 9 +- public/myhr.php | 7 +- public/takeedit.php | 15 +-- public/takeupload.php | 4 +- public/upload.php | 8 +- resources/lang/en/searchbox.php | 4 + resources/lang/zh_CN/searchbox.php | 4 + resources/lang/zh_TW/searchbox.php | 4 + 20 files changed, 222 insertions(+), 81 deletions(-) diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index b84d6d05..13b3ba74 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -14,6 +14,7 @@ use App\Models\HitAndRun; use App\Models\Medal; use App\Models\Peer; use App\Models\SearchBox; +use App\Models\Setting; use App\Models\Snatch; use App\Models\Tag; use App\Models\Torrent; @@ -88,8 +89,7 @@ class Test extends Command */ public function handle() { - $rep = new ToolRepository(); - $r = $rep->transfer('C:\Users\CHENYU~1\AppData\Local\Temp/nexusphp.v1.5.beta5.20120707.web.20220918.053953.zip', 0); + $r = strstr('hr.*', '.', true); dd($r); } diff --git a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php index 95b8f914..3993aa59 100644 --- a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php +++ b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php @@ -76,6 +76,7 @@ class EditSetting extends Page implements Forms\Contracts\HasForms } } Setting::query()->upsert($data, ['name'], ['value']); + do_action("nexus_setting_update"); clear_setting_cache(); Filament::notify('success', __('filament::resources/pages/edit-record.messages.saved'), true); } @@ -85,13 +86,9 @@ class EditSetting extends Page implements Forms\Contracts\HasForms $tabs = []; $tabs[] = Forms\Components\Tabs\Tab::make(__('label.setting.hr.tab_header')) ->id('hr') - ->schema([ - Forms\Components\Radio::make('hr.mode')->options(HitAndRun::listModes(true))->inline(true)->label(__('label.setting.hr.mode')), - Forms\Components\TextInput::make('hr.inspect_time')->helperText(__('label.setting.hr.inspect_time_help'))->label(__('label.setting.hr.inspect_time'))->integer(), - Forms\Components\TextInput::make('hr.seed_time_minimum')->helperText(__('label.setting.hr.seed_time_minimum_help'))->label(__('label.setting.hr.seed_time_minimum'))->integer(), - Forms\Components\TextInput::make('hr.ignore_when_ratio_reach')->helperText(__('label.setting.hr.ignore_when_ratio_reach_help'))->label(__('label.setting.hr.ignore_when_ratio_reach'))->integer(), - Forms\Components\TextInput::make('hr.ban_user_when_counts_reach')->helperText(__('label.setting.hr.ban_user_when_counts_reach_help'))->label(__('label.setting.hr.ban_user_when_counts_reach'))->integer(), - ])->columns(2); + ->schema($this->getHitAndRunSchema()) + ->columns(2) + ; $tabs[] = Forms\Components\Tabs\Tab::make(__('label.setting.backup.tab_header')) ->id('backup') @@ -135,4 +132,16 @@ class EditSetting extends Page implements Forms\Contracts\HasForms return $tabs; } + private function getHitAndRunSchema() + { + $default = [ + Forms\Components\Radio::make('hr.mode')->options(HitAndRun::listModes(true))->inline(true)->label(__('label.setting.hr.mode')), + Forms\Components\TextInput::make('hr.inspect_time')->helperText(__('label.setting.hr.inspect_time_help'))->label(__('label.setting.hr.inspect_time'))->integer(), + Forms\Components\TextInput::make('hr.seed_time_minimum')->helperText(__('label.setting.hr.seed_time_minimum_help'))->label(__('label.setting.hr.seed_time_minimum'))->integer(), + Forms\Components\TextInput::make('hr.ignore_when_ratio_reach')->helperText(__('label.setting.hr.ignore_when_ratio_reach_help'))->label(__('label.setting.hr.ignore_when_ratio_reach'))->integer(), + Forms\Components\TextInput::make('hr.ban_user_when_counts_reach')->helperText(__('label.setting.hr.ban_user_when_counts_reach_help'))->label(__('label.setting.hr.ban_user_when_counts_reach'))->integer(), + ]; + return apply_filter("nexus_hit_and_run_setting_schema", $default); + } + } diff --git a/app/Models/HitAndRun.php b/app/Models/HitAndRun.php index 96c948f5..19d9f219 100644 --- a/app/Models/HitAndRun.php +++ b/app/Models/HitAndRun.php @@ -2,6 +2,8 @@ namespace App\Models; +use Carbon\Carbon; +use Carbon\Exceptions\InvalidArgumentException; use Illuminate\Database\Eloquent\Casts\Attribute; class HitAndRun extends NexusModel @@ -17,7 +19,7 @@ class HitAndRun extends NexusModel const STATUS_UNREACHED = 3; const STATUS_PARDONED = 4; - public static $status = [ + public static array $status = [ self::STATUS_INSPECTING => ['text' => 'Inspecting'], self::STATUS_REACHED => ['text' => 'Reached'], self::STATUS_UNREACHED => ['text' => 'Unreached'], @@ -39,17 +41,37 @@ class HitAndRun extends NexusModel protected function seedTimeRequired(): Attribute { return new Attribute( - get: fn($value, $attributes) => $this->status == self::STATUS_INSPECTING ? mkprettytime(3600 * Setting::get('hr.seed_time_minimum') - $this->snatch->seedtime) : '---' + get: fn($value, $attributes) => $this->doGetSeedTimeRequired() ); } protected function inspectTimeLeft(): Attribute { return new Attribute( - get: fn($value, $attributes) => $this->status == self::STATUS_INSPECTING ? mkprettytime(\Carbon\Carbon::now()->diffInSeconds($this->snatch->completedat->addHours(Setting::get('hr.inspect_time')))) : '---' + get: fn($value, $attributes) => $this->doGetInspectTimeLeft() ); } + private function doGetInspectTimeLeft(): string + { + if ($this->status != self::STATUS_INSPECTING) { + return '---'; + } + $inspectTime = HitAndRun::getConfig('inspect_time', $this->torrent->basic_category->mode); + $diffInSeconds = Carbon::now()->diffInSeconds($this->snatch->completedat->addHours($inspectTime)); + return mkprettytime($diffInSeconds); + } + + private function doGetSeedTimeRequired(): string + { + if ($this->status != self::STATUS_INSPECTING) { + return '---'; + } + $seedTimeMinimum = HitAndRun::getConfig('seed_time_minimum', $this->torrent->basic_category->mode); + $diffInSeconds = 3600 * $seedTimeMinimum - $this->snatch->seedtime; + return mkprettytime($diffInSeconds); + } + public function getStatusTextAttribute() { return nexus_trans('hr.status_' . $this->status); @@ -87,8 +109,29 @@ class HitAndRun extends NexusModel public static function getIsEnabled(): bool { - $result = Setting::get('hr.mode'); - return $result && in_array($result, [self::MODE_GLOBAL, self::MODE_MANUAL]); + $enableSpecialSection = Setting::get('main.spsct') == 'yes'; + $browseMode = self::getConfig('mode', Setting::get('main.browsecat')); + $browseEnabled = $browseMode && in_array($browseMode, [self::MODE_GLOBAL, self::MODE_MANUAL]); + if (!$enableSpecialSection) { + do_log("Not enable special section, browseEnabled: $browseEnabled"); + return $browseEnabled; + } + $specialMode = self::getConfig('mode', Setting::get('main.specialcat')); + $specialEnabled = $specialMode && in_array($specialMode, [self::MODE_GLOBAL, self::MODE_MANUAL]); + $result = $browseEnabled || $specialEnabled; + do_log("Enable special section, browseEnabled: $browseEnabled, specialEnabled: $specialEnabled, result: $result"); + return $result; + } + + public static function getConfig($name, $searchBoxId) + { + if ($name == '*') { + $key = "hr"; + } else { + $key = "hr.$name"; + } + $default = Setting::get($key); + return apply_filter("nexus_setting_get", $default, $name, ['mode' => $searchBoxId]); } public function torrent(): \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Models/SearchBox.php b/app/Models/SearchBox.php index 5a5ddff7..74d0e28d 100644 --- a/app/Models/SearchBox.php +++ b/app/Models/SearchBox.php @@ -18,6 +18,14 @@ class SearchBox extends NexusModel 'extra' => 'object' ]; + const SECTION_BROWSE = 'browse'; + const SECTION_SPECIAL = 'special'; + + public static array $sections = [ + self::SECTION_BROWSE => ['text' => 'Browse'], + self::SECTION_SPECIAL => ['text' => 'Special'], + ]; + const EXTRA_DISPLAY_COVER_ON_TORRENT_LIST = 'display_cover_on_torrent_list'; const EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST = 'display_seed_box_icon_on_torrent_list'; @@ -35,6 +43,21 @@ class SearchBox extends NexusModel return $result; } + public static function listSections($field = null): array + { + $result = []; + foreach (self::$sections as $key => $value) { + $value['text'] = nexus_trans("searchbox.sections.$key"); + $value['mode'] = Setting::get("main.{$key}cat"); + if ($field !== null && isset($value[$field])) { + $result[$key] = $value[$field]; + } else { + $result[$key] = $value; + } + } + return $result; + } + public function getCustomFieldsAttribute($value): array { if (!is_array($value)) { diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 5f259a8b..6a040b24 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -289,7 +289,8 @@ class Torrent extends NexusModel public function getHrAttribute(): string { - $hrMode = Setting::get('hr.mode'); +// $hrMode = Setting::get('hr.mode'); + $hrMode = HitAndRun::getConfig('mode', $this->basic_category->mode); if ($hrMode == HitAndRun::MODE_GLOBAL) { return self::HR_YES; } diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index 25448b28..2c20f091 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -3,13 +3,16 @@ namespace App\Repositories; use App\Models\HitAndRun; use App\Models\Message; +use App\Models\SearchBox; use App\Models\Setting; use App\Models\User; use App\Models\UserBanLog; use Carbon\Carbon; +use Elasticsearch\Endpoints\Search; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use Nexus\Database\NexusDB; class HitAndRunRepository extends BaseRepository { @@ -87,12 +90,23 @@ class HitAndRunRepository extends BaseRepository return $query; } - public function cronjobUpdateStatus($uid = null, $torrentId = null, $ignoreTime = false): bool|int + public function cronjobUpdateStatus($uid = null, $torrentId = null, $ignoreTime = false) { - do_log("uid: $uid, torrentId: $torrentId, ignoreTime: " . var_export($ignoreTime, true)); + $enableSpecialSection = Setting::get('main.spsct') == 'yes'; + $browseMode = Setting::get('main.browsecat'); + $specialMode = Setting::get('main.specialcat'); + $this->doCronjobUpdateStatus($browseMode, $uid, $torrentId, $ignoreTime); + if ($enableSpecialSection && $browseMode != $specialMode) { + $this->doCronjobUpdateStatus($specialMode, $uid, $torrentId, $ignoreTime, $specialMode); + } + } + + private function doCronjobUpdateStatus($searchBoxId, $uid = null, $torrentId = null, $ignoreTime = false) + { + do_log("searchBoxId: $searchBoxId, uid: $uid, torrentId: $torrentId, ignoreTime: " . var_export($ignoreTime, true)); + $setting = HitAndRun::getConfig('*', $searchBoxId); $size = 1000; $page = 1; - $setting = Setting::get('hr'); if (empty($setting['mode'])) { do_log("H&R not set."); return false; @@ -108,7 +122,7 @@ class HitAndRunRepository extends BaseRepository $query = HitAndRun::query() ->where('status', HitAndRun::STATUS_INSPECTING) ->with([ - 'torrent' => function ($query) {$query->select(['id', 'size', 'name']);}, + 'torrent' => function ($query) {$query->select(['id', 'size', 'name', 'category']);}, 'snatch', 'user' => function ($query) {$query->select(['id', 'username', 'lang', 'class', 'donoruntil', 'enabled']);}, 'user.language', @@ -122,6 +136,9 @@ class HitAndRunRepository extends BaseRepository if (!$ignoreTime) { $query->where('created_at', '<', Carbon::now()->subHours($setting['inspect_time'])); } + $query->whereHas('torrent.basic_category', function (Builder $query) use ($searchBoxId) { + return $query->where('mode', $searchBoxId); + }); $successCounts = 0; $disabledUsers = []; while (true) { @@ -164,7 +181,7 @@ class HitAndRunRepository extends BaseRepository $requireSeedTime = bcmul($setting['seed_time_minimum'], 3600); do_log("$currentLog, targetSeedTime: $targetSeedTime, requireSeedTime: $requireSeedTime"); if ($targetSeedTime >= $requireSeedTime) { - $result = $this->reachedBySeedTime($row); + $result = $this->reachedBySeedTime($row, $searchBoxId); if ($result) { $successCounts++; } @@ -176,7 +193,7 @@ class HitAndRunRepository extends BaseRepository $requireShareRatio = $setting['ignore_when_ratio_reach']; do_log("$currentLog, targetShareRatio: $targetShareRatio, requireShareRatio: $requireShareRatio"); if ($targetShareRatio >= $requireShareRatio) { - $result = $this->reachedByShareRatio($row); + $result = $this->reachedByShareRatio($row, $searchBoxId); if ($result) { $successCounts++; } @@ -185,7 +202,7 @@ class HitAndRunRepository extends BaseRepository //unreached if ($row->created_at->addHours($setting['inspect_time'])->lte(Carbon::now())) { - $result = $this->unreached($row, !isset($disabledUsers[$row->uid])); + $result = $this->unreached($row, $searchBoxId, !isset($disabledUsers[$row->uid])); if ($result) { $successCounts++; $disabledUsers[$row->uid] = true; @@ -194,7 +211,7 @@ class HitAndRunRepository extends BaseRepository } $page++; } - do_log("[CRONJOB_UPDATE_HR_DONE]"); + do_log("searchBoxId: $searchBoxId, [CRONJOB_UPDATE_HR_DONE]"); return $successCounts; } @@ -212,15 +229,15 @@ class HitAndRunRepository extends BaseRepository ]; } - private function reachedByShareRatio(HitAndRun $hitAndRun): bool + private function reachedByShareRatio(HitAndRun $hitAndRun, $searchBoxId): bool { do_log(__METHOD__); $comment = nexus_trans('hr.reached_by_share_ratio_comment', [ 'now' => Carbon::now()->toDateTimeString(), - 'seed_time_minimum' => Setting::get('hr.seed_time_minimum'), + 'seed_time_minimum' => HitAndRun::getConfig('seed_time_minimum', $searchBoxId), 'seed_time' => bcdiv($hitAndRun->snatch->seedtime, 3600, 1), 'share_ratio' => get_hr_ratio($hitAndRun->snatch->uploaded, $hitAndRun->snatch->downloaded), - 'ignore_when_ratio_reach' => Setting::get('hr.ignore_when_ratio_reach'), + 'ignore_when_ratio_reach' => HitAndRun::getConfig('ignore_when_ratio_reach', $searchBoxId), ], $hitAndRun->user->locale); $update = [ 'comment' => $comment @@ -228,13 +245,13 @@ class HitAndRunRepository extends BaseRepository return $this->inspectingToReached($hitAndRun, $update, __FUNCTION__); } - private function reachedBySeedTime(HitAndRun $hitAndRun): bool + private function reachedBySeedTime(HitAndRun $hitAndRun, $searchBoxId): bool { do_log(__METHOD__); $comment = nexus_trans('hr.reached_by_seed_time_comment', [ 'now' => Carbon::now()->toDateTimeString(), 'seed_time' => bcdiv($hitAndRun->snatch->seedtime, 3600, 1), - 'seed_time_minimum' => Setting::get('hr.seed_time_minimum') + 'seed_time_minimum' => HitAndRun::getConfig('seed_time_minimum', $searchBoxId) ], $hitAndRun->user->locale); $update = [ 'comment' => $comment @@ -271,16 +288,16 @@ class HitAndRunRepository extends BaseRepository return true; } - private function unreached(HitAndRun $hitAndRun, $disableUser = true): bool + private function unreached(HitAndRun $hitAndRun, $searchBoxId, $disableUser = true): bool { do_log(sprintf('hitAndRun: %s, disableUser: %s', $hitAndRun->toJson(), var_export($disableUser, true))); $comment = nexus_trans('hr.unreached_comment', [ 'now' => Carbon::now()->toDateTimeString(), 'seed_time' => bcdiv($hitAndRun->snatch->seedtime, 3600, 1), - 'seed_time_minimum' => Setting::get('hr.seed_time_minimum'), + 'seed_time_minimum' => HitAndRun::getConfig('seed_time_minimum', $searchBoxId), 'share_ratio' => get_hr_ratio($hitAndRun->snatch->uploaded, $hitAndRun->snatch->downloaded), 'torrent_size' => mksize($hitAndRun->torrent->size), - 'ignore_when_ratio_reach' => Setting::get('hr.ignore_when_ratio_reach') + 'ignore_when_ratio_reach' => HitAndRun::getConfig('ignore_when_ratio_reach', $searchBoxId) ], $hitAndRun->user->locale); $update = [ 'status' => HitAndRun::STATUS_UNREACHED, @@ -319,7 +336,7 @@ class HitAndRunRepository extends BaseRepository /** @var User $user */ $user = $hitAndRun->user; $counts = $user->hitAndRuns()->where('status', HitAndRun::STATUS_UNREACHED)->count(); - $disableCounts = Setting::get('hr.ban_user_when_counts_reach'); + $disableCounts = HitAndRun::getConfig('ban_user_when_counts_reach', $searchBoxId); do_log("user: {$user->id}, H&R counts: $counts, disableCounts: $disableCounts", 'notice'); if ($counts >= $disableCounts) { do_log("[DISABLE_USER_DUE_TO_H&R_UNREACHED]", 'notice'); @@ -347,23 +364,48 @@ class HitAndRunRepository extends BaseRepository public function getStatusStats($uid, $formatted = true) { - $results = HitAndRun::query()->where('uid', $uid) - ->selectRaw('status, count(*) as counts') - ->groupBy('status') - ->get() - ->pluck('counts', 'status'); - if ($formatted) { - return sprintf( - '%s/%s/%s', - $results->get(HitAndRun::STATUS_INSPECTING, 0), - $results->get(HitAndRun::STATUS_UNREACHED, 0), - Setting::get('hr.ban_user_when_counts_reach') - ); + $enableSpecialSection = Setting::get('main.spsct') == 'yes'; + if ($enableSpecialSection) { + $sql = "select hit_and_runs.status, categories.mode, count(*) as counts from hit_and_runs left join torrents on torrents.id = hit_and_runs.torrent_id left join categories on categories.id = torrents.category where hit_and_runs.uid = $uid group by hit_and_runs.status, categories.mode"; + } else { + $sql = "select hit_and_runs.status, count(*) as counts from hit_and_runs where uid = $uid group by status"; + } + $results = NexusDB::select($sql); + if (!$formatted) { + return $results; + } + if ($enableSpecialSection) { + $grouped = []; + foreach ($results as $item) { + $grouped[$item['mode']][$item['status']] = $item['counts']; + } + $out = []; + foreach (SearchBox::listSections() as $key => $info) { + $out[] = sprintf( + '%s: %s/%s/%s', + $info['text'], + $grouped[$info['mode']][HitAndRun::STATUS_INSPECTING] ?? 0, + $grouped[$info['mode']][HitAndRun::STATUS_UNREACHED] ?? 0, + HitAndRun::getConfig('ban_user_when_counts_reach', $info['mode']) + ); + } + return implode(" ", $out); + } else { + foreach (SearchBox::listSections() as $key => $info) { + if ($key == SearchBox::SECTION_BROWSE) { + return sprintf( + '%s/%s/%s', + $results[HitAndRun::STATUS_INSPECTING] ?? 0, + $results[HitAndRun::STATUS_UNREACHED] ?? 0, + HitAndRun::getConfig('ban_user_when_counts_reach', $info['mode']) + ); + } + } } - return $results; - } + + public function listStatus(): array { $results = []; @@ -409,4 +451,14 @@ class HitAndRunRepository extends BaseRepository { return [HitAndRun::STATUS_INSPECTING, HitAndRun::STATUS_UNREACHED]; } + + public function renderOnUploadPage($value, $searchBoxId): string + { + if (HitAndRun::getConfig('mode', $searchBoxId) == \App\Models\HitAndRun::MODE_MANUAL && user_can('torrent_hr')) { + $hrRadio = sprintf('', $searchBoxId, $value == 0 ? ' checked' : ''); + $hrRadio .= sprintf('', $searchBoxId, $value == 1 ? ' checked' : ''); + return tr('H&R', $hrRadio, 1, "mode_$searchBoxId", true); + } + return ''; + } } diff --git a/app/Repositories/TrackerRepository.php b/app/Repositories/TrackerRepository.php index 251151be..85f8795c 100644 --- a/app/Repositories/TrackerRepository.php +++ b/app/Repositories/TrackerRepository.php @@ -1092,7 +1092,8 @@ class TrackerRepository extends BaseRepository if ($user->isDonating()) { return; } - $hrMode = Setting::get('hr.mode'); +// $hrMode = Setting::get('hr.mode'); + $hrMode = HitAndRun::getConfig('mode', $torrent->basic_category->mode); if ($hrMode == HitAndRun::MODE_DISABLED) { return; } diff --git a/include/constants.php b/include/constants.php index c16d9eb8..3be91f9e 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ '; @@ -5178,7 +5179,7 @@ function saveSetting($prefix, $nameAndValue, $autoload = 'yes') $sql .= implode(",", $data) . " on duplicate key update value = values(value)"; \Nexus\Database\NexusDB::statement($sql); clear_setting_cache(); - do_action("nexus_setting_update", $prefix, $nameAndValue); + do_action("nexus_setting_update"); } function getFullDirectory($dir) diff --git a/nexus/Imdb/Imdb.php b/nexus/Imdb/Imdb.php index baad02f9..78fe2bd5 100644 --- a/nexus/Imdb/Imdb.php +++ b/nexus/Imdb/Imdb.php @@ -34,7 +34,8 @@ class Imdb public static function listSupportLanguages(): array { - $data = require_once sprintf('%s/resources/lang/%s/imdb.php', ROOT_PATH, get_langfolder_cookie(true)); + $file = sprintf('%s/resources/lang/%s/imdb.php', ROOT_PATH, get_langfolder_cookie(true)); + $data = include $file; return $data['languages']; } diff --git a/public/announce.php b/public/announce.php index 02737e76..c93ca683 100644 --- a/public/announce.php +++ b/public/announce.php @@ -121,7 +121,7 @@ if (!$az) err("Invalid passkey! Re-download the .torrent from $BASEURL"); $userid = intval($az['id'] ?? 0); unset($GLOBALS['CURUSER']); $CURUSER = $GLOBALS["CURUSER"] = $az; -$isDonor = $az['donor'] == 'yes' && ($az['donoruntil'] === null || $az['donoruntil'] == '0000-00-00 00:00:00' || $az['donoruntil'] > date('Y-m-d H:i:s')); +$isDonor = is_donor($az); $az['__is_donor'] = $isDonor; $log = "user: $userid, isDonor: $isDonor, seeder: $seeder, ip: $ip, ipv4: $ipv4, ipv6: $ipv6"; @@ -156,7 +156,7 @@ elseif ($az['showclienterror'] == 'yes'){ } // check torrent based on info_hash -$checkTorrentSql = "SELECT id, size, owner, sp_state, seeders, leechers, UNIX_TIMESTAMP(added) AS ts, banned, hr, approval_status FROM torrents WHERE " . hash_where("info_hash", $info_hash); +$checkTorrentSql = "SELECT torrents.id, size, owner, sp_state, seeders, leechers, UNIX_TIMESTAMP(added) AS ts, banned, hr, approval_status, categories.mode FROM torrents left join categories on torrents.category = categories.id WHERE " . hash_where("info_hash", $info_hash); if (!$torrent = $Cache->get_value('torrent_hash_'.$info_hash.'_content')){ $res = sql_query($checkTorrentSql); $torrent = mysql_fetch_array($res); @@ -553,9 +553,10 @@ elseif(isset($self)) if (!empty($snatchInfo)) { sql_query("UPDATE snatched SET uploaded = uploaded + $trueupthis, downloaded = downloaded + $truedownthis, to_go = $left, $announcetime, last_action = ".$dt." $finished_snatched WHERE torrentid = $torrentid AND userid = $userid") or err("SL Err 2"); do_action('snatched_saved', $torrent, $snatchInfo); - if ($event == 'completed' && $az['class'] < \App\Models\HitAndRun::MINIMUM_IGNORE_USER_CLASS && !$isDonor) { + if ($event == 'completed' && $az['class'] < \App\Models\HitAndRun::MINIMUM_IGNORE_USER_CLASS && !$isDonor && isset($torrent['mode'])) { //think about H&R - $hrMode = get_setting('hr.mode'); +// $hrMode = get_setting('hr.mode'); + $hrMode = \App\Models\HitAndRun::getConfig('mode', $torrent['mode']); if ($hrMode == \App\Models\HitAndRun::MODE_GLOBAL || ($hrMode == \App\Models\HitAndRun::MODE_MANUAL && $torrent['hr'] == \App\Models\Torrent::HR_YES)) { $sql = "insert into hit_and_runs (uid, torrent_id, snatched_id) values ($userid, $torrentid, {$snatchInfo['id']}) on duplicate key update updated_at = " . sqlesc(date('Y-m-d H:i:s')); $affectedRows = sql_query($sql); diff --git a/public/details.php b/public/details.php index 9aa204f6..8694fc99 100644 --- a/public/details.php +++ b/public/details.php @@ -70,7 +70,7 @@ if (!$row) { $banned_torrent = ($row["banned"] == 'yes' ? " (".$lang_functions['text_banned'].")" : ""); $sp_torrent = get_torrent_promotion_append($row['sp_state'],'word', false, '', 0, '', $row['__ignore_global_sp_state'] ?? false); $sp_torrent_sub = get_torrent_promotion_append_sub($row['sp_state'],"",true,$row['added'], $row['promotion_time_type'], $row['promotion_until'], $row['__ignore_global_sp_state'] ?? false); - $hrImg = get_hr_img($row); + $hrImg = get_hr_img($row, $row['search_box_id']); $approvalStatusIcon = $torrentRep->renderApprovalStatus($row["approval_status"]); $s=htmlspecialchars($row["name"]).$banned_torrent.($sp_torrent ? "   ".$sp_torrent : "").($sp_torrent_sub) . $hrImg . $approvalStatusIcon; print("

      ".$s."

      \n"); diff --git a/public/edit.php b/public/edit.php index a2a64a57..b9d63d52 100644 --- a/public/edit.php +++ b/public/edit.php @@ -17,6 +17,7 @@ if (!$row) die(); * @since v1.6 */ $customField = new \Nexus\Field\Field(); +$hitAndRunRep = new \App\Repositories\HitAndRunRepository(); $tagIdArr = \App\Models\TorrentTag::query()->where('torrent_id', $id)->get()->pluck('tag_id')->toArray(); @@ -145,10 +146,11 @@ else { tr($lang_edit['row_content'],$team_select,1); } - echo $customField->renderOnUploadPage($id, $browsecatmode); + echo $hitAndRunRep->renderOnUploadPage($row['hr'], $browsecatmode); if ($enablespecial) { $customField->renderOnUploadPage($id, $specialcatmode); + echo $hitAndRunRep->renderOnUploadPage($row['hr'], $specialcatmode); } tr($lang_functions['text_tags'], (new \App\Repositories\TagRepository())->renderCheckbox($tagIdArr), 1); @@ -201,11 +203,6 @@ else { } tr($lang_edit['row_pick'], $pickcontent, 1); } - if (get_setting('hr.mode') == \App\Models\HitAndRun::MODE_MANUAL && user_can('torrent_hr')) { - $hrRadio = sprintf('', (string)$row['hr'] === '0' ? ' checked' : ''); - $hrRadio .= sprintf('', (string)$row['hr'] === '1' ? ' checked' : ''); - tr('H&R', $hrRadio, 1); - } print(" \n"); print("\n"); diff --git a/public/myhr.php b/public/myhr.php index 1df8fa02..1da91f1b 100644 --- a/public/myhr.php +++ b/public/myhr.php @@ -67,7 +67,8 @@ if ($rescount) { $query = (clone $baseQuery) ->with([ - 'torrent' => function ($query) {$query->select(['id', 'size', 'name']);}, + 'torrent' => function ($query) {$query->select(['id', 'size', 'name', 'category']);}, + 'torrent.basic_category', 'snatch', 'user' => function ($query) {$query->select(['id', 'lang']);}, 'user.language', @@ -92,9 +93,9 @@ if ($rescount) { " . mksize($row->snatch->uploaded) . " " . mksize($row->snatch->downloaded) . " " . get_hr_ratio($row->snatch->uploaded, $row->snatch->downloaded) . " - " . ($row->status == \App\Models\HitAndRun::STATUS_INSPECTING ? mkprettytime(3600 * get_setting('hr.seed_time_minimum') - $row->snatch->seedtime) : '---') . " + " . $row->seedTimeRequired . " " . format_datetime($row->snatch->completedat) . " - " . ($row->status == \App\Models\HitAndRun::STATUS_INSPECTING ? mkprettytime(\Carbon\Carbon::now()->diffInSeconds($row->snatch->completedat->addHours(get_setting('hr.inspect_time')))) : '---') . " + " . $row->inspectTimeLeft . " " . nl2br(trim($row->comment)) . " {$columnAction} "); diff --git a/public/takeedit.php b/public/takeedit.php index 56f8cf1d..ad310b0f 100644 --- a/public/takeedit.php +++ b/public/takeedit.php @@ -53,13 +53,6 @@ if (!empty($_POST['pt_gen'])) { $updateset[] = "technical_info = " . sqlesc($_POST['technical_info'] ?? ''); $torrentOperationLog = []; -/** - * hr - * @since 1.6.0-beta12 - */ -if (isset($_POST['hr']) && isset(\App\Models\Torrent::$hrStatus[$_POST['hr']]) && user_can('torrent_hr')) { - $updateset[] = "hr = " . sqlesc($_POST['hr']); -} if ($enablenfo_main=='yes'){ @@ -215,6 +208,14 @@ $descriptionArr = format_description($descr); $cover = get_image_from_description($descriptionArr, true, false); $updateset[] = "cover = " . sqlesc($cover); +/** + * hr + * @since 1.6.0-beta12 + */ +if (isset($_POST['hr'][$newcatmode]) && isset(\App\Models\Torrent::$hrStatus[$_POST['hr'][$newcatmode]]) && user_can('torrent_hr')) { + $updateset[] = "hr = " . sqlesc($_POST['hr'][$newcatmode]); +} + $sql = "UPDATE torrents SET " . join(",", $updateset) . " WHERE id = $id"; do_log("[UPDATE_TORRENT]: $sql"); $affectedRows = sql_query($sql) or sqlerr(__FILE__, __LINE__); diff --git a/public/takeupload.php b/public/takeupload.php index 70830baf..1deef989 100644 --- a/public/takeupload.php +++ b/public/takeupload.php @@ -339,8 +339,8 @@ $insert = [ 'technical_info' => $_POST['technical_info'] ?? '', 'cover' => $cover, ]; -if (isset($_POST['hr']) && isset(\App\Models\Torrent::$hrStatus[$_POST['hr']]) && user_can('torrent_hr')) { - $insert['hr'] = $_POST['hr']; +if (isset($_POST['hr'][$catmod]) && isset(\App\Models\Torrent::$hrStatus[$_POST['hr'][$catmod]]) && user_can('torrent_hr')) { + $insert['hr'] = $_POST['hr'][$catmod]; } if(user_can('torrentsticky')) { if (isset($_POST['pos_state']) && isset(\App\Models\Torrent::$posStates[$_POST['pos_state']])) { diff --git a/public/upload.php b/public/upload.php index 633cd7c0..0c33a17d 100644 --- a/public/upload.php +++ b/public/upload.php @@ -149,9 +149,12 @@ stdhead($lang_upload['head_upload']); tr($lang_upload['row_content'],$team_select,1); } $customField = new \Nexus\Field\Field(); + $hitAndRunRep = new \App\Repositories\HitAndRunRepository(); echo $customField->renderOnUploadPage(0, $browsecatmode); + echo $hitAndRunRep->renderOnUploadPage('', $browsecatmode); if ($enablespecial) { echo $customField->renderOnUploadPage(0, $specialcatmode); + echo $hitAndRunRep->renderOnUploadPage('', $specialcatmode); } //==== offer dropdown for offer mod from code by S4NE @@ -218,11 +221,6 @@ JS; tr($lang_upload['row_show_uploader'], "".$lang_upload['checkbox_hide_uploader_note'], 1); } tr($lang_functions['text_tags'], (new \App\Repositories\TagRepository())->renderCheckbox(), 1); - if (get_setting('hr.mode') == \App\Models\HitAndRun::MODE_MANUAL && user_can('torrent_hr')) { - $hrRadio = sprintf('', ''); - $hrRadio .= sprintf('', ''); - tr('H&R', $hrRadio, 1); - } ?> diff --git a/resources/lang/en/searchbox.php b/resources/lang/en/searchbox.php index ceb08948..0fb6d6eb 100644 --- a/resources/lang/en/searchbox.php +++ b/resources/lang/en/searchbox.php @@ -13,4 +13,8 @@ return [ \App\Models\SearchBox::EXTRA_DISPLAY_COVER_ON_TORRENT_LIST => 'Display cover on torrent list', \App\Models\SearchBox::EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST => 'Display seed box icon on torrent list', ], + 'sections' => [ + 'browse' => 'Torrents section', + 'special' => 'Special section', + ], ]; diff --git a/resources/lang/zh_CN/searchbox.php b/resources/lang/zh_CN/searchbox.php index 69344bbe..501d36ca 100644 --- a/resources/lang/zh_CN/searchbox.php +++ b/resources/lang/zh_CN/searchbox.php @@ -13,4 +13,8 @@ return [ \App\Models\SearchBox::EXTRA_DISPLAY_COVER_ON_TORRENT_LIST => '种子列表页展示封面', \App\Models\SearchBox::EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST => '种子列表页展示 SeedBox 图标', ], + 'sections' => [ + 'browse' => '种子区', + 'special' => '特别区', + ], ]; diff --git a/resources/lang/zh_TW/searchbox.php b/resources/lang/zh_TW/searchbox.php index e053f2b7..73558bae 100644 --- a/resources/lang/zh_TW/searchbox.php +++ b/resources/lang/zh_TW/searchbox.php @@ -13,4 +13,8 @@ return [ \App\Models\SearchBox::EXTRA_DISPLAY_COVER_ON_TORRENT_LIST => '種子列表頁展示封面', \App\Models\SearchBox::EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST => '種子列表頁展示 SeedBox 圖標', ], + 'sections' => [ + 'browse' => '種子區', + 'special' => '特別區', + ], ]; From 28b85c7ecf290191223d12bbebffed550be11fd3 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 1 Oct 2022 01:58:18 +0800 Subject: [PATCH 26/59] judge H&R count think about section --- app/Console/Commands/HitAndRunUpdateStatus.php | 4 ++-- app/Console/Commands/Test.php | 6 ++++-- app/Filament/Resources/User/HitAndRunResource.php | 2 +- app/Repositories/HitAndRunRepository.php | 7 ++++++- include/globalfunctions.php | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/Console/Commands/HitAndRunUpdateStatus.php b/app/Console/Commands/HitAndRunUpdateStatus.php index b0f09ecc..7ca934c0 100644 --- a/app/Console/Commands/HitAndRunUpdateStatus.php +++ b/app/Console/Commands/HitAndRunUpdateStatus.php @@ -44,8 +44,8 @@ class HitAndRunUpdateStatus extends Command $rep = new HitAndRunRepository(); $result = $rep->cronjobUpdateStatus($uid, $torrentId, $ignoreTime); $log = sprintf( - '[%s], %s, uid: %s, torrentId: %s, result: %s', - nexus()->getRequestId(), __METHOD__, $uid, $torrentId, var_export($result, true) + '[%s], %s, uid: %s, torrentId: %s, ignoreTime: %s, result: %s', + nexus()->getRequestId(), __METHOD__, $uid, $torrentId, $ignoreTime, var_export($result, true) ); $this->info($log); do_log($log); diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 13b3ba74..aebb3808 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -89,8 +89,10 @@ class Test extends Command */ public function handle() { - $r = strstr('hr.*', '.', true); - dd($r); + $rep = new \NexusPlugin\HitAndRun\HitAndRunRepository(); + $rep->initSectionHitAndRunSetting(SearchBox::SECTION_BROWSE . "_"); + $rep->initSectionHitAndRunSetting(SearchBox::SECTION_SPECIAL . "_"); + clear_setting_cache(); } diff --git a/app/Filament/Resources/User/HitAndRunResource.php b/app/Filament/Resources/User/HitAndRunResource.php index 17d4e132..654df0cb 100644 --- a/app/Filament/Resources/User/HitAndRunResource.php +++ b/app/Filament/Resources/User/HitAndRunResource.php @@ -72,7 +72,7 @@ class HitAndRunResource extends Resource public static function getEloquentQuery(): Builder { - return parent::getEloquentQuery()->with(['user', 'torrent', 'snatch']); + return parent::getEloquentQuery()->with(['user', 'torrent', 'snatch', 'torrent.basic_category']); } public static function getRelations(): array diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index 2c20f091..c1faa836 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -335,7 +335,12 @@ class HitAndRunRepository extends BaseRepository //disable user /** @var User $user */ $user = $hitAndRun->user; - $counts = $user->hitAndRuns()->where('status', HitAndRun::STATUS_UNREACHED)->count(); + $counts = $user->hitAndRuns() + ->where('status', HitAndRun::STATUS_UNREACHED) + ->whereHas('torrent.basic_category', function (Builder $query) use ($searchBoxId) { + return $query->where('mode', $searchBoxId); + }) + ->count(); $disableCounts = HitAndRun::getConfig('ban_user_when_counts_reach', $searchBoxId); do_log("user: {$user->id}, H&R counts: $counts, disableCounts: $disableCounts", 'notice'); if ($counts >= $disableCounts) { diff --git a/include/globalfunctions.php b/include/globalfunctions.php index 09b50ebf..5534c4a2 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -971,7 +971,7 @@ function clear_user_cache($uid, $passkey = '') } } -function clear_setting_cache($buildPermissionCache = false) +function clear_setting_cache() { \Nexus\Database\NexusDB::cache_del('nexus_settings_in_laravel'); \Nexus\Database\NexusDB::cache_del('nexus_settings_in_nexus'); From 127765fe478372214b29b7dbc90b21397a8c6ade Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 1 Oct 2022 03:08:57 +0800 Subject: [PATCH 27/59] fix userdetails page hr --- app/Models/Torrent.php | 2 +- public/getusertorrentlistajax.php | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 6a040b24..4d8c656b 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -35,7 +35,7 @@ class Torrent extends NexusModel public static $commentFields = [ 'id', 'name', 'added', 'visible', 'banned', 'owner', 'sp_state', 'pos_state', 'hr', 'picktype', 'picktime', 'last_action', 'leechers', 'seeders', 'times_completed', 'views', 'size', 'cover', 'anonymous', 'approval_status', - 'pos_state_until' + 'pos_state_until', 'category' ]; public static $basicRelations = [ diff --git a/public/getusertorrentlistajax.php b/public/getusertorrentlistajax.php index d7a3440b..c63b7426 100644 --- a/public/getusertorrentlistajax.php +++ b/public/getusertorrentlistajax.php @@ -150,7 +150,7 @@ function maketable($res, $mode = 'seeding') $total_size += $arr['size']; } - $hrImg = get_hr_img($arr); + $hrImg = get_hr_img($arr, $arr['search_box_id']); $approvalStatusIcon = $torrentRep->renderApprovalStatus($arr["approval_status"]); //torrent name $dispname = $nametitle = htmlspecialchars($arr["torrentname"]); @@ -245,7 +245,7 @@ switch ($type) { // $res = sql_query("SELECT torrents.id AS torrent, torrents.name as torrentname, small_descr, seeders, leechers, anonymous, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, snatched.seedtime, snatched.uploaded FROM torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories ON torrents.category = categories.id WHERE torrents.owner=$id AND snatched.userid=$id " . (($CURUSER["id"] != $id)?((get_user_class() < $viewanonymous_class) ? " AND anonymous = 'no'":""):"") ." ORDER BY torrents.added DESC") or sqlerr(__FILE__, __LINE__); // $res = sql_query("SELECT torrents.id AS torrent, torrents.name as torrentname, small_descr, seeders, leechers, anonymous, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added FROM torrents LEFT JOIN categories ON torrents.category = categories.id WHERE torrents.owner=$id " . (($CURUSER["id"] != $id)?((!user_can('viewanonymous')) ? " AND anonymous = 'no'":""):"") ." ORDER BY torrents.id DESC") or sqlerr(__FILE__, __LINE__); - $fields = "torrents.id AS torrent, torrents.name as torrentname, small_descr, seeders, leechers, anonymous, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,torrents.owner as userid"; + $fields = "torrents.id AS torrent, torrents.name as torrentname, small_descr, seeders, leechers, anonymous, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,torrents.owner as userid, categories.mode as search_box_id"; $tableWhere = "torrents LEFT JOIN categories ON torrents.category = categories.id WHERE torrents.owner=$id"; if ($CURUSER['id'] != $id && !user_can('viewanonymous')) { $tableWhere .= " AND anonymous = 'no'"; @@ -258,7 +258,7 @@ switch ($type) case 'seeding': { // $res = sql_query("SELECT torrent,added,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers FROM peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='yes' ORDER BY torrents.id DESC") or sqlerr(); - $fields = "torrent,added,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers,snatched.seedtime,snatched.uploaded,snatched.userid"; + $fields = "torrent,added,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers,snatched.seedtime,snatched.uploaded,snatched.userid, categories.mode as search_box_id"; $tableWhere = "peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='yes'"; $order = "torrents.id DESC"; break; @@ -268,7 +268,7 @@ switch ($type) case 'leeching': { // $res = sql_query("SELECT torrent,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers, torrents.added FROM peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='no' ORDER BY torrents.id DESC") or sqlerr(); - $fields = "torrent,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers, torrents.added,snatched.seedtime,snatched.uploaded,snatched.userid"; + $fields = "torrent,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers, torrents.added,snatched.seedtime,snatched.uploaded,snatched.userid, categories.mode as search_box_id"; $tableWhere = "peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='no'"; $order = "torrents.id DESC"; break; @@ -278,7 +278,7 @@ switch ($type) case 'completed': { // $res = sql_query("SELECT torrents.id AS torrent, torrents.name AS torrentname, small_descr, categories.name AS catname, torrents.banned, torrents.approval_status, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.seedtime, snatched.leechtime, snatched.completedat FROM torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories on torrents.category = categories.id WHERE snatched.finished='yes' AND torrents.owner != $id AND userid=$id ORDER BY snatched.id DESC") or sqlerr(); - $fields = "torrents.id AS torrent, torrents.name AS torrentname, small_descr, categories.name AS catname, torrents.banned, torrents.approval_status, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.seedtime,snatched.uploaded, snatched.leechtime, snatched.completedat,snatched.userid"; + $fields = "torrents.id AS torrent, torrents.name AS torrentname, small_descr, categories.name AS catname, torrents.banned, torrents.approval_status, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.seedtime,snatched.uploaded, snatched.leechtime, snatched.completedat,snatched.userid, categories.mode as search_box_id"; $tableWhere = "torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories on torrents.category = categories.id WHERE snatched.finished='yes' AND userid=$id AND torrents.owner != $id"; $order = "snatched.id DESC"; break; @@ -288,7 +288,7 @@ switch ($type) case 'incomplete': { // $res = sql_query("SELECT torrents.id AS torrent, torrents.name AS torrentname, small_descr, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.downloaded, snatched.leechtime FROM torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories on torrents.category = categories.id WHERE snatched.finished='no' AND userid=$id AND torrents.owner != $id ORDER BY snatched.id DESC") or sqlerr(); - $fields = "torrents.id AS torrent, torrents.name AS torrentname, small_descr, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.downloaded, snatched.leechtime,snatched.seedtime,snatched.uploaded,snatched.userid"; + $fields = "torrents.id AS torrent, torrents.name AS torrentname, small_descr, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.downloaded, snatched.leechtime,snatched.seedtime,snatched.uploaded,snatched.userid, categories.mode as search_box_id"; $tableWhere = "torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories on torrents.category = categories.id WHERE snatched.finished='no' AND userid=$id AND torrents.owner != $id"; $order = "snatched.id DESC"; break; From b234228264b9a5b26bfce7ede43b286bca4b6030 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 1 Oct 2022 03:32:16 +0800 Subject: [PATCH 28/59] fix myhr action --- public/myhr.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/public/myhr.php b/public/myhr.php index 1da91f1b..04d87071 100644 --- a/public/myhr.php +++ b/public/myhr.php @@ -82,11 +82,12 @@ if ($rescount) { $list = $query->get(); $hasActionRemove = false; foreach($list as $row) { - $columnAction = ''; + $columnAction = ''; if ($row->uid == $CURUSER['id'] && $row->status == \App\Models\HitAndRun::STATUS_INSPECTING) { $hasActionRemove = true; - $columnAction = sprintf('', $lang_myhr['action_remove'], $row->id); + $columnAction .= sprintf('', $lang_myhr['action_remove'], $row->id); } + $columnAction .= ''; print(" " . $row->id . " " . optional($row->torrent)->name . " From ee00be3840107fac86960bcd730e2dad2352ceb1 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 1 Oct 2022 18:26:18 +0800 Subject: [PATCH 29/59] fix details page other version hr img --- .../SettingResource/Pages/EditSetting.php | 2 +- app/Models/HitAndRun.php | 6 ++ app/Repositories/HitAndRunRepository.php | 74 +++++++++++-------- public/details.php | 4 +- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php index 3993aa59..7dc8b37b 100644 --- a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php +++ b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php @@ -141,7 +141,7 @@ class EditSetting extends Page implements Forms\Contracts\HasForms Forms\Components\TextInput::make('hr.ignore_when_ratio_reach')->helperText(__('label.setting.hr.ignore_when_ratio_reach_help'))->label(__('label.setting.hr.ignore_when_ratio_reach'))->integer(), Forms\Components\TextInput::make('hr.ban_user_when_counts_reach')->helperText(__('label.setting.hr.ban_user_when_counts_reach_help'))->label(__('label.setting.hr.ban_user_when_counts_reach'))->integer(), ]; - return apply_filter("nexus_hit_and_run_setting_schema", $default); + return apply_filter("hit_and_run_setting_schema", $default); } } diff --git a/app/Models/HitAndRun.php b/app/Models/HitAndRun.php index 19d9f219..621a53d6 100644 --- a/app/Models/HitAndRun.php +++ b/app/Models/HitAndRun.php @@ -134,6 +134,12 @@ class HitAndRun extends NexusModel return apply_filter("nexus_setting_get", $default, $name, ['mode' => $searchBoxId]); } + public static function diffInSection(): bool + { + $enableSpecialSection = Setting::get('main.spsct') == 'yes'; + return $enableSpecialSection && apply_filter("hit_and_run_diff_in_section", false); + } + public function torrent(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Torrent::class, 'torrent_id'); diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index c1faa836..52f3bf37 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -92,19 +92,25 @@ class HitAndRunRepository extends BaseRepository public function cronjobUpdateStatus($uid = null, $torrentId = null, $ignoreTime = false) { - $enableSpecialSection = Setting::get('main.spsct') == 'yes'; + $diffInSection = HitAndRun::diffInSection(); $browseMode = Setting::get('main.browsecat'); + $setting = HitAndRun::getConfig('*', $browseMode); + $setting['diff_in_section'] = $diffInSection; + $setting['search_box_id'] = $browseMode; + $this->doCronjobUpdateStatus($setting, $uid, $torrentId, $ignoreTime); + $specialMode = Setting::get('main.specialcat'); - $this->doCronjobUpdateStatus($browseMode, $uid, $torrentId, $ignoreTime); - if ($enableSpecialSection && $browseMode != $specialMode) { - $this->doCronjobUpdateStatus($specialMode, $uid, $torrentId, $ignoreTime, $specialMode); + if ($diffInSection && $browseMode != $specialMode) { + $setting = HitAndRun::getConfig('*', $specialMode); + $setting['diff_in_section'] = $diffInSection; + $setting['search_box_id'] = $specialMode; + $this->doCronjobUpdateStatus($setting, $uid, $torrentId, $ignoreTime); } } - private function doCronjobUpdateStatus($searchBoxId, $uid = null, $torrentId = null, $ignoreTime = false) + private function doCronjobUpdateStatus(array $setting, $uid = null, $torrentId = null, $ignoreTime = false) { - do_log("searchBoxId: $searchBoxId, uid: $uid, torrentId: $torrentId, ignoreTime: " . var_export($ignoreTime, true)); - $setting = HitAndRun::getConfig('*', $searchBoxId); + do_log("uid: $uid, torrentId: $torrentId, ignoreTime: " . var_export($ignoreTime, true)); $size = 1000; $page = 1; if (empty($setting['mode'])) { @@ -136,9 +142,12 @@ class HitAndRunRepository extends BaseRepository if (!$ignoreTime) { $query->where('created_at', '<', Carbon::now()->subHours($setting['inspect_time'])); } - $query->whereHas('torrent.basic_category', function (Builder $query) use ($searchBoxId) { - return $query->where('mode', $searchBoxId); - }); + if ($setting['diff_in_section']) { + $query->whereHas('torrent.basic_category', function (Builder $query) use ($setting) { + return $query->where('mode', $setting['search_box_id']); + }); + } + $successCounts = 0; $disabledUsers = []; while (true) { @@ -181,7 +190,7 @@ class HitAndRunRepository extends BaseRepository $requireSeedTime = bcmul($setting['seed_time_minimum'], 3600); do_log("$currentLog, targetSeedTime: $targetSeedTime, requireSeedTime: $requireSeedTime"); if ($targetSeedTime >= $requireSeedTime) { - $result = $this->reachedBySeedTime($row, $searchBoxId); + $result = $this->reachedBySeedTime($row, $setting); if ($result) { $successCounts++; } @@ -193,7 +202,7 @@ class HitAndRunRepository extends BaseRepository $requireShareRatio = $setting['ignore_when_ratio_reach']; do_log("$currentLog, targetShareRatio: $targetShareRatio, requireShareRatio: $requireShareRatio"); if ($targetShareRatio >= $requireShareRatio) { - $result = $this->reachedByShareRatio($row, $searchBoxId); + $result = $this->reachedByShareRatio($row, $setting); if ($result) { $successCounts++; } @@ -202,7 +211,7 @@ class HitAndRunRepository extends BaseRepository //unreached if ($row->created_at->addHours($setting['inspect_time'])->lte(Carbon::now())) { - $result = $this->unreached($row, $searchBoxId, !isset($disabledUsers[$row->uid])); + $result = $this->unreached($row, $setting, !isset($disabledUsers[$row->uid])); if ($result) { $successCounts++; $disabledUsers[$row->uid] = true; @@ -211,7 +220,7 @@ class HitAndRunRepository extends BaseRepository } $page++; } - do_log("searchBoxId: $searchBoxId, [CRONJOB_UPDATE_HR_DONE]"); + do_log("[CRONJOB_UPDATE_HR_DONE]"); return $successCounts; } @@ -229,15 +238,15 @@ class HitAndRunRepository extends BaseRepository ]; } - private function reachedByShareRatio(HitAndRun $hitAndRun, $searchBoxId): bool + private function reachedByShareRatio(HitAndRun $hitAndRun, array $setting): bool { do_log(__METHOD__); $comment = nexus_trans('hr.reached_by_share_ratio_comment', [ 'now' => Carbon::now()->toDateTimeString(), - 'seed_time_minimum' => HitAndRun::getConfig('seed_time_minimum', $searchBoxId), + 'seed_time_minimum' => $setting['seed_time_minimum'], 'seed_time' => bcdiv($hitAndRun->snatch->seedtime, 3600, 1), 'share_ratio' => get_hr_ratio($hitAndRun->snatch->uploaded, $hitAndRun->snatch->downloaded), - 'ignore_when_ratio_reach' => HitAndRun::getConfig('ignore_when_ratio_reach', $searchBoxId), + 'ignore_when_ratio_reach' => $setting['ignore_when_ratio_reach'], ], $hitAndRun->user->locale); $update = [ 'comment' => $comment @@ -245,13 +254,13 @@ class HitAndRunRepository extends BaseRepository return $this->inspectingToReached($hitAndRun, $update, __FUNCTION__); } - private function reachedBySeedTime(HitAndRun $hitAndRun, $searchBoxId): bool + private function reachedBySeedTime(HitAndRun $hitAndRun, array $setting): bool { do_log(__METHOD__); $comment = nexus_trans('hr.reached_by_seed_time_comment', [ 'now' => Carbon::now()->toDateTimeString(), 'seed_time' => bcdiv($hitAndRun->snatch->seedtime, 3600, 1), - 'seed_time_minimum' => HitAndRun::getConfig('seed_time_minimum', $searchBoxId) + 'seed_time_minimum' => $setting['seed_time_minimum'], ], $hitAndRun->user->locale); $update = [ 'comment' => $comment @@ -288,16 +297,16 @@ class HitAndRunRepository extends BaseRepository return true; } - private function unreached(HitAndRun $hitAndRun, $searchBoxId, $disableUser = true): bool + private function unreached(HitAndRun $hitAndRun, array $setting, $disableUser = true): bool { do_log(sprintf('hitAndRun: %s, disableUser: %s', $hitAndRun->toJson(), var_export($disableUser, true))); $comment = nexus_trans('hr.unreached_comment', [ 'now' => Carbon::now()->toDateTimeString(), 'seed_time' => bcdiv($hitAndRun->snatch->seedtime, 3600, 1), - 'seed_time_minimum' => HitAndRun::getConfig('seed_time_minimum', $searchBoxId), + 'seed_time_minimum' => $setting['seed_time_minimum'], 'share_ratio' => get_hr_ratio($hitAndRun->snatch->uploaded, $hitAndRun->snatch->downloaded), 'torrent_size' => mksize($hitAndRun->torrent->size), - 'ignore_when_ratio_reach' => HitAndRun::getConfig('ignore_when_ratio_reach', $searchBoxId) + 'ignore_when_ratio_reach' => $setting['ignore_when_ratio_reach'] ], $hitAndRun->user->locale); $update = [ 'status' => HitAndRun::STATUS_UNREACHED, @@ -335,13 +344,14 @@ class HitAndRunRepository extends BaseRepository //disable user /** @var User $user */ $user = $hitAndRun->user; - $counts = $user->hitAndRuns() - ->where('status', HitAndRun::STATUS_UNREACHED) - ->whereHas('torrent.basic_category', function (Builder $query) use ($searchBoxId) { - return $query->where('mode', $searchBoxId); - }) - ->count(); - $disableCounts = HitAndRun::getConfig('ban_user_when_counts_reach', $searchBoxId); + $countsQuery = $user->hitAndRuns()->where('status', HitAndRun::STATUS_UNREACHED); + if ($setting['diff_in_section']) { + $countsQuery->whereHas('torrent.basic_category', function (Builder $query) use ($setting) { + return $query->where('mode', $setting['search_box_id']); + }); + } + $counts = $countsQuery->count(); + $disableCounts = HitAndRun::getConfig('ban_user_when_counts_reach', $setting['search_box_id']); do_log("user: {$user->id}, H&R counts: $counts, disableCounts: $disableCounts", 'notice'); if ($counts >= $disableCounts) { do_log("[DISABLE_USER_DUE_TO_H&R_UNREACHED]", 'notice'); @@ -369,8 +379,8 @@ class HitAndRunRepository extends BaseRepository public function getStatusStats($uid, $formatted = true) { - $enableSpecialSection = Setting::get('main.spsct') == 'yes'; - if ($enableSpecialSection) { + $diffInSection = HitAndRun::diffInSection(); + if ($diffInSection) { $sql = "select hit_and_runs.status, categories.mode, count(*) as counts from hit_and_runs left join torrents on torrents.id = hit_and_runs.torrent_id left join categories on categories.id = torrents.category where hit_and_runs.uid = $uid group by hit_and_runs.status, categories.mode"; } else { $sql = "select hit_and_runs.status, count(*) as counts from hit_and_runs where uid = $uid group by status"; @@ -379,7 +389,7 @@ class HitAndRunRepository extends BaseRepository if (!$formatted) { return $results; } - if ($enableSpecialSection) { + if ($diffInSection) { $grouped = []; foreach ($results as $item) { $grouped[$item['mode']][$item['status']] = $item['counts']; diff --git a/public/details.php b/public/details.php index 8694fc99..889ca0f5 100644 --- a/public/details.php +++ b/public/details.php @@ -386,7 +386,7 @@ JS; { // $where_area = " url = " . sqlesc((int)$imdb_id) ." AND torrents.id != ".sqlesc($id); $where_area = sprintf('torrents.id in (%s)', implode(',', $otherCopiesIdArr)); - $copies_res = sql_query("SELECT torrents.id, torrents.name, torrents.sp_state, torrents.size, torrents.added, torrents.seeders, torrents.leechers, torrents.hr,categories.id AS catid, categories.name AS catname, categories.image AS catimage, sources.name AS source_name, media.name AS medium_name, codecs.name AS codec_name, standards.name AS standard_name, processings.name AS processing_name FROM torrents LEFT JOIN categories ON torrents.category=categories.id LEFT JOIN sources ON torrents.source = sources.id LEFT JOIN media ON torrents.medium = media.id LEFT JOIN codecs ON torrents.codec = codecs.id LEFT JOIN standards ON torrents.standard = standards.id LEFT JOIN processings ON torrents.processing = processings.id WHERE " . $where_area . " ORDER BY torrents.id DESC") or sqlerr(__FILE__, __LINE__); + $copies_res = sql_query("SELECT torrents.id, torrents.name, torrents.sp_state, torrents.size, torrents.added, torrents.seeders, torrents.leechers, torrents.hr,categories.id AS catid, categories.name AS catname, categories.image AS catimage, sources.name AS source_name, media.name AS medium_name, codecs.name AS codec_name, standards.name AS standard_name, processings.name AS processing_name, categories.mode as search_box_id FROM torrents LEFT JOIN categories ON torrents.category=categories.id LEFT JOIN sources ON torrents.source = sources.id LEFT JOIN media ON torrents.medium = media.id LEFT JOIN codecs ON torrents.codec = codecs.id LEFT JOIN standards ON torrents.standard = standards.id LEFT JOIN processings ON torrents.processing = processings.id WHERE " . $where_area . " ORDER BY torrents.id DESC") or sqlerr(__FILE__, __LINE__); $copies_count = mysql_num_rows($copies_res); if($copies_count > 0) @@ -416,7 +416,7 @@ JS; $sphighlight = get_torrent_bg_color($copy_row['sp_state']); $sp_info = get_torrent_promotion_append($copy_row['sp_state'], '', false, '', 0, '', $copy_row['__ignore_global_sp_state'] ?? false); - $hrImg = get_hr_img($copy_row); + $hrImg = get_hr_img($copy_row, $copy_row['search_box_id']); $s .= "".return_category_image($copy_row["catid"], "torrents.php?allsec=1&")."" . $dispname ."". $sp_info. $hrImg ."" . "" . rtrim(trim($other_source_info . $other_medium_info . $other_codec_info . $other_standard_info . $other_processing_info), ","). "" . From cdaec9bc62aff17617a1d0aa994602c47c1bdb3f Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 1 Oct 2022 19:54:19 +0800 Subject: [PATCH 30/59] fix nfo display --- include/functions.php | 38 ++++++++++++++++++++++++++++++++++++++ public/details.php | 2 +- public/viewnfo.php | 4 ++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/include/functions.php b/include/functions.php index 11b8e8f0..808e7804 100644 --- a/include/functions.php +++ b/include/functions.php @@ -3998,6 +3998,44 @@ $s = str_replace($table437, $tablehtml, $s); return $s; } +/** + * @param $ibm_437 + * @param $view + * @return array|string|string[] + * @ref https://github.com/HDInnovations/UNIT3D-Community-Edition/blob/master/app/Helpers/Nfo.php + */ +function code_new($ibm_437, $view) +{ + $swedishmagic = false; + if ($view == "magic") { + $swedishmagic = true; + } + $cf = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 8962, 199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197, 201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 162, 163, 165, 8359, 402, 225, 237, 243, 250, 241, 209, 170, 186, 191, 8976, 172, 189, 188, 161, 171, 187, 9617, 9618, 9619, 9474, 9508, 9569, 9570, 9558, 9557, 9571, 9553, 9559, 9565, 9564, 9563, 9488, 9492, 9524, 9516, 9500, 9472, 9532, 9566, 9567, 9562, 9556, 9577, 9574, 9568, 9552, 9580, 9575, 9576, 9572, 9573, 9561, 9560, 9554, 9555, 9579, 9578, 9496, 9484, 9608, 9604, 9612, 9616, 9600, 945, 223, 915, 960, 931, 963, 181, 964, 934, 920, 937, 948, 8734, 966, 949, 8745, 8801, 177, 8805, 8804, 8992, 8993, 247, 8776, 176, 8729, 183, 8730, 8319, 178, 9632, 160); + $s = ""; + for ($c = 0; $c < strlen($ibm_437); $c++) { // cyctle through the whole file doing a byte at a time. + $byte = $ibm_437[$c]; + $ob = ord($byte); + if ($ob >= 127) { // is it in the normal ascii range + $s .= '&#' . $cf[$ob] . ';'; + } else { + $s .= $byte; + } + } + + if ($swedishmagic) { + $s = str_replace("\345","\206",$s); + $s = str_replace("\344","\204",$s); + $s = str_replace("\366","\224",$s); + $s = preg_replace("/([ -~])\305([ -~])/", "\\1\217\\2", $s); + $s = preg_replace("/([ -~])\304([ -~])/", "\\1\216\\2", $s); + $s = preg_replace("/([ -~])\326([ -~])/", "\\1\231\\2", $s); + $s = str_replace ( "\311", "\220", $s ); // + $s = str_replace ( "\351", "\202", $s ); // + } + + return $s; +} + //Tooltip container for hot movie, classic movie, etc function create_tooltip_container($id_content_arr, $width = 400) diff --git a/public/details.php b/public/details.php index 889ca0f5..33bbeb9f 100644 --- a/public/details.php +++ b/public/details.php @@ -300,7 +300,7 @@ JS; if (user_can('viewnfo') && $CURUSER['shownfo'] != 'no' && $row["nfosz"] > 0){ if (!$nfo = $Cache->get_value('nfo_block_torrent_id_'.$id)){ - $nfo = code($row["nfo"], get_setting('torrent.nfo_view_style_default')); + $nfo = code_new($row["nfo"], get_setting('torrent.nfo_view_style_default')); $Cache->cache_value('nfo_block_torrent_id_'.$id, $nfo, 604800); } tr("\"Show/Hide\" ".$lang_details['text_nfo']."
      ". $lang_details['text_view_nfo']. "", "
      ".$nfo."
      \n", 1); diff --git a/public/viewnfo.php b/public/viewnfo.php index 9efee758..6d5b7ed6 100644 --- a/public/viewnfo.php +++ b/public/viewnfo.php @@ -28,13 +28,13 @@ if ($view == "latin-1" || $view == "fonthack") { // NOTICE: TBSource specifies Latin-1 encoding in include/bittorrent.php: // stdhead() //$nfo = htmlspecialchars(($a["nfo"])); -$nfo = code($a["nfo"], $view); +$nfo = code_new($a["nfo"], $view); } else { // Convert from ibm-437 to html unicode entities. // take special care of Swedish letters if in magic view. //$nfo = code($a["nfo"], $view == "magic"); -$nfo = code($a["nfo"], $view); +$nfo = code_new($a["nfo"], $view); } stdhead($lang_viewnfo['head_view_nfo']); From bb000fb67af7dbe1f7642a2afda559352f32f6e8 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 2 Oct 2022 21:14:11 +0800 Subject: [PATCH 31/59] [admin] torrent add more bulk action --- app/Filament/OptionsTrait.php | 8 ++ .../System/SeedBoxRecordResource.php | 1 + .../SettingResource/Pages/EditSetting.php | 1 + .../Resources/Torrent/TorrentResource.php | 113 +++++++++++++++++- app/Models/NexusModel.php | 15 +++ app/Models/Tag.php | 8 ++ app/Models/Torrent.php | 15 +++ app/Repositories/TagRepository.php | 17 +-- app/Repositories/TorrentRepository.php | 50 ++++++++ include/functions.php | 27 +++-- include/globalfunctions.php | 17 ++- nexus/Field/Field.php | 1 + nexus/Install/settings.default.php | 2 + public/announce.php | 2 +- public/mybonus.php | 4 +- public/settings.php | 3 +- resources/lang/en/admin.php | 3 + resources/lang/en/label.php | 7 +- resources/lang/en/permission.php | 4 + resources/lang/en/torrent.php | 5 + resources/lang/zh_CN/admin.php | 3 + resources/lang/zh_CN/label.php | 7 +- resources/lang/zh_CN/permission.php | 4 + resources/lang/zh_CN/torrent.php | 5 + resources/lang/zh_TW/admin.php | 3 + resources/lang/zh_TW/label.php | 7 +- resources/lang/zh_TW/permission.php | 4 + resources/lang/zh_TW/torrent.php | 5 + 28 files changed, 313 insertions(+), 28 deletions(-) diff --git a/app/Filament/OptionsTrait.php b/app/Filament/OptionsTrait.php index 0da89a5f..c210d280 100644 --- a/app/Filament/OptionsTrait.php +++ b/app/Filament/OptionsTrait.php @@ -15,4 +15,12 @@ trait OptionsTrait $disableValue => __('label.disabled'), ]; } + + private static function getYesNoOptions($yesValue = 1, $noValue = 0): array + { + return [ + $yesValue => 'Yes', + $noValue => 'No', + ]; + } } diff --git a/app/Filament/Resources/System/SeedBoxRecordResource.php b/app/Filament/Resources/System/SeedBoxRecordResource.php index 14565204..fca5b10c 100644 --- a/app/Filament/Resources/System/SeedBoxRecordResource.php +++ b/app/Filament/Resources/System/SeedBoxRecordResource.php @@ -56,6 +56,7 @@ class SeedBoxRecordResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id'), Tables\Columns\TextColumn::make('typeText')->label(__('label.seed_box_record.type')), + Tables\Columns\TextColumn::make('uid')->searchable(), Tables\Columns\TextColumn::make('user.username')->label(__('label.username'))->searchable(), Tables\Columns\TextColumn::make('operator')->label(__('label.seed_box_record.operator'))->searchable(), Tables\Columns\TextColumn::make('bandwidth')->label(__('label.seed_box_record.bandwidth')), diff --git a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php index 7dc8b37b..53c207db 100644 --- a/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php +++ b/app/Filament/Resources/System/SettingResource/Pages/EditSetting.php @@ -112,6 +112,7 @@ class EditSetting extends Page implements Forms\Contracts\HasForms Forms\Components\TextInput::make('seed_box.not_seed_box_max_speed')->label(__('label.setting.seed_box.not_seed_box_max_speed'))->helperText(__('label.setting.seed_box.not_seed_box_max_speed_help'))->integer(), Forms\Components\Radio::make('seed_box.no_promotion')->options(self::$yesOrNo)->inline(true)->label(__('label.setting.seed_box.no_promotion'))->helperText(__('label.setting.seed_box.no_promotion_help')), Forms\Components\TextInput::make('seed_box.max_uploaded')->label(__('label.setting.seed_box.max_uploaded'))->helperText(__('label.setting.seed_box.max_uploaded_help'))->integer(), + Forms\Components\TextInput::make('seed_box.max_uploaded_duration')->label(__('label.setting.seed_box.max_uploaded_duration'))->helperText(__('label.setting.seed_box.max_uploaded_duration_help'))->integer(), ])->columns(2); $tabs[] = Forms\Components\Tabs\Tab::make(__('label.setting.system.tab_header')) diff --git a/app/Filament/Resources/Torrent/TorrentResource.php b/app/Filament/Resources/Torrent/TorrentResource.php index 49f14881..f4b09701 100644 --- a/app/Filament/Resources/Torrent/TorrentResource.php +++ b/app/Filament/Resources/Torrent/TorrentResource.php @@ -9,6 +9,7 @@ use App\Models\Setting; use App\Models\Tag; use App\Models\Torrent; use App\Models\TorrentTag; +use App\Models\User; use App\Repositories\TagRepository; use App\Repositories\TorrentRepository; use Filament\Facades\Filament; @@ -24,6 +25,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; use Illuminate\Support\HtmlString; use Illuminate\Support\Str; +use Illuminate\Validation\Rule; class TorrentResource extends Resource { @@ -83,10 +85,16 @@ class TorrentResource extends Resource })->label(__('label.name'))->searchable(), Tables\Columns\TextColumn::make('posStateText')->label(__('label.torrent.pos_state')), Tables\Columns\TextColumn::make('spStateText')->label(__('label.torrent.sp_state')), + Tables\Columns\TextColumn::make('pickInfoText') + ->label(__('label.torrent.picktype')) + ->formatStateUsing(fn ($record) => $record->pickInfo['text']) + , + Tables\Columns\BooleanColumn::make('hr') + ->label(__('label.torrent.hr')) + , Tables\Columns\TextColumn::make('size')->label(__('label.torrent.size'))->formatStateUsing(fn ($state) => mksize($state)), Tables\Columns\TextColumn::make('seeders')->label(__('label.torrent.seeders')), Tables\Columns\TextColumn::make('leechers')->label(__('label.torrent.leechers')), -// Tables\Columns\TextColumn::make('times_completed')->label(__('label.torrent.times_completed')), Tables\Columns\BadgeColumn::make('approval_status') ->visible($showApproval) ->label(__('label.torrent.approval_status')) @@ -113,10 +121,18 @@ class TorrentResource extends Resource ->options(Torrent::listPromotionTypes(true)) ->label(__('label.torrent.sp_state')), + Tables\Filters\SelectFilter::make('picktype') + ->options(Torrent::listPickInfo(true)) + ->label(__('label.torrent.picktype')), + Tables\Filters\SelectFilter::make('approval_status') ->options(Torrent::listApprovalStatus(true)) ->visible($showApproval) ->label(__('label.torrent.approval_status')), + + Tables\Filters\SelectFilter::make('hr') + ->options(self::getYesNoOptions()) + ->label(__('label.torrent.hr')), ]) ->actions(self::getActions()) ->bulkActions(self::getBulkActions()); @@ -146,6 +162,7 @@ class TorrentResource extends Resource private static function getBulkActions(): array { + $user = Auth::user(); $actions = []; if (user_can('torrentsticky')) { $actions[] = Tables\Actions\BulkAction::make('posState') @@ -174,6 +191,66 @@ class TorrentResource extends Resource ->deselectRecordsAfterCompletion(); } + if (user_can('torrentonpromotion')) { + $actions[] = Tables\Actions\BulkAction::make('sp_state') + ->label(__('admin.resources.torrent.bulk_action_sp_state')) + ->form([ + Forms\Components\Select::make('sp_state') + ->label(__('label.torrent.sp_state')) + ->options(Torrent::listPromotionTypes(true)) + ->required() + , + Forms\Components\Select::make('promotion_time_type') + ->label(__('label.torrent.promotion_time_type')) + ->options(Torrent::listPromotionTimeTypes(true)) + ->required() + , + Forms\Components\DateTimePicker::make('promotion_until') + ->label(__('label.deadline')) + , + ]) + ->icon('heroicon-o-speakerphone') + ->action(function (Collection $records, array $data) { + $idArr = $records->pluck('id')->toArray(); + try { + $torrentRep = new TorrentRepository(); + $torrentRep->setSpState($idArr, $data['sp_state'], $data['promotion_time_type'], $data['promotion_until']); + } catch (\Exception $exception) { + do_log($exception->getMessage() . $exception->getTraceAsString(), 'error'); + Filament::notify('danger', $exception->getMessage()); + } + }) + ->deselectRecordsAfterCompletion(); + } + + if (user_can('torrentmanage') && ($user->picker == 'yes' || $user->class >= User::CLASS_SYSOP)) { + $actions[] = Tables\Actions\BulkAction::make('recommend') + ->label(__('admin.resources.torrent.bulk_action_recommend')) + ->form([ + Forms\Components\Radio::make('picktype') + ->label(__('admin.resources.torrent.bulk_action_recommend')) + ->inline() + ->options(Torrent::listPickInfo(true)) + ->required(), + + ]) + ->icon('heroicon-o-fire') + ->action(function (Collection $records, array $data) { + if (empty($data['picktype'])) { + return; + } + $idArr = $records->pluck('id')->toArray(); + try { + $torrentRep = new TorrentRepository(); + $torrentRep->setPickType($idArr, $data['picktype']); + } catch (\Exception $exception) { + do_log($exception->getMessage() . $exception->getTraceAsString(), 'error'); + Filament::notify('danger', class_basename($exception)); + } + }) + ->deselectRecordsAfterCompletion(); + } + if (user_can('torrentmanage')) { $actions[] = Tables\Actions\BulkAction::make('remove_tag') ->label(__('admin.resources.torrent.bulk_action_remove_tag')) @@ -217,6 +294,38 @@ class TorrentResource extends Resource } }) ->deselectRecordsAfterCompletion(); + + $actions[] = Tables\Actions\BulkAction::make('hr') + ->label(__('admin.resources.torrent.bulk_action_hr')) + ->form([ + Forms\Components\Radio::make('hr') + ->label(__('admin.resources.torrent.bulk_action_hr')) + ->inline() + ->options(self::getYesNoOptions()) + ->required(), + + ]) + ->icon('heroicon-o-sparkles') + ->action(function (Collection $records, array $data) { + if (empty($data['hr'])) { + return; + } + $idArr = $records->pluck('id')->toArray(); + try { + $torrentRep = new TorrentRepository(); + $torrentRep->setHr($idArr, $data['hr']); + } catch (\Exception $exception) { + do_log($exception->getMessage() . $exception->getTraceAsString(), 'error'); + Filament::notify('danger', class_basename($exception)); + } + }) + ->deselectRecordsAfterCompletion(); + } + + if (user_can('torrent-delete')) { + $actions[] = Tables\Actions\DeleteBulkAction::make('bulk-delete')->using(function (Collection $records) { + deletetorrent($records->pluck('id')->toArray()); + }); } return $actions; @@ -248,7 +357,7 @@ class TorrentResource extends Resource }); } - if (user_can('torrentmanage')) { + if (user_can('torrent-delete')) { $actions[] = Tables\Actions\DeleteAction::make('delete')->using(function ($record) { deletetorrent($record->id); }); diff --git a/app/Models/NexusModel.php b/app/Models/NexusModel.php index fcead220..75248fe4 100644 --- a/app/Models/NexusModel.php +++ b/app/Models/NexusModel.php @@ -51,4 +51,19 @@ class NexusModel extends Model return sprintf('%s: %s', nexus_trans('label.deadline'), $raw); } + public static function listStaticProps($dataSource, $textTransPrefix, $onlyKeyValue = false, $valueField = 'text'): array + { + $result = $dataSource; + $keyValue = []; + foreach ($result as $key => &$info) { + $text = $textTransPrefix ? nexus_trans("$textTransPrefix.$key") : $info['text']; + $info['text'] = $text; + $keyValue[$key] = $info[$valueField]; + } + if ($onlyKeyValue) { + return $keyValue; + } + return $result; + } + } diff --git a/app/Models/Tag.php b/app/Models/Tag.php index b9d42700..03858aec 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -48,6 +48,14 @@ class Tag extends NexusModel ], ]; + public static function listSpecial(): array + { + return array_filter([ + Setting::get('system.official_tag'), + Setting::get('system.zero_bonus_tag'), + ]); + } + public function torrents(): \Illuminate\Database\Eloquent\Relations\BelongsToMany { return $this->belongsToMany(Torrent::class, 'torrent_tags', 'tag_id', 'torrent_id'); diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 4d8c656b..a36faa4c 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -130,6 +130,16 @@ class Torrent extends NexusModel self::PICK_RECOMMENDED => ['text' => self::PICK_RECOMMENDED, 'color' => '#820084'], ]; + const PROMOTION_TIME_TYPE_GLOBAL = 0; + const PROMOTION_TIME_TYPE_PERMANENT = 1; + const PROMOTION_TIME_TYPE_DEADLINE = 2; + + public static array $promotionTimeTypes = [ + self::PROMOTION_TIME_TYPE_GLOBAL => ['text' => 'Global'], + self::PROMOTION_TIME_TYPE_PERMANENT => ['text' => 'Permanent'], + self::PROMOTION_TIME_TYPE_DEADLINE => ['text' => 'Until'], + ]; + const BONUS_REWARD_VALUES = [50, 100, 200, 500, 1000]; const APPROVAL_STATUS_NONE = 0; @@ -272,6 +282,11 @@ class Torrent extends NexusModel return $result; } + public static function listPromotionTimeTypes($onlyKeyValue = false, $valueField = 'text'): array + { + return self::listStaticProps(self::$promotionTimeTypes, 'torrent.promotion_time_types', $onlyKeyValue, $valueField); + } + public static function listPickInfo($onlyKeyValue = false, $valueField = 'text'): array { $result = self::$pickTypes; diff --git a/app/Repositories/TagRepository.php b/app/Repositories/TagRepository.php index 2353101d..ab107dd0 100644 --- a/app/Repositories/TagRepository.php +++ b/app/Repositories/TagRepository.php @@ -50,10 +50,14 @@ class TagRepository extends BaseRepository return Tag::query()->orderBy('priority', 'desc')->orderBy('id', 'desc'); } - public function renderCheckbox(array $checked = []): string + public function renderCheckbox(array $checked = [], $ignorePermission = false): string { $html = ''; - $results = $this->createBasicQuery()->get(); + $results = $this->listAll(); + if (!$ignorePermission && !user_can('torrent-set-special-tag')) { + $specialTags = Tag::listSpecial(); + $results = $results->filter(fn ($item) => !in_array($item->id, $specialTags)); + } foreach ($results as $value) { $html .= sprintf( '', @@ -65,11 +69,8 @@ class TagRepository extends BaseRepository public function renderSpan(array $renderIdArr = [], $withFilterLink = false): string { - if (empty(self::$allTags)) { - self::$allTags = self::createBasicQuery()->get(); - } $html = ''; - foreach (self::$allTags as $value) { + foreach ($this->listAll() as $value) { if (in_array($value->id, $renderIdArr) || (isset($renderIdArr[0]) && $renderIdArr[0] == '*')) { $tagId = $value->id; if ($value) { @@ -150,7 +151,9 @@ class TagRepository extends BaseRepository public function listAll() { - self::$allTags = self::createBasicQuery()->get(); + if (empty(self::$allTags)) { + self::$allTags = self::createBasicQuery()->get(); + } return self::$allTags; } diff --git a/app/Repositories/TorrentRepository.php b/app/Repositories/TorrentRepository.php index fe91ad6d..2d161b7e 100644 --- a/app/Repositories/TorrentRepository.php +++ b/app/Repositories/TorrentRepository.php @@ -616,6 +616,56 @@ class TorrentRepository extends BaseRepository return Torrent::query()->whereIn('id', $idArr)->update($update); } + public function setPickType($id, $pickType): int + { + user_can('torrentmanage', true); + if (!isset(Torrent::$pickTypes[$pickType])) { + throw new \InvalidArgumentException("Invalid pickType: $pickType"); + } + $update = [ + 'picktype' => $pickType, + 'picktime' => now(), + ]; + $idArr = Arr::wrap($id); + return Torrent::query()->whereIn('id', $idArr)->update($update); + } + + public function setHr($id, $hrStatus): int + { + user_can('torrentmanage', true); + if (!isset(Torrent::$hrStatus[$hrStatus])) { + throw new \InvalidArgumentException("Invalid hrStatus: $hrStatus"); + } + $update = [ + 'hr' => $hrStatus, + ]; + $idArr = Arr::wrap($id); + return Torrent::query()->whereIn('id', $idArr)->update($update); + } + + public function setSpState($id, $spState, $promotionTimeType, $promotionUntil = null): int + { + user_can('torrentonpromotion', true); + if (!isset(Torrent::$promotionTypes[$spState])) { + throw new \InvalidArgumentException("Invalid spState: $spState"); + } + if (!isset(Torrent::$promotionTimeTypes[$promotionTimeType])) { + throw new \InvalidArgumentException("Invalid promotionTimeType: $promotionTimeType"); + } + if (in_array($promotionTimeType, [Torrent::PROMOTION_TIME_TYPE_GLOBAL, Torrent::PROMOTION_TIME_TYPE_PERMANENT])) { + $promotionUntil = null; + } elseif (!$promotionUntil || Carbon::parse($promotionUntil)->lte(now())) { + throw new \InvalidArgumentException("Invalid promotionUntil: $promotionUntil"); + } + $update = [ + 'sp_state' => $spState, + 'promotion_time_type' => $promotionTimeType, + 'promotion_until' => $promotionUntil, + ]; + $idArr = Arr::wrap($id); + return Torrent::query()->whereIn('id', $idArr)->update($update); + } + public function buildUploadFieldInput($name, $value, $noteText, $btnText): string { $btn = $note = ''; diff --git a/include/functions.php b/include/functions.php index 808e7804..89052420 100644 --- a/include/functions.php +++ b/include/functions.php @@ -3049,18 +3049,21 @@ function loggedinorreturn($mainpage = false) { } function deletetorrent($id) { - $id = intval($id); + $idArr = \Illuminate\Support\Arr::wrap($id); + $idStr = implode(', ', $idArr ?: [0]); $torrent_dir = get_setting('main.torrent_dir'); - \Nexus\Database\NexusDB::statement("DELETE FROM torrents WHERE id = $id"); - \Nexus\Database\NexusDB::statement("DELETE FROM snatched WHERE torrentid = $id"); + \Nexus\Database\NexusDB::statement("DELETE FROM torrents WHERE id in ($idStr)"); + \Nexus\Database\NexusDB::statement("DELETE FROM snatched WHERE torrentid in ($idStr)"); foreach(array("peers", "files", "comments") as $x) { - \Nexus\Database\NexusDB::statement("DELETE FROM $x WHERE torrent = $id"); + \Nexus\Database\NexusDB::statement("DELETE FROM $x WHERE torrent in ($idStr)"); } - \Nexus\Database\NexusDB::statement("DELETE FROM hit_and_runs WHERE torrent_id = $id"); - \Nexus\Database\NexusDB::statement("DELETE FROM claims WHERE torrent_id = $id"); - do_action("torrent_delete", $id); - do_log("delete torrent: $id", "error"); - unlink(getFullDirectory("$torrent_dir/$id.torrent")); + \Nexus\Database\NexusDB::statement("DELETE FROM hit_and_runs WHERE torrent_id in ($idStr)"); + \Nexus\Database\NexusDB::statement("DELETE FROM claims WHERE torrent_id in ($idStr)"); + foreach ($idArr as $_id) { + do_action("torrent_delete", $_id); + do_log("delete torrent: $_id", "error"); + unlink(getFullDirectory("$torrent_dir/$_id.torrent")); + } } function pager($rpp, $count, $href, $opts = array(), $pagename = "page") { @@ -5790,6 +5793,8 @@ function build_medal_image(\Illuminate\Support\Collection $medals, $maxHeight = function insert_torrent_tags($torrentId, $tagIdArr, $sync = false) { + $specialTags = \App\Models\Tag::listSpecial(); + $canSetSpecialTag = user_can('torrent-set-special-tag'); $dateTimeStringNow = date('Y-m-d H:i:s'); if ($sync) { sql_query("delete from torrent_tags where torrent_id = $torrentId"); @@ -5800,6 +5805,10 @@ function insert_torrent_tags($torrentId, $tagIdArr, $sync = false) $insertTagsSql = 'insert into torrent_tags (`torrent_id`, `tag_id`, `created_at`, `updated_at`) values '; $values = []; foreach ($tagIdArr as $tagId) { + if (in_array($tagId, $specialTags) && !$canSetSpecialTag) { + do_log("special tag: $tagId, and user no permission"); + continue; + } $values[] = sprintf("(%s, %s, '%s', '%s')", $torrentId, $tagId, $dateTimeStringNow, $dateTimeStringNow); } $insertTagsSql .= implode(', ', $values); diff --git a/include/globalfunctions.php b/include/globalfunctions.php index 5534c4a2..51d23737 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -942,9 +942,20 @@ function getDataTraffic(array $torrent, array $queries, array $user, $peer, $sna $log .= ", isIPSeedBox && isSeedBoxNoPromotion, increment for user = real"; } $maxUploadedTimes = get_setting('seed_box.max_uploaded'); - if (!empty($snatch) && isset($torrent['size']) && $snatch['uploaded'] >= $torrent['size'] * $maxUploadedTimes) { - $log .= ", snatchUploaded >= torrentSize * times($maxUploadedTimes), uploadedIncrementForUser = 0"; - $uploadedIncrementForUser = 0; + $maxUploadedDurationSeconds = get_setting('seed_box.max_uploaded_duration', 0) * 3600; + $torrentTTL = time() - strtotime($torrent['added']); + $timeRangeValid = ($maxUploadedDurationSeconds == 0) || ($torrentTTL < $maxUploadedDurationSeconds); + $log .= ", maxUploadedTimes: $maxUploadedTimes, maxUploadedDurationSeconds: $maxUploadedDurationSeconds, timeRangeValid: $timeRangeValid"; + if ($maxUploadedTimes > 0 && $timeRangeValid) { + $log .= ", [LIMIT_UPLOADED]"; + if (!empty($snatch) && isset($torrent['size']) && $snatch['uploaded'] >= $torrent['size'] * $maxUploadedTimes) { + $log .= ", snatchUploaded({$snatch['uploaded']}) >= torrentSize({$torrent['size']}) * times($maxUploadedTimes), uploadedIncrementForUser = 0"; + $uploadedIncrementForUser = 0; + } else { + $log .= ", snatchUploaded({$snatch['uploaded']}) < torrentSize({$torrent['size']}) * times($maxUploadedTimes), uploadedIncrementForUser do not change to 0"; + } + } else { + $log .= ", [NOT_LIMIT_UPLOADED]"; } } } diff --git a/nexus/Field/Field.php b/nexus/Field/Field.php index 8ca7cc18..9906c060 100644 --- a/nexus/Field/Field.php +++ b/nexus/Field/Field.php @@ -3,6 +3,7 @@ namespace Nexus\Field; use App\Models\SearchBox; +use App\Models\Tag; use App\Models\TorrentCustomField; use App\Models\TorrentCustomFieldValue; use Elasticsearch\Endpoints\Search; diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index 99330be6..bdb20baf 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -180,6 +180,7 @@ return array ( 'torrent-delete' => User::CLASS_ADMINISTRATOR, 'user-delete' => User::CLASS_ADMINISTRATOR, 'user-change-class' => User::CLASS_ADMINISTRATOR, + 'torrent-set-special-tag' => User::CLASS_ADMINISTRATOR, ), 'tweak' => array ( @@ -425,6 +426,7 @@ return array ( 'no_promotion' => 'yes', 'max_uploaded' => 3, 'not_seed_box_max_speed' => 10240, + 'max_uploaded_duration' => 0, ], 'system' => [ 'change_username_min_interval_in_days' => '365', diff --git a/public/announce.php b/public/announce.php index c93ca683..eb041ac9 100644 --- a/public/announce.php +++ b/public/announce.php @@ -156,7 +156,7 @@ elseif ($az['showclienterror'] == 'yes'){ } // check torrent based on info_hash -$checkTorrentSql = "SELECT torrents.id, size, owner, sp_state, seeders, leechers, UNIX_TIMESTAMP(added) AS ts, banned, hr, approval_status, categories.mode FROM torrents left join categories on torrents.category = categories.id WHERE " . hash_where("info_hash", $info_hash); +$checkTorrentSql = "SELECT torrents.id, size, owner, sp_state, seeders, leechers, UNIX_TIMESTAMP(added) AS ts, added, banned, hr, approval_status, categories.mode FROM torrents left join categories on torrents.category = categories.id WHERE " . hash_where("info_hash", $info_hash); if (!$torrent = $Cache->get_value('torrent_hash_'.$info_hash.'_content')){ $res = sql_query($checkTorrentSql); $torrent = mysql_fetch_array($res); diff --git a/public/mybonus.php b/public/mybonus.php index e7ac933d..8a5d851e 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -580,14 +580,14 @@ if ($action == "exchange") { $up = $upload + $bonusarray['menge']; // $bonuscomment = date("Y-m-d") . " - " .$points. " Points for upload bonus.\n " .$bonuscomment; // sql_query("UPDATE users SET uploaded = ".sqlesc($up).", seedbonus = seedbonus - $points, bonuscomment = ".sqlesc($bonuscomment)." WHERE id = ".sqlesc($userid)) or sqlerr(__FILE__, __LINE__); - $bonusRep->consumeUserBonus($CURUSER['id'], $points, \App\Models\BonusLogs::BUSINESS_TYPE_EXCHANGE_UPLOAD, $points. " Points for upload bonus.", ['uploaded' => $up]); + $bonusRep->consumeUserBonus($CURUSER['id'], $points, \App\Models\BonusLogs::BUSINESS_TYPE_EXCHANGE_UPLOAD, $points. " Points for uploaded.", ['uploaded' => $up]); nexus_redirect("" . get_protocol_prefix() . "$BASEURL/mybonus.php?do=upload"); } } if($art == "traffic_downloaded") { $downloaded = $CURUSER['downloaded']; $down = $downloaded + $bonusarray['menge']; - $bonusRep->consumeUserBonus($CURUSER['id'], $points, \App\Models\BonusLogs::BUSINESS_TYPE_EXCHANGE_DOWNLOAD, $points. " Points for download bonus.", ['downloaded' => $down]); + $bonusRep->consumeUserBonus($CURUSER['id'], $points, \App\Models\BonusLogs::BUSINESS_TYPE_EXCHANGE_DOWNLOAD, $points. " Points for downloaded.", ['downloaded' => $down]); nexus_redirect("" . get_protocol_prefix() . "$BASEURL/mybonus.php?do=download"); } //=== trade for one month VIP status ***note "SET class = '10'" change "10" to whatever your VIP class number is diff --git a/public/settings.php b/public/settings.php index 7b70aa36..005d9ede 100644 --- a/public/settings.php +++ b/public/settings.php @@ -224,7 +224,7 @@ elseif ($action == 'savesettings_authority') // save user authority 'torrentstructure','sendinvite','viewhistory','topten','log','confilog','userprofile', 'torrenthistory','prfmanage', 'cruprfmanage', 'uploadsub','delownsub','submanage','updateextinfo', 'viewanonymous','beanonymous','addoffer','offermanage', 'upload','uploadspecial', 'view_special_torrent','movetorrent','chrmanage','viewinvite', 'buyinvite','seebanned','againstoffer','userbar', 'torrent-approval', - 'torrent-delete', 'user-delete', 'user-change-class', + 'torrent-delete', 'user-delete', 'user-change-class', 'torrent-set-special-tag' ); GetVar($validConfig); $AUTHORITY = []; @@ -452,6 +452,7 @@ elseif ($action == 'authoritysettings') //Authority settings tr($lang_settings['row_torrent_sticky'], $lang_settings['text_minimum_class'].classlist('torrentsticky',$maxclass,$AUTHORITY['torrentsticky'],0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).$lang_settings['text_torrent_sticky_note'],1); tr($lang_settings['row_torrent_on_promotion'], $lang_settings['text_minimum_class'].classlist('torrentonpromotion',$maxclass,$AUTHORITY['torrentonpromotion'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).$lang_settings['text_torrent_promotion_note'],1); tr($lang_settings['row_torrent_hr'], $lang_settings['text_minimum_class'].classlist('torrent_hr',$maxclass,$AUTHORITY['torrent_hr'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).$lang_settings['text_torrent_hr_note'],1); + tr(nexus_trans('permission.torrent-set-special-tag.text'), $lang_settings['text_minimum_class'].classlist('torrent-set-special-tag',$maxclass,$AUTHORITY['torrent-set-special-tag'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).nexus_trans('permission.torrent-set-special-tag.desc'),1); tr(nexus_trans('permission.torrent-approval.text'), $lang_settings['text_minimum_class'].classlist('torrent-approval',$maxclass,$AUTHORITY['torrent-approval'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).nexus_trans('permission.torrent-approval.desc'),1); tr($lang_settings['row_ask_for_reseed'], $lang_settings['text_minimum_class'].classlist('askreseed',$maxclass,$AUTHORITY['askreseed'],0,true).$lang_settings['text_default'].get_user_class_name(UC_POWER_USER,false,true,true).$lang_settings['text_ask_for_reseed_note'],1); tr($lang_settings['row_view_nfo'], $lang_settings['text_minimum_class'].classlist('viewnfo',$maxclass,$AUTHORITY['viewnfo'],0,true).$lang_settings['text_default'].get_user_class_name(UC_POWER_USER,false,true,true).$lang_settings['text_view_nfo_note'],1); diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index 82480c32..ce81cbeb 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -89,6 +89,9 @@ return [ 'bulk_action_attach_tag' => 'Attach tag', 'action_approval' => 'Approval', 'bulk_action_attach_tag_remove_old' => 'Also delete old tags', + 'bulk_action_recommend' => 'Recommend', + 'bulk_action_sp_state' => 'Promotion', + 'bulk_action_hr' => 'H&R', ], 'seed_box_record' => [ 'toggle_status' => 'Change status', diff --git a/resources/lang/en/label.php b/resources/lang/en/label.php index a865ef26..3273d595 100644 --- a/resources/lang/en/label.php +++ b/resources/lang/en/label.php @@ -73,9 +73,11 @@ return [ 'no_promotion' => 'No promotion', 'no_promotion_help' => 'No Promotion, uploaded/downloaded are calculated according to the actual value', 'max_uploaded' => 'Maximum upload volume multiplier', - 'max_uploaded_help' => 'The total upload volume is at most a multiple of its volume', + 'max_uploaded_help' => 'The total upload volume is at most a multiple of its volume. Set to 0 No limitation', 'not_seed_box_max_speed' => 'Not SeedBox max upload speed', 'not_seed_box_max_speed_help' => 'Unit: Mbps, if this value is exceeded and the SeedBox record cannot be matched, download permission is disabled', + 'max_uploaded_duration' => 'Maximum upload volume multiplier effective time range', + 'max_uploaded_duration_help' => 'Unit: hours. The maximum upload volume multiplier takes effect within this time range after the torrent is published, and does not take effect beyond this range. A setting of 0 is always in effect', ], 'system' => [ 'tab_header' => 'System', @@ -149,6 +151,9 @@ return [ 'pos_state' => 'Pos state', 'sp_state' => 'Promotion', 'visible' => 'Visible', + 'picktype' => 'Recommend', + 'promotion_time_type' => 'Promotion type time', + 'hr' => 'H&R', ], 'hit_and_run' => [ 'label' => 'User H&R', diff --git a/resources/lang/en/permission.php b/resources/lang/en/permission.php index 47ae27aa..3555f17e 100644 --- a/resources/lang/en/permission.php +++ b/resources/lang/en/permission.php @@ -5,6 +5,10 @@ return [ 'text' => 'Approval Torrent', 'desc' => 'Allow, Deny, or mark as unreviewed', ], + 'torrent-set-special-tag' => [ + 'text' => 'Set torrent special tags', + 'desc' => 'Set the Official/Zero bonus tag to torrents', + ], 'defaultclass' => [ 'text' => 'Default Class', 'desc' => ' Class upon registration', diff --git a/resources/lang/en/torrent.php b/resources/lang/en/torrent.php index 907d2e0d..f30409bd 100644 --- a/resources/lang/en/torrent.php +++ b/resources/lang/en/torrent.php @@ -76,4 +76,9 @@ return [ 'logs_label' => 'Approval logs' ], 'show_hide_media_info' => 'Show/Hide raw MediaInfo', + 'promotion_time_types' => [ + \App\Models\Torrent::PROMOTION_TIME_TYPE_GLOBAL => 'Global', + \App\Models\Torrent::PROMOTION_TIME_TYPE_PERMANENT => 'Permanent', + \App\Models\Torrent::PROMOTION_TIME_TYPE_DEADLINE => 'Until', + ], ]; diff --git a/resources/lang/zh_CN/admin.php b/resources/lang/zh_CN/admin.php index 546c835e..69ecf72a 100644 --- a/resources/lang/zh_CN/admin.php +++ b/resources/lang/zh_CN/admin.php @@ -90,6 +90,9 @@ return [ 'bulk_action_attach_tag' => '设置标签', 'action_approval' => '审核', 'bulk_action_attach_tag_remove_old' => '同时删除旧标签', + 'bulk_action_recommend' => '推荐', + 'bulk_action_sp_state' => '优惠', + 'bulk_action_hr' => 'H&R', ], 'seed_box_record' => [ 'toggle_status' => '更改状态', diff --git a/resources/lang/zh_CN/label.php b/resources/lang/zh_CN/label.php index fc750670..42985d70 100644 --- a/resources/lang/zh_CN/label.php +++ b/resources/lang/zh_CN/label.php @@ -73,9 +73,11 @@ return [ 'no_promotion' => '无优惠', 'no_promotion_help' => '不享受任何优惠,上传量/下载量按实际值计算', 'max_uploaded' => '最大上传量倍数', - 'max_uploaded_help' => '总上传量最多为其体积的多少倍', + 'max_uploaded_help' => '总上传量最多为其体积的多少倍。设置为 0 无此限制', 'not_seed_box_max_speed' => '非 SeedBox 最高限速', 'not_seed_box_max_speed_help' => '单位:Mbps。若超过此值又不能匹配 SeedBox 记录,禁用下载权限', + 'max_uploaded_duration' => '最大上传量倍数有效时间范围', + 'max_uploaded_duration_help' => '单位:小时。种子发布后的这个时间范围内,最大上传量倍数生效,超过此范围不生效。设置为 0 一直生效', ], 'system' => [ 'tab_header' => '系统', @@ -148,6 +150,9 @@ return [ 'pos_state' => '置顶', 'sp_state' => '优惠', 'visible' => '活种', + 'picktype' => '推荐', + 'promotion_time_type' => '优惠时间类型', + 'hr' => 'H&R', ], 'hit_and_run' => [ 'label' => '用户 H&R', diff --git a/resources/lang/zh_CN/permission.php b/resources/lang/zh_CN/permission.php index 1e50fba3..8d85f91f 100644 --- a/resources/lang/zh_CN/permission.php +++ b/resources/lang/zh_CN/permission.php @@ -5,6 +5,10 @@ return [ 'text' => '审核种子', 'desc' => '通过种子、拒绝种子、或将种子标记为未审', ], + 'torrent-set-special-tag' => [ + 'text' => '设定种子特殊标签', + 'desc' => '设定种子的官方、零魔标签', + ], 'defaultclass' => [ 'text' => '默认等级', 'desc' => '注册时获得的等级', diff --git a/resources/lang/zh_CN/torrent.php b/resources/lang/zh_CN/torrent.php index 4870f6de..7740eb33 100644 --- a/resources/lang/zh_CN/torrent.php +++ b/resources/lang/zh_CN/torrent.php @@ -76,4 +76,9 @@ return [ 'logs_label' => '审核记录', ], 'show_hide_media_info' => '显示/隐藏原始 MediaInfo', + 'promotion_time_types' => [ + \App\Models\Torrent::PROMOTION_TIME_TYPE_GLOBAL => '全局', + \App\Models\Torrent::PROMOTION_TIME_TYPE_PERMANENT => '永久', + \App\Models\Torrent::PROMOTION_TIME_TYPE_DEADLINE => '直到', + ], ]; diff --git a/resources/lang/zh_TW/admin.php b/resources/lang/zh_TW/admin.php index c46b91fd..07664aed 100644 --- a/resources/lang/zh_TW/admin.php +++ b/resources/lang/zh_TW/admin.php @@ -89,6 +89,9 @@ return [ 'bulk_action_attach_tag' => '設置標簽', 'action_approval' => '審核', 'bulk_action_attach_tag_remove_old' => '同時刪除舊標簽', + 'bulk_action_recommend' => '推薦', + 'bulk_action_sp_state' => '優惠', + 'bulk_action_hr' => 'H&R', ], 'seed_box_record' => [ 'toggle_status' => '更改狀態', diff --git a/resources/lang/zh_TW/label.php b/resources/lang/zh_TW/label.php index e19d82f0..d1ac1dca 100644 --- a/resources/lang/zh_TW/label.php +++ b/resources/lang/zh_TW/label.php @@ -73,9 +73,11 @@ return [ 'no_promotion' => '無優惠', 'no_promotion_help' => '不享受任何優惠,上傳量/下載量按實際值計算', 'max_uploaded' => '最大上傳量倍數', - 'max_uploaded_help' => '總上傳量最多為其體積的多少倍', + 'max_uploaded_help' => '總上傳量最多為其體積的多少倍。設置為 0 無此限製', 'not_seed_box_max_speed' => '非 SeedBox 最高限速', 'not_seed_box_max_speed_help' => '單位:Mbps。若超過此值又不能匹配 SeedBox 記錄,禁用下載權限', + 'max_uploaded_duration' => '最大上傳量倍數有效時間範圍', + 'max_uploaded_duration_help' => '單位:小時。種子發布後的這個時間範圍內,最大上傳量倍數生效,超過此範圍不生效。設置為 0 一直生效', ], 'system' => [ 'tab_header' => '系統', @@ -149,6 +151,9 @@ return [ 'pos_state' => '置頂', 'sp_state' => '優惠', 'visible' => '活種', + 'picktype' => '推薦', + 'promotion_time_type' => '優惠時間類型', + 'hr' => 'H&R', ], 'hit_and_run' => [ 'label' => '用戶 H&R', diff --git a/resources/lang/zh_TW/permission.php b/resources/lang/zh_TW/permission.php index da0889d6..c0a254bb 100644 --- a/resources/lang/zh_TW/permission.php +++ b/resources/lang/zh_TW/permission.php @@ -5,6 +5,10 @@ return [ 'text' => '審核種子', 'desc' => '通過種子、拒絕種子、或將種子標記為未審', ], + 'torrent-set-special-tag' => [ + 'text' => '設定種子特殊標簽', + 'desc' => '設定種子的官方、零魔標簽', + ], 'defaultclass' => [ 'text' => '預設等級', 'desc' => '註冊時獲得的等級', diff --git a/resources/lang/zh_TW/torrent.php b/resources/lang/zh_TW/torrent.php index e2d99a49..790c82e0 100644 --- a/resources/lang/zh_TW/torrent.php +++ b/resources/lang/zh_TW/torrent.php @@ -76,4 +76,9 @@ return [ 'logs_label' => '審核記錄' ], 'show_hide_media_info' => '顯示/隱藏原始 MediaInfo', + 'promotion_time_types' => [ + \App\Models\Torrent::PROMOTION_TIME_TYPE_GLOBAL => '全局', + \App\Models\Torrent::PROMOTION_TIME_TYPE_PERMANENT => '永久', + \App\Models\Torrent::PROMOTION_TIME_TYPE_DEADLINE => '直到', + ], ]; From 273730228157c9e17f61a4c96484813a7f3112bb Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Tue, 4 Oct 2022 18:43:00 +0800 Subject: [PATCH 32/59] approval allow automatic --- include/constants.php | 2 +- nexus/Install/settings.default.php | 1 + public/ipcheck.php | 23 ++++++++++++++++++----- public/settings.php | 4 +++- public/staffbox.php | 3 +++ public/takeupload.php | 3 +++ resources/lang/en/permission.php | 4 ++++ resources/lang/zh_CN/permission.php | 4 ++++ resources/lang/zh_TW/permission.php | 4 ++++ 9 files changed, 41 insertions(+), 7 deletions(-) diff --git a/include/constants.php b/include/constants.php index 3be91f9e..7ffc5c54 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ User::CLASS_ADMINISTRATOR, 'user-change-class' => User::CLASS_ADMINISTRATOR, 'torrent-set-special-tag' => User::CLASS_ADMINISTRATOR, + 'torrent-approval-allow-automatic' => User::CLASS_UPLOADER, ), 'tweak' => array ( diff --git a/public/ipcheck.php b/public/ipcheck.php index 415b54d7..e7168110 100644 --- a/public/ipcheck.php +++ b/public/ipcheck.php @@ -5,8 +5,21 @@ loggedinorreturn(); if (get_user_class() < UC_MODERATOR) stderr("Sorry", "Access denied."); -stdhead("Duplicate IP users"); -begin_frame("Duplicate IP users:", true); + +$tabs = ['users', 'peers']; +$tab = 'users'; +if (!empty($_REQUEST['tab']) && in_array($_REQUEST['tab'], $tabs)) { + $tab = $_REQUEST['tab']; +} +$page = $_REQUEST['page'] ?? 0; +$title = 'Duplicate IP users'; +stdhead($title); +print '

      '.$title.'

      '; +//print ''; begin_table(); if (get_user_class() >= UC_MODERATOR || $CURUSER["guard"] == "yes") @@ -44,7 +57,7 @@ if (get_user_class() >= UC_MODERATOR || $CURUSER["guard"] == "yes") $ratio = number_format($arr["uploaded"] / $arr["downloaded"], 3); else $ratio="---"; - + $ratio = "$ratio"; $uploaded = mksize($arr["uploaded"]); $downloaded = mksize($arr["downloaded"]); @@ -54,7 +67,7 @@ if (get_user_class() >= UC_MODERATOR || $CURUSER["guard"] == "yes") $utc = ""; else $utc = " bgcolor=\"ECE9D8\""; - + $peer_res = sql_query("SELECT count(*) FROM peers WHERE ip = " . sqlesc($ras['ip']) . " AND userid = " . $arr['id']); $peer_row = mysql_fetch_row($peer_res); print("" . get_username($arr["id"])." @@ -64,7 +77,7 @@ if (get_user_class() >= UC_MODERATOR || $CURUSER["guard"] == "yes") $downloaded $uploaded $ratio - $arr[ip]\n" . + $arr[ip]\n" . ($peer_row[0] ? "ja" : "nein") . "\n"); $ip = $arr["ip"]; } diff --git a/public/settings.php b/public/settings.php index 005d9ede..081737b9 100644 --- a/public/settings.php +++ b/public/settings.php @@ -224,7 +224,7 @@ elseif ($action == 'savesettings_authority') // save user authority 'torrentstructure','sendinvite','viewhistory','topten','log','confilog','userprofile', 'torrenthistory','prfmanage', 'cruprfmanage', 'uploadsub','delownsub','submanage','updateextinfo', 'viewanonymous','beanonymous','addoffer','offermanage', 'upload','uploadspecial', 'view_special_torrent','movetorrent','chrmanage','viewinvite', 'buyinvite','seebanned','againstoffer','userbar', 'torrent-approval', - 'torrent-delete', 'user-delete', 'user-change-class', 'torrent-set-special-tag' + 'torrent-delete', 'user-delete', 'user-change-class', 'torrent-set-special-tag', 'torrent-approval-allow-automatic' ); GetVar($validConfig); $AUTHORITY = []; @@ -454,6 +454,8 @@ elseif ($action == 'authoritysettings') //Authority settings tr($lang_settings['row_torrent_hr'], $lang_settings['text_minimum_class'].classlist('torrent_hr',$maxclass,$AUTHORITY['torrent_hr'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).$lang_settings['text_torrent_hr_note'],1); tr(nexus_trans('permission.torrent-set-special-tag.text'), $lang_settings['text_minimum_class'].classlist('torrent-set-special-tag',$maxclass,$AUTHORITY['torrent-set-special-tag'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).nexus_trans('permission.torrent-set-special-tag.desc'),1); tr(nexus_trans('permission.torrent-approval.text'), $lang_settings['text_minimum_class'].classlist('torrent-approval',$maxclass,$AUTHORITY['torrent-approval'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_ADMINISTRATOR,false,true,true).nexus_trans('permission.torrent-approval.desc'),1); + tr(nexus_trans('permission.torrent-approval-allow-automatic.text'), $lang_settings['text_minimum_class'].classlist('torrent-approval-allow-automatic',$maxclass,$AUTHORITY['torrent-approval-allow-automatic'] ?? '',0,true).$lang_settings['text_default'].get_user_class_name(UC_UPLOADER,false,true,true).nexus_trans('permission.torrent-approval-allow-automatic.desc'),1); + tr($lang_settings['row_ask_for_reseed'], $lang_settings['text_minimum_class'].classlist('askreseed',$maxclass,$AUTHORITY['askreseed'],0,true).$lang_settings['text_default'].get_user_class_name(UC_POWER_USER,false,true,true).$lang_settings['text_ask_for_reseed_note'],1); tr($lang_settings['row_view_nfo'], $lang_settings['text_minimum_class'].classlist('viewnfo',$maxclass,$AUTHORITY['viewnfo'],0,true).$lang_settings['text_default'].get_user_class_name(UC_POWER_USER,false,true,true).$lang_settings['text_view_nfo_note'],1); tr($lang_settings['row_view_torrent_structure'], $lang_settings['text_minimum_class'].classlist('torrentstructure',$maxclass,$AUTHORITY['torrentstructure'],0,true).$lang_settings['text_default'].get_user_class_name(UC_ULTIMATE_USER,false,true,true).$lang_settings['text_view_torrent_structure_note'],1); diff --git a/public/staffbox.php b/public/staffbox.php index b865cab5..764a53ee 100644 --- a/public/staffbox.php +++ b/public/staffbox.php @@ -239,6 +239,9 @@ header("Refresh: 0; url=staffbox.php?action=viewpm&pmid=$id"); ////////////////////////// if ($action == "takecontactanswered") { + if (empty($_POST['setanswered'])) { + stderr($lang_staffbox['std_sorry'], nexus_trans('nexus.select_one_please')); + } if ($_POST['setdealt']){ $res = sql_query ("SELECT * FROM staffmessages WHERE answered=0 AND id IN (" . implode(", ", $_POST['setanswered']) . ")"); diff --git a/public/takeupload.php b/public/takeupload.php index 1deef989..08bfdcdb 100644 --- a/public/takeupload.php +++ b/public/takeupload.php @@ -367,6 +367,9 @@ if(user_can('torrentmanage') && ($CURUSER['picker'] == 'yes' || get_user_class() } } } +if (user_can('torrent-approval-allow-automatic')) { + $insert['approval_status'] = \App\Models\Torrent::APPROVAL_STATUS_ALLOW; +} do_log("[INSERT_TORRENT]: " . nexus_json_encode($insert)); $id = \Nexus\Database\NexusDB::insert('torrents', $insert); diff --git a/resources/lang/en/permission.php b/resources/lang/en/permission.php index 3555f17e..fa0c5a1c 100644 --- a/resources/lang/en/permission.php +++ b/resources/lang/en/permission.php @@ -9,6 +9,10 @@ return [ 'text' => 'Set torrent special tags', 'desc' => 'Set the Official/Zero bonus tag to torrents', ], + 'torrent-approval-allow-automatic' => [ + 'text' => 'Torrent approval allow automatically', + 'desc' => 'Torrent is the approval allow status after upload automatically', + ], 'defaultclass' => [ 'text' => 'Default Class', 'desc' => ' Class upon registration', diff --git a/resources/lang/zh_CN/permission.php b/resources/lang/zh_CN/permission.php index 8d85f91f..5d1dbb7b 100644 --- a/resources/lang/zh_CN/permission.php +++ b/resources/lang/zh_CN/permission.php @@ -9,6 +9,10 @@ return [ 'text' => '设定种子特殊标签', 'desc' => '设定种子的官方、零魔标签', ], + 'torrent-approval-allow-automatic' => [ + 'text' => '种子自动通过审核', + 'desc' => '种子发布即为审核通过状态', + ], 'defaultclass' => [ 'text' => '默认等级', 'desc' => '注册时获得的等级', diff --git a/resources/lang/zh_TW/permission.php b/resources/lang/zh_TW/permission.php index c0a254bb..95cb74ca 100644 --- a/resources/lang/zh_TW/permission.php +++ b/resources/lang/zh_TW/permission.php @@ -9,6 +9,10 @@ return [ 'text' => '設定種子特殊標簽', 'desc' => '設定種子的官方、零魔標簽', ], + 'torrent-approval-allow-automatic' => [ + 'text' => '種子自動通過審核', + 'desc' => '種子發布即為審核通過狀態', + ], 'defaultclass' => [ 'text' => '預設等級', 'desc' => '註冊時獲得的等級', From fac5ad3cc863e59b2ea67a45d7e129d919055e4e Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 6 Oct 2022 18:19:39 +0800 Subject: [PATCH 33/59] admin user add link + upload over speed msg --- .../Resources/System/UsernameChangeLogResource.php | 12 ++++++++++-- app/Filament/Resources/Torrent/TorrentResource.php | 3 +-- app/Filament/Resources/User/ClaimResource.php | 7 ++++++- app/Filament/Resources/User/ExamUserResource.php | 7 ++++++- app/Filament/Resources/User/HitAndRunResource.php | 8 +++++++- app/Filament/Resources/User/UserMedalResource.php | 7 ++++++- app/Filament/Resources/User/UserResource.php | 2 +- app/Models/HitAndRun.php | 5 +++++ app/Repositories/HitAndRunRepository.php | 2 +- app/Repositories/TrackerRepository.php | 2 +- app/Repositories/UserRepository.php | 10 +++++++--- include/constants.php | 2 +- public/announce.php | 2 +- public/myhr.php | 2 +- resources/lang/en/message.php | 6 +++++- resources/lang/zh_CN/message.php | 4 ++++ resources/lang/zh_TW/message.php | 4 ++++ 17 files changed, 67 insertions(+), 18 deletions(-) diff --git a/app/Filament/Resources/System/UsernameChangeLogResource.php b/app/Filament/Resources/System/UsernameChangeLogResource.php index f9a5e6a6..57e2cc47 100644 --- a/app/Filament/Resources/System/UsernameChangeLogResource.php +++ b/app/Filament/Resources/System/UsernameChangeLogResource.php @@ -12,6 +12,7 @@ use Filament\Resources\Table; use Filament\Tables; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Support\HtmlString; class UsernameChangeLogResource extends Resource { @@ -50,8 +51,15 @@ class UsernameChangeLogResource extends Resource Tables\Columns\TextColumn::make('uid')->searchable(), Tables\Columns\TextColumn::make('user.username')->searchable()->label(__('label.username')), Tables\Columns\TextColumn::make('username_old')->searchable()->label(__('username-change-log.labels.username_old')), - Tables\Columns\TextColumn::make('username_new')->searchable()->label(__('username-change-log.labels.username_new')), - Tables\Columns\TextColumn::make('operator')->searchable()->label(__('label.operator')), + Tables\Columns\TextColumn::make('username_new') + ->searchable() + ->label(__('username-change-log.labels.username_new')) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + , + Tables\Columns\TextColumn::make('operator') + ->searchable() + ->label(__('label.operator')) + , Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at'))->formatStateUsing(fn ($state) => format_datetime($state)), ]) diff --git a/app/Filament/Resources/Torrent/TorrentResource.php b/app/Filament/Resources/Torrent/TorrentResource.php index f4b09701..04771692 100644 --- a/app/Filament/Resources/Torrent/TorrentResource.php +++ b/app/Filament/Resources/Torrent/TorrentResource.php @@ -103,8 +103,7 @@ class TorrentResource extends Resource Tables\Columns\TextColumn::make('added')->label(__('label.added'))->dateTime(), Tables\Columns\TextColumn::make('user.username') ->label(__('label.torrent.owner')) - ->url(fn ($record) => sprintf('/userdetails.php?id=%s', $record->owner)) - ->openUrlInNewTab(true) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->owner, false, true, true, true))) , ]) ->defaultSort('id', 'desc') diff --git a/app/Filament/Resources/User/ClaimResource.php b/app/Filament/Resources/User/ClaimResource.php index d7970ce8..f0b77c1f 100644 --- a/app/Filament/Resources/User/ClaimResource.php +++ b/app/Filament/Resources/User/ClaimResource.php @@ -13,6 +13,7 @@ use Filament\Tables; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Support\HtmlString; class ClaimResource extends Resource { @@ -48,7 +49,11 @@ class ClaimResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('uid')->searchable(), - Tables\Columns\TextColumn::make('user.username')->label(__('label.user.label'))->searchable(), + Tables\Columns\TextColumn::make('user.username') + ->label(__('label.user.label')) + ->searchable() + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + , Tables\Columns\TextColumn::make('torrent.name')->limit(40)->label(__('label.torrent.label'))->searchable(), Tables\Columns\TextColumn::make('torrent.size')->label(__('label.torrent.size'))->formatStateUsing(fn (Model $record) => mksize($record->torrent->size)), Tables\Columns\TextColumn::make('torrent.added')->label(__('label.torrent.ttl'))->formatStateUsing(fn (Model $record) => mkprettytime($record->torrent->added->diffInSeconds())), diff --git a/app/Filament/Resources/User/ExamUserResource.php b/app/Filament/Resources/User/ExamUserResource.php index b1b24dae..e8a2226b 100644 --- a/app/Filament/Resources/User/ExamUserResource.php +++ b/app/Filament/Resources/User/ExamUserResource.php @@ -16,6 +16,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\HtmlString; class ExamUserResource extends Resource { @@ -51,7 +52,11 @@ class ExamUserResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('uid')->searchable(), - Tables\Columns\TextColumn::make('user.username')->label(__('label.username'))->searchable(), + Tables\Columns\TextColumn::make('user.username') + ->label(__('label.username')) + ->searchable() + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + , Tables\Columns\TextColumn::make('exam.name')->label(__('label.exam.label')), Tables\Columns\TextColumn::make('begin')->label(__('label.begin'))->dateTime(), Tables\Columns\TextColumn::make('end')->label(__('label.end'))->dateTime(), diff --git a/app/Filament/Resources/User/HitAndRunResource.php b/app/Filament/Resources/User/HitAndRunResource.php index 654df0cb..cca3645a 100644 --- a/app/Filament/Resources/User/HitAndRunResource.php +++ b/app/Filament/Resources/User/HitAndRunResource.php @@ -15,6 +15,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\HtmlString; class HitAndRunResource extends Resource { @@ -42,7 +43,12 @@ class HitAndRunResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('uid')->searchable(), - Tables\Columns\TextColumn::make('user.username')->searchable()->label(__('label.username')), + Tables\Columns\TextColumn::make('user.username') + ->searchable() + ->label(__('label.username')) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + , + Tables\Columns\TextColumn::make('torrent.name')->limit(30)->label(__('label.torrent.label')), Tables\Columns\TextColumn::make('snatch.uploadText')->label(__('label.uploaded')), Tables\Columns\TextColumn::make('snatch.downloadText')->label(__('label.downloaded')), diff --git a/app/Filament/Resources/User/UserMedalResource.php b/app/Filament/Resources/User/UserMedalResource.php index 7d83cfc4..c790aa38 100644 --- a/app/Filament/Resources/User/UserMedalResource.php +++ b/app/Filament/Resources/User/UserMedalResource.php @@ -12,6 +12,7 @@ use Filament\Resources\Table; use Filament\Tables; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Support\HtmlString; class UserMedalResource extends Resource { @@ -47,7 +48,11 @@ class UserMedalResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('uid')->searchable(), - Tables\Columns\TextColumn::make('user.username')->label(__('label.username'))->searchable(), + Tables\Columns\TextColumn::make('user.username') + ->label(__('label.username')) + ->searchable() + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + , Tables\Columns\TextColumn::make('medal.name')->label(__('label.medal.label'))->searchable(), Tables\Columns\ImageColumn::make('medal.image_large')->label(__('label.image')), Tables\Columns\TextColumn::make('expire_at')->label(__('label.expire_at'))->dateTime(), diff --git a/app/Filament/Resources/User/UserResource.php b/app/Filament/Resources/User/UserResource.php index e2f86cde..9e32fc54 100644 --- a/app/Filament/Resources/User/UserResource.php +++ b/app/Filament/Resources/User/UserResource.php @@ -61,7 +61,7 @@ class UserResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id')->sortable()->searchable(), Tables\Columns\TextColumn::make('username')->searchable()->label(__("label.user.username")) - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, false, true))), + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))), Tables\Columns\TextColumn::make('email')->searchable()->label(__("label.email")), Tables\Columns\TextColumn::make('class')->label('Class') ->formatStateUsing(fn(Tables\Columns\Column $column) => $column->getRecord()->classText) diff --git a/app/Models/HitAndRun.php b/app/Models/HitAndRun.php index 621a53d6..c93fc77c 100644 --- a/app/Models/HitAndRun.php +++ b/app/Models/HitAndRun.php @@ -26,6 +26,11 @@ class HitAndRun extends NexusModel self::STATUS_PARDONED => ['text' => 'Pardoned'], ]; + const CAN_PARDON_STATUS = [ + self::STATUS_INSPECTING, + self::STATUS_UNREACHED, + ]; + const MODE_DISABLED = 'disabled'; const MODE_MANUAL = 'manual'; const MODE_GLOBAL = 'global'; diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index 52f3bf37..567898e9 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -464,7 +464,7 @@ class HitAndRunRepository extends BaseRepository private function getCanPardonStatus(): array { - return [HitAndRun::STATUS_INSPECTING, HitAndRun::STATUS_UNREACHED]; + return HitAndRun::CAN_PARDON_STATUS; } public function renderOnUploadPage($value, $searchBoxId): string diff --git a/app/Repositories/TrackerRepository.php b/app/Repositories/TrackerRepository.php index 85f8795c..c438d3b0 100644 --- a/app/Repositories/TrackerRepository.php +++ b/app/Repositories/TrackerRepository.php @@ -593,7 +593,7 @@ class TrackerRepository extends BaseRepository $notSeedBoxMaxSpeedMbps = Setting::get('seed_box.not_seed_box_max_speed'); do_log("upSpeedMbps: $upSpeedMbps, notSeedBoxMaxSpeedMbps: $notSeedBoxMaxSpeedMbps"); if ($upSpeedMbps > $notSeedBoxMaxSpeedMbps) { - (new \App\Repositories\UserRepository())->updateDownloadPrivileges(null, $user, 'no'); + (new \App\Repositories\UserRepository())->updateDownloadPrivileges(null, $user, 'no', 'upload_over_speed'); do_log("user: {$user->id} downloading privileges have been disabled! (over speed)", 'error'); throw new TrackerException("Your downloading privileges have been disabled! (over speed)"); } diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index fccf5f78..a72290f5 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -326,7 +326,7 @@ class UserRepository extends BaseRepository } - public function updateDownloadPrivileges($operator, $user, $status) + public function updateDownloadPrivileges($operator, $user, $status, $disableReasonKey = null) { if (!in_array($status, ['yes', 'no'])) { throw new \InvalidArgumentException("Invalid status: $status"); @@ -345,8 +345,12 @@ class UserRepository extends BaseRepository if ($status == 'no') { $update = ['downloadpos' => 'no']; $modComment = date('Y-m-d') . " - Download disable by " . $operatorUsername; - $message['subject'] = nexus_trans('message.download_disable.subject', [], $targetUser->locale); - $message['msg'] = nexus_trans('message.download_disable.body', ['operator' => $operatorUsername], $targetUser->locale); + $msgTransPrefix = "message.download_disable"; + if ($disableReasonKey !== null) { + $msgTransPrefix .= "_$disableReasonKey"; + } + $message['subject'] = nexus_trans("$msgTransPrefix.subject", [], $targetUser->locale); + $message['msg'] = nexus_trans("$msgTransPrefix.body", ['operator' => $operatorUsername], $targetUser->locale); } else { $update = ['downloadpos' => 'yes']; $modComment = date('Y-m-d') . " - Download enable by " . $operatorUsername; diff --git a/include/constants.php b/include/constants.php index 7ffc5c54..d7416b2d 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ $notSeedBoxMaxSpeedMbps) { - (new \App\Repositories\UserRepository())->updateDownloadPrivileges(null, $userid, 'no'); + (new \App\Repositories\UserRepository())->updateDownloadPrivileges(null, $userid, 'no', 'upload_over_speed'); do_log("user: $userid downloading privileges have been disabled! (over speed), notSeedBoxMaxSpeedMbps: $notSeedBoxMaxSpeedMbps > upSpeedMbps: $upSpeedMbps", 'error'); err("Your downloading privileges have been disabled! (over speed)"); } diff --git a/public/myhr.php b/public/myhr.php index 04d87071..e5730e0f 100644 --- a/public/myhr.php +++ b/public/myhr.php @@ -83,7 +83,7 @@ if ($rescount) { $hasActionRemove = false; foreach($list as $row) { $columnAction = ''; - if ($row->uid == $CURUSER['id'] && $row->status == \App\Models\HitAndRun::STATUS_INSPECTING) { + if ($row->uid == $CURUSER['id'] && in_array($row->status, \App\Models\HitAndRun::CAN_PARDON_STATUS)) { $hasActionRemove = true; $columnAction .= sprintf('', $lang_myhr['action_remove'], $row->id); } diff --git a/resources/lang/en/message.php b/resources/lang/en/message.php index c9fb81d4..3d27859b 100644 --- a/resources/lang/en/message.php +++ b/resources/lang/en/message.php @@ -12,9 +12,13 @@ return [ 'field_value_change_message_subject' => ':field changed', 'download_disable' => [ - 'subject' => 'Download permission cancellation', + 'subject' => 'Download permission canceled', 'body' => 'Your download privileges has revoked, possibly due to low sharing rates or misbehavior. By: :operator', ], + 'download_disable_upload_over_speed' => [ + 'subject' => 'Download permission canceled', + 'body' => 'Your download permission has been cancelled due to excessive upload speed, please file if you are a seed box user.' , + ], 'download_enable' => [ 'subject' => 'Download permission restored', 'body' => 'Your download privileges restored, you can now download torrents. By: :operator', diff --git a/resources/lang/zh_CN/message.php b/resources/lang/zh_CN/message.php index 30ff49e6..f030b00e 100644 --- a/resources/lang/zh_CN/message.php +++ b/resources/lang/zh_CN/message.php @@ -15,6 +15,10 @@ return [ 'subject' => '下载权限取消', 'body' => '你的下载权限被取消,可能的原因是过低的分享率或行为不当。By: :operator', ], + 'download_disable_upload_over_speed' => [ + 'subject' => '下载权限取消', + 'body' => '你因上传速度过快下载权限被取消,若是盒子用户请备案。', + ], 'download_enable' => [ 'subject' => '下载权限恢复', 'body' => '你的下载权限恢复,你现在可以下载种子。By: :operator', diff --git a/resources/lang/zh_TW/message.php b/resources/lang/zh_TW/message.php index b2978f75..99aaceb2 100644 --- a/resources/lang/zh_TW/message.php +++ b/resources/lang/zh_TW/message.php @@ -14,6 +14,10 @@ return [ 'subject' => '下載權限取消', 'body' => '你的下載權限被取消,可能的原因是過低的分享率或行為不當。By: :operator', ], + 'download_disable_upload_over_speed' => [ + 'subject' => '下載權限取消', + 'body' => '你因上傳速度過快下載權限被取消,若是盒子用戶請備案。', + ], 'download_enable' => [ 'subject' => '下載權限恢復', 'body' => '你的下載權限恢復,你現在可以下載種子。By: :operator', From 2c41009111cfef74ddf2c116f8bf58daf7c43670 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 6 Oct 2022 18:31:16 +0800 Subject: [PATCH 34/59] fix trans --- resources/lang/en/nexus.php | 1 + resources/lang/zh_CN/nexus.php | 1 + resources/lang/zh_TW/nexus.php | 1 + 3 files changed, 3 insertions(+) diff --git a/resources/lang/en/nexus.php b/resources/lang/en/nexus.php index 8637dd30..bd9196f0 100644 --- a/resources/lang/en/nexus.php +++ b/resources/lang/en/nexus.php @@ -4,4 +4,5 @@ return [ 'invalid_argument' => 'Invalid argument', 'require_argument' => ':argument cannot be empty', 'select_one_please' => 'Please select one', + 'user_not_exists' => '(orphaned)', ]; diff --git a/resources/lang/zh_CN/nexus.php b/resources/lang/zh_CN/nexus.php index 5b4c8ffa..9d206b96 100644 --- a/resources/lang/zh_CN/nexus.php +++ b/resources/lang/zh_CN/nexus.php @@ -4,4 +4,5 @@ return [ 'invalid_argument' => '参数错误', 'require_argument' => ':argument 不能为空', 'select_one_please' => '请选择一项', + 'user_not_exists' => '(无此帐户)', ]; diff --git a/resources/lang/zh_TW/nexus.php b/resources/lang/zh_TW/nexus.php index 6bc71b91..2fd6b606 100644 --- a/resources/lang/zh_TW/nexus.php +++ b/resources/lang/zh_TW/nexus.php @@ -4,4 +4,5 @@ return [ 'invalid_argument' => '參數錯誤', 'require_argument' => ':argument 不能為空', 'select_one_please' => '請選擇一項', + 'user_not_exists' => '(無此帳戶)', ]; From 00fc2293cd38b03788f88b928581d12921548125 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 6 Oct 2022 18:34:33 +0800 Subject: [PATCH 35/59] get_user_row() use nexus_trans() --- include/functions.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/functions.php b/include/functions.php index 89052420..df41c9eb 100644 --- a/include/functions.php +++ b/include/functions.php @@ -3734,7 +3734,6 @@ create_tooltip_container($torrent_tooltip, 500); function get_username($id, $big = false, $link = true, $bold = true, $target = false, $bracket = false, $withtitle = false, $link_ext = "", $underline = false) { static $usernameArray = array(); - global $lang_functions; $id = (int)$id; if (func_num_args() == 1 && isset($usernameArray[$id])) { //One argument=is default display of username. Get it directly from static array if available @@ -3813,7 +3812,7 @@ function get_username($id, $big = false, $link = true, $bold = true, $target = f } else { - $username = "".$lang_functions['text_orphaned'].""; + $username = "".nexus_trans('nexus.user_not_exists').""; $username = "" . ( $bracket == true ? "(" . $username . ")" : $username) . ""; } if (func_num_args() == 1) { //One argument=is default display of username, save it in static array From 9865fed808f4cecc0fbe39a43a22dbf76edad67d Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Fri, 7 Oct 2022 02:51:52 +0800 Subject: [PATCH 36/59] [admin] fix user link --- app/Filament/Resources/System/UsernameChangeLogResource.php | 2 +- app/Filament/Resources/User/ClaimResource.php | 2 +- app/Filament/Resources/User/ExamUserResource.php | 2 +- app/Filament/Resources/User/HitAndRunResource.php | 2 +- app/Filament/Resources/User/UserMedalResource.php | 2 +- include/constants.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Filament/Resources/System/UsernameChangeLogResource.php b/app/Filament/Resources/System/UsernameChangeLogResource.php index 57e2cc47..aff1d66b 100644 --- a/app/Filament/Resources/System/UsernameChangeLogResource.php +++ b/app/Filament/Resources/System/UsernameChangeLogResource.php @@ -54,7 +54,7 @@ class UsernameChangeLogResource extends Resource Tables\Columns\TextColumn::make('username_new') ->searchable() ->label(__('username-change-log.labels.username_new')) - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->uid, false, true, true, true))) , Tables\Columns\TextColumn::make('operator') ->searchable() diff --git a/app/Filament/Resources/User/ClaimResource.php b/app/Filament/Resources/User/ClaimResource.php index f0b77c1f..0bc70183 100644 --- a/app/Filament/Resources/User/ClaimResource.php +++ b/app/Filament/Resources/User/ClaimResource.php @@ -52,7 +52,7 @@ class ClaimResource extends Resource Tables\Columns\TextColumn::make('user.username') ->label(__('label.user.label')) ->searchable() - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->uid, false, true, true, true))) , Tables\Columns\TextColumn::make('torrent.name')->limit(40)->label(__('label.torrent.label'))->searchable(), Tables\Columns\TextColumn::make('torrent.size')->label(__('label.torrent.size'))->formatStateUsing(fn (Model $record) => mksize($record->torrent->size)), diff --git a/app/Filament/Resources/User/ExamUserResource.php b/app/Filament/Resources/User/ExamUserResource.php index e8a2226b..9d439447 100644 --- a/app/Filament/Resources/User/ExamUserResource.php +++ b/app/Filament/Resources/User/ExamUserResource.php @@ -55,7 +55,7 @@ class ExamUserResource extends Resource Tables\Columns\TextColumn::make('user.username') ->label(__('label.username')) ->searchable() - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->uid, false, true, true, true))) , Tables\Columns\TextColumn::make('exam.name')->label(__('label.exam.label')), Tables\Columns\TextColumn::make('begin')->label(__('label.begin'))->dateTime(), diff --git a/app/Filament/Resources/User/HitAndRunResource.php b/app/Filament/Resources/User/HitAndRunResource.php index cca3645a..dc90ede1 100644 --- a/app/Filament/Resources/User/HitAndRunResource.php +++ b/app/Filament/Resources/User/HitAndRunResource.php @@ -46,7 +46,7 @@ class HitAndRunResource extends Resource Tables\Columns\TextColumn::make('user.username') ->searchable() ->label(__('label.username')) - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->uid, false, true, true, true))) , Tables\Columns\TextColumn::make('torrent.name')->limit(30)->label(__('label.torrent.label')), diff --git a/app/Filament/Resources/User/UserMedalResource.php b/app/Filament/Resources/User/UserMedalResource.php index c790aa38..9ef4f34b 100644 --- a/app/Filament/Resources/User/UserMedalResource.php +++ b/app/Filament/Resources/User/UserMedalResource.php @@ -51,7 +51,7 @@ class UserMedalResource extends Resource Tables\Columns\TextColumn::make('user.username') ->label(__('label.username')) ->searchable() - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->id, false, true, true, true))) + ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->uid, false, true, true, true))) , Tables\Columns\TextColumn::make('medal.name')->label(__('label.medal.label'))->searchable(), Tables\Columns\ImageColumn::make('medal.image_large')->label(__('label.image')), diff --git a/include/constants.php b/include/constants.php index d7416b2d..9b7b03c8 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ Date: Sun, 9 Oct 2022 02:30:11 +0800 Subject: [PATCH 37/59] fix userdetails page BT client SeedBox icon --- README-EN.md | 1 + README.md | 1 + include/constants.php | 4 ++-- public/userdetails.php | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README-EN.md b/README-EN.md index a8d258e1..1c8bbe9a 100644 --- a/README-EN.md +++ b/README-EN.md @@ -34,6 +34,7 @@ Complete PT website building solution. Based on NexusPHP + Laravel + Filament. - Custom menu - Lucky draw - Custom role permission +- Section H&R ## System Requirements - PHP: 8.0, must have extensions: bcmath, ctype, curl, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, mysqli, gd, redis, pcntl, sockets, posix, gmp - Mysql: 5.7 latest version or above diff --git a/README.md b/README.md index 9e7b4285..bfb4d790 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ - 自定义菜单 - 幸运大转盘 - 自定义角色权限 +- 分区 H&R ## 系统要求 - PHP: 8.0,必须扩展:bcmath, ctype, curl, fileinfo, json, mbstring, openssl, pdo_mysql, tokenizer, xml, mysqli, gd, redis, pcntl, sockets, posix, gmp diff --git a/include/constants.php b/include/constants.php index 9b7b03c8..67c10ccb 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ 0) $clientselect .= ""; $clientselect .= sprintf('%s', get_agent($arr['peer_id'], $arr['agent'])); if (user_can('userprofile') || $user["id"] == $CURUSER["id"]) { - $clientselect .= sprintf('%s%s%s', $arr['ipv4'].$seedBoxRep->renderIcon($arr['ipv4'], $CURUSER['id']), $arr['ipv6'].$seedBoxRep->renderIcon($arr['ipv6'], $CURUSER['id']), $arr['port']); + $clientselect .= sprintf('%s%s%s', $arr['ipv4'].$seedBoxRep->renderIcon($arr['ipv4'], $user['id']), $arr['ipv6'].$seedBoxRep->renderIcon($arr['ipv6'], $user['id']), $arr['port']); } else { $clientselect .= sprintf('%s%s%s', '---', '---', '---'); } From 0bdfc73528a2dd2a16223ac2d71dee3326cb747c Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 10 Oct 2022 01:36:35 +0800 Subject: [PATCH 38/59] fix addMeta deadine --- .../User/UserResource/Pages/UserProfile.php | 5 ----- app/Repositories/UserRepository.php | 22 +++++++++++++++++-- include/constants.php | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/app/Filament/Resources/User/UserResource/Pages/UserProfile.php b/app/Filament/Resources/User/UserResource/Pages/UserProfile.php index dfec0818..5a45a121 100644 --- a/app/Filament/Resources/User/UserResource/Pages/UserProfile.php +++ b/app/Filament/Resources/User/UserResource/Pages/UserProfile.php @@ -278,11 +278,6 @@ class UserProfile extends ViewRecord ->action(function ($data) { $rep = $this->getRep(); try { - if (!empty($data['duration'])) { - $data['deadline'] = now()->addDays($data['duration']); - } else { - $data['deadline'] = null; - } $rep->addMeta($this->record, $data, $data); $this->notify('success', 'Success!'); $this->emitSelf(self::EVENT_RECORD_UPDATED, $this->record->id); diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index a72290f5..b2b37efa 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -467,23 +467,41 @@ class UserRepository extends BaseRepository $user = $this->getUser($user); $metaKey = $metaData['meta_key']; $allowMultiple = UserMeta::$metaKeys[$metaKey]['multiple']; + $log = "user: {$user->id}, metaKey: $metaKey, allowMultiple: $allowMultiple"; if ($allowMultiple) { //Allow multiple, just insert $result = $user->metas()->create($metaData); + $log .= ", allowMultiple, just insert"; } else { $metaExists = $user->metas()->where('meta_key', $metaKey)->first(); + $log .= ", metaExists: " . ($metaExists->id ?? ''); if (!$metaExists) { $result = $user->metas()->create($metaData); + $log .= ", meta not exists, just create"; } else { - if (empty($keyExistsUpdates)) { - $keyExistsUpdates = ['updated_at' => now()]; + $log .= ", meta exists"; + $keyExistsUpdates['updated_at'] = now(); + if (!empty($keyExistsUpdates['duration'])) { + $log .= ", has duration: {$keyExistsUpdates['duration']}"; + if ($metaExists->deadline && $metaExists->deadline->gte(now())) { + $log .= ", not expire"; + $keyExistsUpdates['deadline'] = $metaExists->deadline->addDays($keyExistsUpdates['duration']); + } else { + $log .= ", expired or not set"; + $keyExistsUpdates['deadline'] = now()->addDays($keyExistsUpdates['duration']); + } + unset($keyExistsUpdates['duration']); + } else { + $keyExistsUpdates['deadline'] = null; } + $log .= ", update: " . json_encode($keyExistsUpdates); $result = $metaExists->update($keyExistsUpdates); } } if ($result) { clear_user_cache($user->id, $user->passkey); } + do_log($log); return $result; } diff --git a/include/constants.php b/include/constants.php index 67c10ccb..ae443d6e 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ Date: Wed, 12 Oct 2022 01:42:43 +0800 Subject: [PATCH 39/59] fix user that has permission can not see uploader on torrent table --- include/constants.php | 2 +- include/functions.php | 2 +- public/details.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/constants.php b/include/constants.php index ae443d6e..4f96d1f0 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ ".$lang_functions['text_anonymous']."
      ".(isset($row["owner"]) ? "(" . get_username($row["owner"]) .")" : "".$lang_functions['text_orphaned']."") . "\n"); } diff --git a/public/details.php b/public/details.php index 33bbeb9f..b6a440bd 100644 --- a/public/details.php +++ b/public/details.php @@ -101,7 +101,7 @@ if (!$row) { // ------------- start upped by block ------------------// if($row['anonymous'] == 'yes') { - if (!user_can('viewanonymous')) + if (!user_can('viewanonymous') && $row['owner'] != $CURUSER['id']) $uprow = "".$lang_details['text_anonymous'].""; else $uprow = "".$lang_details['text_anonymous']." (" . get_username($row['owner'], false, true, true, false, false, true) . ")"; From 0a9f3e4e140449f08fd7b7b739439db5ed58fc5e Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Wed, 12 Oct 2022 19:37:02 +0800 Subject: [PATCH 40/59] bonus show counts + size + A value and fix H&R stats --- app/Repositories/HitAndRunRepository.php | 9 +++++++-- include/functions.php | 13 +++++++++---- include/globalfunctions.php | 6 +++--- lang/chs/lang_mybonus.php | 3 +++ lang/cht/lang_mybonus.php | 3 +++ lang/en/lang_mybonus.php | 3 +++ public/mybonus.php | 17 +++++++++++++---- 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index 567898e9..f976598e 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -386,6 +386,7 @@ class HitAndRunRepository extends BaseRepository $sql = "select hit_and_runs.status, count(*) as counts from hit_and_runs where uid = $uid group by status"; } $results = NexusDB::select($sql); + do_log("user: $uid, sql: $sql, results: " . json_encode($results)); if (!$formatted) { return $results; } @@ -406,12 +407,16 @@ class HitAndRunRepository extends BaseRepository } return implode(" ", $out); } else { + $grouped = []; + foreach ($results as $item) { + $grouped[$item['status']] = $item['counts']; + } foreach (SearchBox::listSections() as $key => $info) { if ($key == SearchBox::SECTION_BROWSE) { return sprintf( '%s/%s/%s', - $results[HitAndRun::STATUS_INSPECTING] ?? 0, - $results[HitAndRun::STATUS_UNREACHED] ?? 0, + $grouped[HitAndRun::STATUS_INSPECTING] ?? 0, + $grouped[HitAndRun::STATUS_UNREACHED] ?? 0, HitAndRun::getConfig('ban_user_when_counts_reach', $info['mode']) ); } diff --git a/include/functions.php b/include/functions.php index 003f6636..4f356865 100644 --- a/include/functions.php +++ b/include/functions.php @@ -5867,8 +5867,8 @@ function calculate_seed_bonus($uid, $torrentIdArr = null): array $timenow = time(); $sectoweek = 7*24*60*60; - $A = 0; - $count = $torrent_peer_count = 0; + $A = $official_a = $size = $official_size = 0; + $count = $torrent_peer_count = $official_torrent_peer_count = 0; $logPrefix = "[CALCULATE_SEED_BONUS], uid: $uid, torrentIdArr: " . json_encode($torrentIdArr); if ($torrentIdArr !== null) { if (empty($torrentIdArr)) { @@ -5893,9 +5893,9 @@ function calculate_seed_bonus($uid, $torrentIdArr = null): array $zeroBonusTag = \App\Models\Setting::get('bonus.zero_bonus_tag'); $zeroBonusFactor = \App\Models\Setting::get('bonus.zero_bonus_factor'); do_log("$logPrefix, sql: $sql, count: " . count($torrentResult) . ", officialTag: $officialTag, officialAdditionalFactor: $officialAdditionalFactor, zeroBonusTag: $zeroBonusTag, zeroBonusFactor: $zeroBonusFactor"); - $official_a = 0; foreach ($torrentResult as $torrent) { + $size = bcadd($size, $torrent['size']); $weeks_alive = ($timenow - strtotime($torrent['added'])) / $sectoweek; $gb_size = $gb_size_raw = $torrent['size'] / 1073741824; if ($zeroBonusTag && isset($tagGrouped[$torrent['id']][$zeroBonusTag]) && is_numeric($zeroBonusFactor)) { @@ -5908,6 +5908,8 @@ function calculate_seed_bonus($uid, $torrentIdArr = null): array $officialAIncrease = 0; if ($officialTag && isset($tagGrouped[$torrent['id']][$officialTag])) { $officialAIncrease = $temp; + $official_torrent_peer_count++; + $official_size = bcadd($official_size, $torrent['size']); } $official_a += $officialAIncrease; do_log(sprintf( @@ -5920,7 +5922,10 @@ function calculate_seed_bonus($uid, $torrentIdArr = null): array $seed_bonus = $seed_points = $valuetwo * atan($A / $l_bonus) + ($perseeding_bonus * $count); //Official addition don't think about the minimum value $official_bonus = $valuetwo * atan($official_a / $l_bonus); - $result = compact('seed_points','seed_bonus', 'A', 'count', 'torrent_peer_count', 'official_a', 'official_bonus'); + $result = compact( + 'seed_points','seed_bonus', 'A', 'count', 'torrent_peer_count', 'size', + 'official_bonus', 'official_a', 'official_torrent_peer_count', 'official_size' + ); $result['donor_times'] = $donortimes_bonus; $result['official_additional_factor'] = $officialAdditionalFactor; do_log("$logPrefix, result: " . json_encode($result)); diff --git a/include/globalfunctions.php b/include/globalfunctions.php index 51d23737..5fffd7fe 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -867,8 +867,8 @@ function getDataTraffic(array $torrent, array $queries, array $user, $peer, $sna throw new \InvalidArgumentException("user no '__is_donor' field"); } $log = sprintf( - "torrent: %s, user: %s, peerUploaded: %s, peerDownloaded: %s, queriesUploaded: %s, queriesDownloaded: %s", - $torrent['id'], $user['id'], $peer['uploaded'] ?? '', $peer['downloaded'] ?? '', $queries['uploaded'], $queries['downloaded'] + "torrent: %s, owner: %s, user: %s, peerUploaded: %s, peerDownloaded: %s, queriesUploaded: %s, queriesDownloaded: %s", + $torrent['id'], $torrent['owner'], $user['id'], $peer['uploaded'] ?? '', $peer['downloaded'] ?? '', $queries['uploaded'], $queries['downloaded'] ); if (!empty($peer)) { $realUploaded = max(bcsub($queries['uploaded'], $peer['uploaded']), 0); @@ -930,7 +930,7 @@ function getDataTraffic(array $torrent, array $queries, array $user, $peer, $sna */ $isSeedBoxRuleEnabled = get_setting('seed_box.enabled') == 'yes'; $log .= ", isSeedBoxRuleEnabled: $isSeedBoxRuleEnabled, user class: {$user['class']}, __is_donor: {$user['__is_donor']}"; - if ($isSeedBoxRuleEnabled && !($user['class'] >= \App\Models\User::CLASS_VIP || $user['__is_donor'])) { + if ($isSeedBoxRuleEnabled && $torrent['owner'] != $user['id'] && !($user['class'] >= \App\Models\User::CLASS_VIP || $user['__is_donor'])) { $isIPSeedBox = isIPSeedBox($queries['ip'], $user['id']); $log .= ", isIPSeedBox: $isIPSeedBox"; if ($isIPSeedBox) { diff --git a/lang/chs/lang_mybonus.php b/lang/chs/lang_mybonus.php index 4f7f4b6b..98999c84 100644 --- a/lang/chs/lang_mybonus.php +++ b/lang/chs/lang_mybonus.php @@ -153,6 +153,9 @@ $lang_mybonus = array 'harem_additional_desc' => '后宫只考虑直属后宫。每个后宫加成值可在此查看', 'harem_additional_factor' => '所得奖励为全部后宫的时魔(不考虑加成)之和,乘以后宫加成系数,当前值为:', 'text_bonus_summary' => '每小时获得的合计魔力值', + 'col_count' => '数量', + 'col_size' => '体积', + 'col_a' => 'A 值', ); ?> diff --git a/lang/cht/lang_mybonus.php b/lang/cht/lang_mybonus.php index c71668e2..6fb176ba 100644 --- a/lang/cht/lang_mybonus.php +++ b/lang/cht/lang_mybonus.php @@ -153,6 +153,9 @@ $lang_mybonus = array 'harem_additional_desc' => '後宮只考慮直屬後宮。每個後宮加成值可在此查看', 'harem_additional_factor' => '所得獎勵為全部後宮的時魔(不考慮加成)之和,乘以後宮加成系數,當前值為:', 'text_bonus_summary' => '每小時獲得的合計魔力值', + 'col_count' => '數量', + 'col_size' => '體積', + 'col_a' => 'A 值', ); ?> diff --git a/lang/en/lang_mybonus.php b/lang/en/lang_mybonus.php index f42e096d..83b6717e 100644 --- a/lang/en/lang_mybonus.php +++ b/lang/en/lang_mybonus.php @@ -153,6 +153,9 @@ where
      • A is an intermediate variable
      • Ti is the i< 'harem_additional_desc' => "Only direct harems will be considered for the harem. Each harem's bonus addition value can be viewed here", 'harem_additional_factor' => 'The reward obtained is the sum of the hourly bonus of all the harems (regardless of the addition), multiplied by the harem bonus factor, with the current value of ', 'text_bonus_summary' => 'Total bonus gained per hour', + 'col_count' => 'Counts', + 'col_size' => 'Size', + 'col_a' => 'A Value', ); ?> diff --git a/public/mybonus.php b/public/mybonus.php index 8a5d851e..ae280139 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -461,10 +461,13 @@ if ($officialAdditionalFactor > 0 && $officialTag) { $hasOfficialAddition = true; } $summaryTable = ''; -$summaryTable .= ''; +$summaryTable .= ''; $summaryTable .= sprintf( - '', + '', $lang_mybonus['reward_type_basic'], + $seedBonusResult['torrent_peer_count'], + mksize($seedBonusResult['size']), + $seedBonusResult['A'], number_format($seedBonusResult['seed_bonus'],3), $baseBonusFactor, number_format($baseBonus,3), @@ -479,8 +482,11 @@ if ($hasOfficialAddition) { print("
      • ".$lang_mybonus['official_tag_bonus_additional_factor'].$officialAdditionalFactor."
      • "); print(""); $summaryTable .= sprintf( - '', + '', $lang_mybonus['reward_type_official_addition'], + $seedBonusResult['official_torrent_peer_count'], + mksize($seedBonusResult['official_size']), + $seedBonusResult['official_a'], number_format($seedBonusResult['official_bonus'], 3), $officialAdditionalFactor, number_format($seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3) @@ -494,8 +500,11 @@ if ($hasHaremAddition) { print("
      • ".$lang_mybonus['harem_additional_factor'].$haremFactor."
      • "); print(""); $summaryTable .= sprintf( - '', + '', $lang_mybonus['reward_type_harem_addition'], + '--', + '--', + '--', number_format($haremAddition, 3), $haremFactor, number_format($haremAddition * $haremFactor, 3) From 4ffcacc131f428b8b14cb85ce6b048e6740a4d95 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Wed, 12 Oct 2022 19:44:41 +0800 Subject: [PATCH 41/59] format bonus A value --- public/mybonus.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/mybonus.php b/public/mybonus.php index ae280139..2aa8e53c 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -467,7 +467,7 @@ $summaryTable .= sprintf( $lang_mybonus['reward_type_basic'], $seedBonusResult['torrent_peer_count'], mksize($seedBonusResult['size']), - $seedBonusResult['A'], + number_format($seedBonusResult['A'], 3), number_format($seedBonusResult['seed_bonus'],3), $baseBonusFactor, number_format($baseBonus,3), @@ -486,7 +486,7 @@ if ($hasOfficialAddition) { $lang_mybonus['reward_type_official_addition'], $seedBonusResult['official_torrent_peer_count'], mksize($seedBonusResult['official_size']), - $seedBonusResult['official_a'], + number_format($seedBonusResult['official_a'], 3), number_format($seedBonusResult['official_bonus'], 3), $officialAdditionalFactor, number_format($seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3) From 749afd6c5a3f6e9643f9a7570f781669b92deb6c Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 13 Oct 2022 00:48:02 +0800 Subject: [PATCH 42/59] complain check email and record ip --- ...10_13_002653_add_ip_to_complains_table.php | 38 +++++++++++++++++++ include/constants.php | 2 +- public/complains.php | 11 ++++-- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 database/migrations/2022_10_13_002653_add_ip_to_complains_table.php diff --git a/database/migrations/2022_10_13_002653_add_ip_to_complains_table.php b/database/migrations/2022_10_13_002653_add_ip_to_complains_table.php new file mode 100644 index 00000000..84eca8be --- /dev/null +++ b/database/migrations/2022_10_13_002653_add_ip_to_complains_table.php @@ -0,0 +1,38 @@ +string('ip')->nullable(true); + }); + Schema::table('complain_replies', function (Blueprint $table) { + $table->string('ip')->nullable(true); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('complains', function (Blueprint $table) { + $table->dropColumn('ip'); + }); + Schema::table('complain_replies', function (Blueprint $table) { + $table->dropColumn('ip'); + }); + } +}; diff --git a/include/constants.php b/include/constants.php index 4f96d1f0..1825f479 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ where('email', $email)->first(); + if (!$user) { + stderr($lang_functions['std_error'], $lang_complains['text_new_failure']); + } + sql_query(sprintf('INSERT INTO complains (uuid, email, body, added, ip) VALUES (UUID(), %s, %s, NOW(), %s)', sqlesc($email), sqlesc($body), sqlesc(getip()))) or sqlerr(__FILE__, __LINE__); $Cache->delete_value('COMPLAINTS_COUNT_CACHE'); nexus_redirect(sprintf('complains.php?action=view&id=%s', get_single_value('complains', 'uuid', 'WHERE id = ' . mysql_insert_id()))); break; @@ -27,7 +31,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST'){ $body = filter_input(INPUT_POST, 'body', FILTER_SANITIZE_FULL_SPECIAL_CHARS); $complain = \App\Models\Complain::query()->findOrFail($id); if(empty($id) || empty($body)) stderr($lang_functions['std_error'], $lang_complains['text_new_failure']); - sql_query(sprintf('INSERT INTO complain_replies (complain, userid, added, body) VALUES (%u, %u, NOW(), %s)', $id, $uid, sqlesc($body))) or sqlerr(__FILE__, __LINE__); + sql_query(sprintf('INSERT INTO complain_replies (complain, userid, added, body, ip) VALUES (%u, %u, NOW(), %s, %s)', $id, $uid, sqlesc($body), sqlesc(getip()))) or sqlerr(__FILE__, __LINE__); if ($uid > 0) { try { $toolRep = new \App\Repositories\ToolRepository(); @@ -111,6 +115,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST'){ printf(' [%s]', urlencode($user->username), $lang_complains['text_view_band_log']); } } + printf('
        IP: ' . htmlspecialchars($complain['ip'])); echo '
        ', format_comment($complain['body']); end_frame(); // REPLIES @@ -118,7 +123,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST'){ $res = sql_query(sprintf('SELECT * FROM `complain_replies` WHERE complain = %u ORDER BY id DESC', $complain['id'])) or sqlerr(__FILE__, __LINE__); if(mysql_num_rows($res)){ while($row = mysql_fetch_assoc($res)){ - printf('%s @ %s: ', $row['userid'] ? get_plain_username($row['userid']) : $lang_complains['text_complainer'], gettime($row['added'])); + printf('%s @ %s (%s): ', $row['userid'] ? get_plain_username($row['userid']) : $lang_complains['text_complainer'], gettime($row['added']), htmlspecialchars($row['ip'])); echo format_comment($row['body']) . '
        '; } }else{ From b435e49581157d9f4d5e720eb8a9a16ad9641f26 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Thu, 13 Oct 2022 18:52:10 +0800 Subject: [PATCH 43/59] userdetails page show bonus table --- app/Console/Commands/Test.php | 6 +-- app/Models/UserBanLog.php | 19 +++++++ include/cleanup.php | 9 ++++ include/functions.php | 91 ++++++++++++++++++++++++++++++++++ lang/chs/lang_mybonus.php | 2 +- lang/chs/lang_userdetails.php | 1 + lang/cht/lang_mybonus.php | 2 +- lang/cht/lang_userdetails.php | 1 + lang/en/lang_mybonus.php | 2 +- lang/en/lang_userdetails.php | 1 + nexus/Install/Update.php | 4 +- public/mybonus.php | 68 +++---------------------- public/userdetails.php | 4 ++ resources/lang/en/bonus.php | 15 ++++++ resources/lang/zh_CN/bonus.php | 15 ++++++ resources/lang/zh_TW/bonus.php | 15 ++++++ 16 files changed, 185 insertions(+), 70 deletions(-) diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index aebb3808..819ad92a 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -20,6 +20,7 @@ use App\Models\Tag; use App\Models\Torrent; use App\Models\TorrentOperationLog; use App\Models\User; +use App\Models\UserBanLog; use App\Repositories\AgentAllowRepository; use App\Repositories\AttendanceRepository; use App\Repositories\ExamRepository; @@ -89,10 +90,7 @@ class Test extends Command */ public function handle() { - $rep = new \NexusPlugin\HitAndRun\HitAndRunRepository(); - $rep->initSectionHitAndRunSetting(SearchBox::SECTION_BROWSE . "_"); - $rep->initSectionHitAndRunSetting(SearchBox::SECTION_SPECIAL . "_"); - clear_setting_cache(); + UserBanLog::clearUserBanLogDuplicate(); } diff --git a/app/Models/UserBanLog.php b/app/Models/UserBanLog.php index c6201fbc..081ed06b 100644 --- a/app/Models/UserBanLog.php +++ b/app/Models/UserBanLog.php @@ -7,4 +7,23 @@ class UserBanLog extends NexusModel protected $table = 'user_ban_logs'; protected $fillable = ['uid', 'username', 'operator', 'reason']; + + public static function clearUserBanLogDuplicate() + { + $lists = UserBanLog::query() + ->selectRaw("min(id) as id, uid, count(*) as counts") + ->groupBy('uid') + ->having("counts", ">", 1) + ->get(); + if ($lists->isEmpty()) { + do_log("sql: " . last_query() . ", no data to delete"); + return; + } + $idArr = $lists->pluck("id")->toArray(); + $uidArr = $lists->pluck('uid')->toArray(); + $result = UserBanLog::query()->whereIn("uid", $uidArr)->whereNotIn("id", $idArr)->delete(); + do_log("sql: " . last_query() . ", result: $result"); + } + + } diff --git a/include/cleanup.php b/include/cleanup.php index a9410767..6e58b676 100644 --- a/include/cleanup.php +++ b/include/cleanup.php @@ -1019,6 +1019,15 @@ function docleanup($forceAll = 0, $printProgress = false) { if ($printProgress) { printProgress($log); } + + //remove duplicate user ban logs + $log = "clear user ban log duplicate"; + \App\Models\UserBanLog::clearUserBanLogDuplicate(); + do_log($log); + if ($printProgress) { + printProgress($log); + } + $log = 'Full cleanup is done'; do_log($log); if ($printProgress) { diff --git a/include/functions.php b/include/functions.php index 4f356865..844359f9 100644 --- a/include/functions.php +++ b/include/functions.php @@ -5969,4 +5969,95 @@ JS; \Nexus\Nexus::js($js, 'footer', false); return $input; } + +function build_bonus_table(array $user, array $bonusResult = [], array $options = []) +{ + if (empty($bonusResult)) { + $bonusResult = calculate_seed_bonus($user['id']); + } + $officialTag = get_setting('bonus.official_tag'); + $officialAdditionalFactor = get_setting('bonus.official_addition', 0); + $haremFactor = get_setting('bonus.harem_addition'); + $haremAddition = calculate_harem_addition($user['id']); + $isDonor = is_donor($user); + $donortimes_bonus = get_setting('bonus.donortimes'); + $baseBonusFactor = 1; + if ($isDonor) { + $baseBonusFactor = $donortimes_bonus; + } + $baseBonus = $bonusResult['seed_bonus'] * $baseBonusFactor; + $totalBonus = number_format( $baseBonus + $haremAddition * $haremFactor + $bonusResult['official_bonus'] * $officialAdditionalFactor, 3); + + $rowSpan = 1; + $hasHaremAddition = $hasOfficialAddition = false; + if ($haremFactor > 0) { + $rowSpan++; + $hasHaremAddition = true; + } + if ($officialAdditionalFactor > 0 && $officialTag) { + $rowSpan++; + $hasOfficialAddition = true; + } + + $table = sprintf('
        '.$lang_mybonus['reward_type'].''.$lang_mybonus['bonus_base'].''.$lang_mybonus['factor'].''.$lang_mybonus['got_bonus'].''.$lang_mybonus['total'].'
        '.$lang_mybonus['reward_type'].''.$lang_mybonus['col_count'].''.$lang_mybonus['col_size'].''.$lang_mybonus['col_a'].''.$lang_mybonus['bonus_base'].''.$lang_mybonus['factor'].''.$lang_mybonus['got_bonus'].''.$lang_mybonus['total'].'
        %s%s%s%s%s
        %s%s%s%s%s%s%s%s
        %s%s%s%s
        %s%s%s%s%s%s%s
        %s%s%s%s
        %s%s%s%s%s%s%s
        ', $options['table_style'] ?? ''); + $table .= ''; + $table .= sprintf('', nexus_trans('bonus.table_thead.reward_type')); + $table .= sprintf('', nexus_trans('bonus.table_thead.count')); + $table .= sprintf('', nexus_trans('bonus.table_thead.size')); + $table .= sprintf('', nexus_trans('bonus.table_thead.a_value')); + $table .= sprintf('', nexus_trans('bonus.table_thead.bonus_base')); + $table .= sprintf('', nexus_trans('bonus.table_thead.factor')); + $table .= sprintf('', nexus_trans('bonus.table_thead.got_bonus')); + $table .= sprintf('', nexus_trans('bonus.table_thead.total')); + $table .= ''; + + $table .= sprintf( + '', + nexus_trans('bonus.reward_types.basic'), + $bonusResult['torrent_peer_count'], + mksize($bonusResult['size']), + number_format($bonusResult['A'], 3), + number_format($bonusResult['seed_bonus'],3), + $baseBonusFactor, + number_format($baseBonus,3), + $rowSpan, + $totalBonus + ); + + if ($hasOfficialAddition) { + $table .= sprintf( + '', + nexus_trans('bonus.reward_types.official_addition'), + $bonusResult['official_torrent_peer_count'], + mksize($bonusResult['official_size']), + number_format($bonusResult['official_a'], 3), + number_format($bonusResult['official_bonus'], 3), + $officialAdditionalFactor, + number_format($bonusResult['official_bonus'] * $officialAdditionalFactor, 3) + ); + } + + if ($hasHaremAddition) { + $table .= sprintf( + '', + nexus_trans('bonus.reward_types.harem_addition'), + '--', + '--', + '--', + number_format($haremAddition, 3), + $haremFactor, + number_format($haremAddition * $haremFactor, 3) + ); + } + $table .= '
        %s%s%s%s%s%s%s%s
        %s%s%s%s%s%s%s%s
        %s%s%s%s%s%s%s
        %s%s%s%s%s%s%s
        '; + + return [ + 'table' => $table, + 'has_harem_addition' => $hasHaremAddition, + 'harem_addition_factor' => $haremFactor, + 'has_official_addition' => $hasOfficialAddition, + 'official_addition_factor' => $officialAdditionalFactor, + ]; + +} ?> diff --git a/lang/chs/lang_mybonus.php b/lang/chs/lang_mybonus.php index 98999c84..21653080 100644 --- a/lang/chs/lang_mybonus.php +++ b/lang/chs/lang_mybonus.php @@ -146,7 +146,7 @@ $lang_mybonus = array 'bonus_base' => '基础魔力', 'lock_text' => '系统限制 %s 秒内只能点击交换按钮一次!', 'text_get_by_seeding_official' => '官种加成每小时将额外得到如下的魔力值', - 'official_calculate_method' => '官种奖励计算公式同上,只是仅针对官种进行计算', + 'official_calculate_method' => '官种奖励计算公式同上,只是仅针对官种进行计算,不考虑低保', 'official_tag_bonus_additional_factor' => '最终奖励为计算所得官种奖励乘以官种系数,当前官种系数为: ', 'reward_type_official_addition' => '官种加成', 'text_get_by_harem' => '后宫加成每小时将额外得到如下的魔力值', diff --git a/lang/chs/lang_userdetails.php b/lang/chs/lang_userdetails.php index d27d81cd..4546c3a2 100644 --- a/lang/chs/lang_userdetails.php +++ b/lang/chs/lang_userdetails.php @@ -155,5 +155,6 @@ $lang_userdetails = array 'row_user_props' => '道具', 'meta_key_change_username_username' => '新用户名', 'consume' => '使用', + 'text_bonus_table' => '时魔', ); ?> diff --git a/lang/cht/lang_mybonus.php b/lang/cht/lang_mybonus.php index 6fb176ba..70c265bf 100644 --- a/lang/cht/lang_mybonus.php +++ b/lang/cht/lang_mybonus.php @@ -146,7 +146,7 @@ $lang_mybonus = array 'bonus_base' => '基礎魔力', 'lock_text' => '系統限製 %s 秒內只能點擊交換按鈕一次!', 'text_get_by_seeding_official' => '官種加成每小時將額外得到如下的魔力值', - 'official_calculate_method' => '官種獎勵計算公式同上,只是僅針對官種進行計算', + 'official_calculate_method' => '官種獎勵計算公式同上,只是僅針對官種進行計算,不考慮低保', 'official_tag_bonus_additional_factor' => '最終獎勵為計算所得官種獎勵乘以官種系數,當前官種系數為: ', 'reward_type_official_addition' => '官種加成', 'text_get_by_harem' => '後宮加成每小時將額外得到如下的魔力值', diff --git a/lang/cht/lang_userdetails.php b/lang/cht/lang_userdetails.php index f9dc757d..4a3c0a98 100644 --- a/lang/cht/lang_userdetails.php +++ b/lang/cht/lang_userdetails.php @@ -155,5 +155,6 @@ $lang_userdetails = array 'row_user_props' => '道具', 'meta_key_change_username_username' => '新用戶名', 'consume' => '使用', + 'text_bonus_table' => '時魔', ); ?> diff --git a/lang/en/lang_mybonus.php b/lang/en/lang_mybonus.php index 83b6717e..70179d9f 100644 --- a/lang/en/lang_mybonus.php +++ b/lang/en/lang_mybonus.php @@ -146,7 +146,7 @@ where
        • A is an intermediate variable
        • Ti is the i< 'bonus_base' => 'Base bonus', 'lock_text' => 'The system limits you to one click on the exchange button within %s seconds!', 'text_get_by_seeding_official' => 'The official torrents will receive the following additional bonus value per hour', - 'official_calculate_method' => 'The formula for calculating the official reward is the same as above, but only for the official type', + 'official_calculate_method' => 'The formula for calculating the official reward is the same as above, but only for the official type, No consideration for low income', 'official_tag_bonus_additional_factor' => 'The final reward is the calculated official type reward multiplied by the official type factor, the current official type factor is: ', 'reward_type_official_addition' => 'Official addition', 'text_get_by_harem' => 'The harem addition will give the following additional bonus value per hour', diff --git a/lang/en/lang_userdetails.php b/lang/en/lang_userdetails.php index 44546aae..6be9dc95 100644 --- a/lang/en/lang_userdetails.php +++ b/lang/en/lang_userdetails.php @@ -155,5 +155,6 @@ $lang_userdetails = array 'row_user_props' => 'Props', 'meta_key_change_username_username' => 'New username', 'consume' => 'Use', + 'text_bonus_table' => 'Bonus per hour', ); ?> diff --git a/nexus/Install/Update.php b/nexus/Install/Update.php index 54ff934a..f9d4d312 100644 --- a/nexus/Install/Update.php +++ b/nexus/Install/Update.php @@ -15,6 +15,7 @@ use App\Models\Tag; use App\Models\Torrent; use App\Models\TorrentTag; use App\Models\User; +use App\Models\UserBanLog; use App\Repositories\AttendanceRepository; use App\Repositories\BonusRepository; use App\Repositories\ExamRepository; @@ -391,6 +392,8 @@ class Update extends Install $command .= " --exclude=$exclude"; } $this->executeCommand($command); + //remove original file + unlink($filename); break; } } @@ -444,5 +447,4 @@ class Update extends Install } - } diff --git a/public/mybonus.php b/public/mybonus.php index 2aa8e53c..3a51e839 100644 --- a/public/mybonus.php +++ b/public/mybonus.php @@ -428,18 +428,8 @@ print("
        "); $seedBonusResult = calculate_seed_bonus($CURUSER['id']); $A = $seedBonusResult['A']; -$officialAdditionalFactor = get_setting('bonus.official_addition', 0); -$officialTag = get_setting('bonus.official_tag'); -$haremFactor = get_setting('bonus.harem_addition'); -$haremAddition = calculate_harem_addition($CURUSER['id']); -$isDonor = is_donor($CURUSER); -$baseBonusFactor = 1; -if ($isDonor) { - $baseBonusFactor = $donortimes_bonus; -} -$baseBonus = $seedBonusResult['seed_bonus'] * $baseBonusFactor; -$totalBonus = number_format( $baseBonus + $haremAddition * $haremFactor + $seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3); +$bonusTableResult = build_bonus_table($CURUSER, $seedBonusResult, ['table_style' => 'width: 50%']); $percent = $seedBonusResult['seed_bonus'] * 100 / ($bzero_bonus + $perseeding_bonus * $maxseeding_bonus); print("
        ".$lang_mybonus['text_you_are_currently_getting'].round($seedBonusResult['seed_bonus'],3).$lang_mybonus['text_point'].add_s($seedBonusResult['seed_bonus']).$lang_mybonus['text_per_hour']." (A = ".round($A,1).")
        "); @@ -450,70 +440,24 @@ else $loadpic = "loadbargreen"; $width = $percent * 4; print("\"".$percent."%\"
        "); -$rowSpan = 1; -$hasHaremAddition = $hasOfficialAddition = false; -if ($haremFactor > 0) { - $rowSpan++; - $hasHaremAddition = true; -} -if ($officialAdditionalFactor > 0 && $officialTag) { - $rowSpan++; - $hasOfficialAddition = true; -} -$summaryTable = ''; -$summaryTable .= ''; -$summaryTable .= sprintf( - '', - $lang_mybonus['reward_type_basic'], - $seedBonusResult['torrent_peer_count'], - mksize($seedBonusResult['size']), - number_format($seedBonusResult['A'], 3), - number_format($seedBonusResult['seed_bonus'],3), - $baseBonusFactor, - number_format($baseBonus,3), - $rowSpan, - $totalBonus -); - -if ($hasOfficialAddition) { +if ($bonusTableResult['has_official_addition']) { print("

        ".$lang_mybonus['text_get_by_seeding_official']."

        "); print("
          "); print("
        • ".$lang_mybonus['official_calculate_method']."
        • "); - print("
        • ".$lang_mybonus['official_tag_bonus_additional_factor'].$officialAdditionalFactor."
        • "); + print("
        • ".$lang_mybonus['official_tag_bonus_additional_factor'].$bonusTableResult['official_addition_factor']."
        • "); print("
        "); - $summaryTable .= sprintf( - '', - $lang_mybonus['reward_type_official_addition'], - $seedBonusResult['official_torrent_peer_count'], - mksize($seedBonusResult['official_size']), - number_format($seedBonusResult['official_a'], 3), - number_format($seedBonusResult['official_bonus'], 3), - $officialAdditionalFactor, - number_format($seedBonusResult['official_bonus'] * $officialAdditionalFactor, 3) - ); } -if ($hasHaremAddition) { +if ($bonusTableResult['has_harem_addition']) { print("

        ".$lang_mybonus['text_get_by_harem']."

        "); print("
          "); print("
        • ".sprintf($lang_mybonus['harem_additional_desc'], $CURUSER['id'])."
        • "); - print("
        • ".$lang_mybonus['harem_additional_factor'].$haremFactor."
        • "); + print("
        • ".$lang_mybonus['harem_additional_factor'].$bonusTableResult['harem_addition_factor']."
        • "); print("
        "); - $summaryTable .= sprintf( - '', - $lang_mybonus['reward_type_harem_addition'], - '--', - '--', - '--', - number_format($haremAddition, 3), - $haremFactor, - number_format($haremAddition * $haremFactor, 3) - ); } -$summaryTable .= '
        '.$lang_mybonus['reward_type'].''.$lang_mybonus['col_count'].''.$lang_mybonus['col_size'].''.$lang_mybonus['col_a'].''.$lang_mybonus['bonus_base'].''.$lang_mybonus['factor'].''.$lang_mybonus['got_bonus'].''.$lang_mybonus['total'].'
        %s%s%s%s%s%s%s%s
        %s%s%s%s%s%s%s
        %s%s%s%s%s%s%s
        '; print("

        ".$lang_mybonus['text_bonus_summary']."

        "); -print '
        '.$summaryTable.'
        '; +print '
        '.$bonusTableResult['table'].'
        '; print("

        ".$lang_mybonus['text_other_things_get_bonus']."

        "); print("
          "); diff --git a/public/userdetails.php b/public/userdetails.php index fb0cd08d..f5900081 100644 --- a/public/userdetails.php +++ b/public/userdetails.php @@ -394,6 +394,10 @@ if ($user["id"] == $CURUSER["id"] || user_can('viewhistory')) { tr_small($lang_functions['text_seed_points'], number_format($user['seed_points'], 1), 1); } +if (user_can('prfmanage') && $user["class"] < get_user_class()) { + $bonusTable = build_bonus_table($user); + tr_small($lang_userdetails['text_bonus_table'], $bonusTable['table'], 1); +} if ($user["ip"] && (user_can('torrenthistory') || $user["id"] == $CURUSER["id"])){ diff --git a/resources/lang/en/bonus.php b/resources/lang/en/bonus.php index 323dbe07..3b772e0d 100644 --- a/resources/lang/en/bonus.php +++ b/resources/lang/en/bonus.php @@ -3,4 +3,19 @@ return [ 'comment_buy_medal' => 'Spend :bonus bonus buy :medal_name', 'comment_buy_attendance_card' => 'Spend :bonus bonus buy one attend card', + 'table_thead' => [ + 'reward_type' => 'Reward type', + 'count' => 'Count', + 'size' => 'Size', + 'a_value' => 'A Value', + 'bonus_base' => 'Basic bonus', + 'factor' => 'Factor', + 'got_bonus' => 'Got bonus', + 'total' => 'Total', + ], + 'reward_types' => [ + 'basic' => 'Basic reward', + 'harem_addition' => 'Harem addition', + 'official_addition' => 'Official addition', + ], ]; diff --git a/resources/lang/zh_CN/bonus.php b/resources/lang/zh_CN/bonus.php index 26000772..aa7ead52 100644 --- a/resources/lang/zh_CN/bonus.php +++ b/resources/lang/zh_CN/bonus.php @@ -3,4 +3,19 @@ return [ 'comment_buy_medal' => '花费 :bonus 魔力购买了 :medal_name', 'comment_buy_attendance_card' => '花费 :bonus 魔力购买了 1 张补签卡', + 'table_thead' => [ + 'reward_type' => '奖励类型', + 'count' => '数量', + 'size' => '体积', + 'a_value' => 'A 值', + 'bonus_base' => '基础魔力', + 'factor' => '系数', + 'got_bonus' => '获得魔力', + 'total' => '合计', + ], + 'reward_types' => [ + 'basic' => '基本奖励', + 'harem_addition' => '后宫加成', + 'official_addition' => '官种加成', + ], ]; diff --git a/resources/lang/zh_TW/bonus.php b/resources/lang/zh_TW/bonus.php index 0e57807c..a5cae0da 100644 --- a/resources/lang/zh_TW/bonus.php +++ b/resources/lang/zh_TW/bonus.php @@ -3,4 +3,19 @@ return [ 'comment_buy_medal' => '花費 :bonus 魔力購買了 :medal_name', 'comment_buy_attendance_card' => '花費 :bonus 魔力購買了 1 張補簽卡', + 'table_thead' => [ + 'reward_type' => '獎勵類型', + 'count' => '數量', + 'size' => '體積', + 'a_value' => 'A 值', + 'bonus_base' => '基礎魔力', + 'factor' => '系數', + 'got_bonus' => '獲得魔力', + 'total' => '合計', + ], + 'reward_types' => [ + 'basic' => '基本獎勵', + 'harem_addition' => '後宮加成', + 'official_addition' => '官種加成', + ], ]; From 871e3637ea1f6b73c9ae84638cfadd644862449a Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Fri, 14 Oct 2022 20:48:42 +0800 Subject: [PATCH 44/59] seeding&leeching show client and IP --- lang/chs/lang_getusertorrentlistajax.php | 1 + lang/cht/lang_getusertorrentlistajax.php | 1 + lang/en/lang_getusertorrentlistajax.php | 1 + public/getusertorrentlistajax.php | 21 +++++++++++++++++---- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lang/chs/lang_getusertorrentlistajax.php b/lang/chs/lang_getusertorrentlistajax.php index ed72e43b..7dc0428c 100644 --- a/lang/chs/lang_getusertorrentlistajax.php +++ b/lang/chs/lang_getusertorrentlistajax.php @@ -18,5 +18,6 @@ $lang_getusertorrentlistajax = array 'text_no_record' => "没有记录", 'text_total_size' => " | 总大小:", 'col_added' => "发布时间", + 'col_client' => '客户端', ); ?> diff --git a/lang/cht/lang_getusertorrentlistajax.php b/lang/cht/lang_getusertorrentlistajax.php index 3f8f1835..7de473ba 100644 --- a/lang/cht/lang_getusertorrentlistajax.php +++ b/lang/cht/lang_getusertorrentlistajax.php @@ -18,5 +18,6 @@ $lang_getusertorrentlistajax = array 'text_no_record' => "沒有記錄", 'text_total_size' => " | 總大小:", 'col_added' => "發布時間", + 'col_client' => '客戶端', ); ?> diff --git a/lang/en/lang_getusertorrentlistajax.php b/lang/en/lang_getusertorrentlistajax.php index a86a31bd..1be0f156 100644 --- a/lang/en/lang_getusertorrentlistajax.php +++ b/lang/en/lang_getusertorrentlistajax.php @@ -18,5 +18,6 @@ $lang_getusertorrentlistajax = array 'text_no_record' => "No record.", 'text_total_size' => " | Total size: ", 'col_added' => "Added", + 'col_client' => 'Client', ); ?> diff --git a/public/getusertorrentlistajax.php b/public/getusertorrentlistajax.php index c63b7426..d5d234fa 100644 --- a/public/getusertorrentlistajax.php +++ b/public/getusertorrentlistajax.php @@ -23,7 +23,7 @@ function maketable($res, $mode = 'seeding') { global $lang_getusertorrentlistajax,$CURUSER,$smalldescription_main, $lang_functions, $id; global $torrentRep, $claimRep, $claimTorrentTTL; - $showActionClaim = false; + $showActionClaim = $showClient = false; switch ($mode) { case 'uploaded': { @@ -55,6 +55,7 @@ function maketable($res, $mode = 'seeding') $showtotalsize = true; $columncount = 8; $showActionClaim = true; + $showClient = true; break; } case 'leeching': { @@ -69,6 +70,7 @@ function maketable($res, $mode = 'seeding') $showcotime = false; $showanonymous = false; $showtotalsize = true; + $showClient = true; $columncount = 8; break; } @@ -129,6 +131,9 @@ function maketable($res, $mode = 'seeding') $ret = "". ($showsize ? "" : "").($showsenum ? "" : "").($showlenum ? "" : "").($showuploaded ? "" : "") . ($showdownloaded ? "" : "").($showratio ? "" : "").($showsetime ? "" : "").($showletime ? "" : "").($showcotime ? "" : "").($showanonymous ? "" : ""); + if ($showClient) { + $ret .= sprintf('', $lang_getusertorrentlistajax['col_client']); + } $ret .= sprintf('', $lang_functions['std_action']); $ret .= ""; $total_size = 0; @@ -212,6 +217,14 @@ function maketable($res, $mode = 'seeding') $ret .= ""; if ($showanonymous) $ret .= ""; + if ($showClient) { + $ipArr = array_filter([$arr['ipv4'], $arr['ipv6']]); + $ret .= sprintf( + '', + get_agent($arr['peer_id'], $arr['agent']), $arr['port'], + implode('
          ', $ipArr) + ); + } $claimButton = ''; if ( $showActionClaim @@ -258,7 +271,7 @@ switch ($type) case 'seeding': { // $res = sql_query("SELECT torrent,added,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers FROM peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='yes' ORDER BY torrents.id DESC") or sqlerr(); - $fields = "torrent,added,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers,snatched.seedtime,snatched.uploaded,snatched.userid, categories.mode as search_box_id"; + $fields = "torrent,added,snatched.uploaded,snatched.downloaded,snatched.seedtime,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers,snatched.userid, categories.mode as search_box_id, peers.peer_id, peers.agent, peers.port, peers.ipv4, peers.ipv6"; $tableWhere = "peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='yes'"; $order = "torrents.id DESC"; break; @@ -268,7 +281,7 @@ switch ($type) case 'leeching': { // $res = sql_query("SELECT torrent,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers, torrents.added FROM peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='no' ORDER BY torrents.id DESC") or sqlerr(); - $fields = "torrent,snatched.uploaded,snatched.downloaded,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers, torrents.added,snatched.seedtime,snatched.uploaded,snatched.userid, categories.mode as search_box_id"; + $fields = "torrent,snatched.uploaded,snatched.downloaded,snatched.seedtime,torrents.name as torrentname, torrents.small_descr, torrents.sp_state, torrents.banned, torrents.approval_status, categories.name as catname,size,torrents.hr,image,category,seeders,leechers, torrents.added,snatched.userid, categories.mode as search_box_id, peers.peer_id, peers.agent, peers.port, peers.ipv4, peers.ipv6"; $tableWhere = "peers LEFT JOIN torrents ON peers.torrent = torrents.id LEFT JOIN categories ON torrents.category = categories.id LEFT JOIN snatched ON torrents.id = snatched.torrentid WHERE peers.userid=$id AND snatched.userid = $id AND peers.seeder='no'"; $order = "torrents.id DESC"; break; @@ -288,7 +301,7 @@ switch ($type) case 'incomplete': { // $res = sql_query("SELECT torrents.id AS torrent, torrents.name AS torrentname, small_descr, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.downloaded, snatched.leechtime FROM torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories on torrents.category = categories.id WHERE snatched.finished='no' AND userid=$id AND torrents.owner != $id ORDER BY snatched.id DESC") or sqlerr(); - $fields = "torrents.id AS torrent, torrents.name AS torrentname, small_descr, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.downloaded, snatched.leechtime,snatched.seedtime,snatched.uploaded,snatched.userid, categories.mode as search_box_id"; + $fields = "torrents.id AS torrent, torrents.name AS torrentname, small_descr, torrents.banned, torrents.approval_status, categories.name AS catname, categories.image, category, sp_state, size, torrents.hr, torrents.added,snatched.uploaded, snatched.downloaded, snatched.leechtime,snatched.seedtime,snatched.userid, categories.mode as search_box_id"; $tableWhere = "torrents LEFT JOIN snatched ON torrents.id = snatched.torrentid LEFT JOIN categories on torrents.category = categories.id WHERE snatched.finished='no' AND userid=$id AND torrents.owner != $id"; $order = "snatched.id DESC"; break; From be29509cff4a937c5505e555c024392cf335b37c Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 16 Oct 2022 04:52:44 +0800 Subject: [PATCH 45/59] seedBox record alert + destroy disabled account --- app/Repositories/SeedBoxRepository.php | 2 +- include/cleanup.php | 30 ++++++++++++++++++++------ include/functions.php | 13 +++++++++++ lang/chs/lang_functions.php | 1 + lang/chs/lang_settings.php | 3 +++ lang/cht/lang_functions.php | 1 + lang/cht/lang_settings.php | 3 +++ lang/en/lang_functions.php | 1 + lang/en/lang_settings.php | 3 +++ nexus/Install/settings.default.php | 1 + public/getusertorrentlistajax.php | 14 +++++++++--- public/settings.php | 13 ++++++++--- public/viewsnatches.php | 4 ++-- resources/lang/en/cleanup.php | 10 ++++----- resources/lang/zh_CN/cleanup.php | 10 ++++----- resources/lang/zh_CN/permission.php | 8 +++++++ resources/lang/zh_TW/cleanup.php | 10 ++++----- 17 files changed, 96 insertions(+), 31 deletions(-) diff --git a/app/Repositories/SeedBoxRepository.php b/app/Repositories/SeedBoxRepository.php index 13666832..2649046a 100644 --- a/app/Repositories/SeedBoxRepository.php +++ b/app/Repositories/SeedBoxRepository.php @@ -154,7 +154,7 @@ class SeedBoxRepository extends BaseRepository private function clearCache() { - return true; + NexusDB::cache_del('SEED_BOX_RECORD_APPROVAL_NONE'); // SeedBoxRecordUpdated::dispatch(); } diff --git a/include/cleanup.php b/include/cleanup.php index 6e58b676..3e301bfa 100644 --- a/include/cleanup.php +++ b/include/cleanup.php @@ -204,7 +204,7 @@ function ban_user_with_leech_warning_expired() } -function delete_user(\Illuminate\Database\Eloquent\Builder $query, $reasonKey) +function disable_user(\Illuminate\Database\Eloquent\Builder $query, $reasonKey) { $results = $query->where('enabled', \App\Models\User::ENABLED_YES)->get(['id', 'username', 'modcomment', 'lang']); if ($results->isEmpty()) { @@ -228,7 +228,7 @@ function delete_user(\Illuminate\Database\Eloquent\Builder $query, $reasonKey) ); sql_query($sql); \App\Models\UserBanLog::query()->insert($userBanLogData); - do_log("[DELETE_USER]($reasonKey): " . implode(', ', $uidArr)); + do_log("[DISABLE_USER]($reasonKey): " . implode(', ', $uidArr)); return $uidArr; } @@ -537,7 +537,7 @@ function docleanup($forceAll = 0, $printProgress = false) { ->whereRaw("added < FROM_UNIXTIME($deadtime)") ->whereRaw("last_login < FROM_UNIXTIME($deadtime)") ->whereRaw("last_access < FROM_UNIXTIME($deadtime)"); - delete_user($query, "cleanup.delete_user_unconfirmed"); + disable_user($query, "cleanup.disable_user_unconfirmed"); $log = "delete unconfirmed accounts"; do_log($log); if ($printProgress) { @@ -590,7 +590,7 @@ function docleanup($forceAll = 0, $printProgress = false) { ->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($iniupload_main) { $query->where('uploaded', 0)->orWhere('uploaded', $iniupload_main); }); - delete_user($query, "cleanup.delete_user_no_transfer_alt_last_access_time"); + disable_user($query, "cleanup.disable_user_no_transfer_alt_last_access_time"); } $log = "delete inactive user accounts, no transfer. Alt. 1: last access time"; do_log($log); @@ -613,7 +613,7 @@ function docleanup($forceAll = 0, $printProgress = false) { ->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($iniupload_main) { $query->where('uploaded', 0)->orWhere('uploaded', $iniupload_main); }); - delete_user($query, "cleanup.delete_user_no_transfer_alt_register_time"); + disable_user($query, "cleanup.disable_user_no_transfer_alt_register_time"); } $log = "delete inactive user accounts, no transfer. Alt. 2: registering time"; do_log($log); @@ -632,7 +632,7 @@ function docleanup($forceAll = 0, $printProgress = false) { ->where('status', 'confirmed') ->where("class","<", $maxclass) ->where("last_access","<", $dt); - delete_user($query, "cleanup.delete_user_not_parked"); + disable_user($query, "cleanup.disable_user_not_parked"); } $log = "delete inactive user accounts, not parked"; do_log($log); @@ -651,7 +651,7 @@ function docleanup($forceAll = 0, $printProgress = false) { ->where('status', 'confirmed') ->where("class","<", $maxclass) ->where("last_access","<", $dt); - delete_user($query, "cleanup.delete_user_parked"); + disable_user($query, "cleanup.disable_user_parked"); } $log = "delete parked user accounts, parked"; do_log($log); @@ -659,6 +659,22 @@ function docleanup($forceAll = 0, $printProgress = false) { printProgress($log); } + //destroy disabled accounts + $destroyDisabledDays = get_setting('account.destroy_disabled'); + if ($destroyDisabledDays > 0) { + $secs = $destroyDisabledDays*24*60*60; + $dt = date("Y-m-d H:i:s",(TIMENOW - $secs)); + \App\Models\User::query() + ->where('enabled', 'no') + ->where("last_access","<", $dt) + ->delete(); + } + $log = "destroy disabled accounts"; + do_log($log); + if ($printProgress) { + printProgress($log); + } + //remove VIP status if time's up $res = sql_query("SELECT id, modcomment FROM users WHERE vip_added='yes' AND vip_until < NOW()") or sqlerr(__FILE__, __LINE__); if (mysql_num_rows($res) > 0) diff --git a/include/functions.php b/include/functions.php index 844359f9..ddc1f374 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2800,6 +2800,19 @@ if ($msgalert) } } + //seed box approval + if (get_user_class() >= \App\Models\User::CLASS_ADMINISTRATOR && get_setting('seed_box.enabled') == 'yes') { + $cacheKey = 'SEED_BOX_RECORD_APPROVAL_NONE'; + $toApprovalCounts = $Cache->get_value($cacheKey); + if ($toApprovalCounts === false) { + $toApprovalCounts = get_row_count('seed_box_records', 'where status = 0'); + $Cache->cache_value($cacheKey, $toApprovalCounts, 60); + } + if ($toApprovalCounts) { + msgalert('/nexusphp/seed-box-records?tableFilters[status][value]=0', sprintf($lang_functions['text_seed_box_record_to_approval'], is_or_are($toApprovalCounts), $toApprovalCounts, add_s($toApprovalCounts)), 'darkred'); + } + } + if (user_can('staffmem')) { diff --git a/lang/chs/lang_functions.php b/lang/chs/lang_functions.php index 7bbb9b1f..082dc32f 100644 --- a/lang/chs/lang_functions.php +++ b/lang/chs/lang_functions.php @@ -329,6 +329,7 @@ $lang_functions = array 'input_check_all' => "全选", 'input_uncheck_all' => "全不选", 'select_at_least_one_record' => '至少选择一条记录!', + 'text_seed_box_record_to_approval' => '有 %s%u 条待审核的 SeedBox 记录%s', ); ?> diff --git a/lang/chs/lang_settings.php b/lang/chs/lang_settings.php index e79009f5..75e82e5b 100644 --- a/lang/chs/lang_settings.php +++ b/lang/chs/lang_settings.php @@ -791,6 +791,9 @@ $lang_settings = array 'row_upload_deny_approval_deny_count' => '拒绝发布审核不通过数', 'text_upload_deny_approval_deny_count_note' => "当审核不通过的种子数大于等于此数值时,不允许发布。设置为 '0' 不使用此规则", 'row_nfo_view_style_default' => 'NFO 默认查看样式', + 'row_destroy_disabled' => '彻底删除账号', + 'text_destroy_disabled_note_one' => '被封禁的账号如果连续', + 'text_destroy_disabled_note_two' => "天不登录,将被从数据库彻底物理删除。默认'500',请设置一个大于上边任何一种导致封禁的值。设为'0'来禁止此规则。", ); ?> diff --git a/lang/cht/lang_functions.php b/lang/cht/lang_functions.php index d1f50e6b..96ff35d5 100644 --- a/lang/cht/lang_functions.php +++ b/lang/cht/lang_functions.php @@ -336,6 +336,7 @@ $lang_functions = array 'input_check_all' => "全選", 'input_uncheck_all' => "全不選", 'select_at_least_one_record' => '至少選擇一條記錄!', + 'text_seed_box_record_to_approval' => '有 %s%u 條待審核的 SeedBox 記錄%s', ); ?> diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index ee0df495..6aaf03e8 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -791,6 +791,9 @@ $lang_settings = array 'row_upload_deny_approval_deny_count' => '拒絕發布審核不通過數', 'text_upload_deny_approval_deny_count_note' => "當審核不通過的種子數大於等於此數值時,不允許發布。設置為 '0' 不使用此規則", 'row_nfo_view_style_default' => 'NFO 默認查看樣式', + 'row_destroy_disabled' => '徹底刪除賬號', + 'text_destroy_disabled_note_one' => '被封禁的賬號如果連續', + 'text_destroy_disabled_note_two' => "天不登錄,將被從數據庫徹底物理刪除。默認'500',請設置一個大於上邊任何一種導致封禁的值。設為'0'來禁止此規則。", ); ?> diff --git a/lang/en/lang_functions.php b/lang/en/lang_functions.php index 421ec32a..bc4fbe54 100644 --- a/lang/en/lang_functions.php +++ b/lang/en/lang_functions.php @@ -337,6 +337,7 @@ $lang_functions = array 'input_check_all' => "Check All", 'input_uncheck_all' => "Uncheck All", 'select_at_least_one_record' => 'Select at least one record!', + 'text_seed_box_record_to_approval' => 'There %s%u not approval seed box record%s.', ); ?> diff --git a/lang/en/lang_settings.php b/lang/en/lang_settings.php index 10168383..a82eb6ad 100644 --- a/lang/en/lang_settings.php +++ b/lang/en/lang_settings.php @@ -791,6 +791,9 @@ $lang_settings = array 'row_upload_deny_approval_deny_count' => 'Refuse to upload approval deny count', 'text_upload_deny_approval_deny_count_note' => "When the number of torrents approval deny is greater than or equal to this value, publishing is not allowed. Set to '0' to not use this rule", 'row_nfo_view_style_default' => 'NFO view style default', + 'row_destroy_disabled' => 'Delete account completely', + 'text_destroy_disabled_note_one' => 'Disabled accounts if they are continuously', + 'text_destroy_disabled_note_two' => "Days without logging in, will be physically deleted from the database completely. Default '500', please set a value greater than any of the above to cause disable. Set to '0' to disable this rule." , ); ?> diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index 978a056b..ed7f04d5 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -304,6 +304,7 @@ return array ( 8 => '5', 9 => '10', ), + 'destroy_disabled' => 500, ), 'torrent' => array ( diff --git a/public/getusertorrentlistajax.php b/public/getusertorrentlistajax.php index d5d234fa..cc1d963e 100644 --- a/public/getusertorrentlistajax.php +++ b/public/getusertorrentlistajax.php @@ -11,6 +11,7 @@ header("Pragma: no-cache" ); $torrentRep = new \App\Repositories\TorrentRepository(); $claimRep = new \App\Repositories\ClaimRepository(); +$seedBoxRep = new \App\Repositories\SeedBoxRepository(); $claimTorrentTTL = \App\Models\Claim::getConfigTorrentTTL(); $id = intval($_GET['userid'] ?? 0); $type = $_GET['type']; @@ -22,7 +23,7 @@ if(!user_can('torrenthistory') && $id != $CURUSER["id"]) function maketable($res, $mode = 'seeding') { global $lang_getusertorrentlistajax,$CURUSER,$smalldescription_main, $lang_functions, $id; - global $torrentRep, $claimRep, $claimTorrentTTL; + global $torrentRep, $claimRep, $claimTorrentTTL, $seedBoxRep; $showActionClaim = $showClient = false; switch ($mode) { @@ -107,6 +108,10 @@ function maketable($res, $mode = 'seeding') } default: break; } + $shouldShowClient = false; + if ($showClient && (user_can('userprofile') || $CURUSER['id'] == $id)) { + $shouldShowClient = true; + } $results = $torrentIdArr = []; while ($row = mysql_fetch_assoc($res)) { $results[] = $row; @@ -131,7 +136,7 @@ function maketable($res, $mode = 'seeding') $ret = "
          ".$lang_getusertorrentlistajax['col_type']."".$lang_getusertorrentlistajax['col_name']."".$lang_getusertorrentlistajax['col_added']."\"size\"\"seeders\"\"leechers\"".$lang_getusertorrentlistajax['col_uploaded']."".$lang_getusertorrentlistajax['col_downloaded']."".$lang_getusertorrentlistajax['col_ratio']."".$lang_getusertorrentlistajax['col_se_time']."".$lang_getusertorrentlistajax['col_le_time']."".$lang_getusertorrentlistajax['col_time_completed']."".$lang_getusertorrentlistajax['col_anonymous']."%sIP%s
          "."". str_replace(" ", "
          ", gettime($arr['completedat'],false)). "
          ".$arr['anonymous']."%s
          %s
          %s
          ". ($showsize ? "" : "").($showsenum ? "" : "").($showlenum ? "" : "").($showuploaded ? "" : "") . ($showdownloaded ? "" : "").($showratio ? "" : "").($showsetime ? "" : "").($showletime ? "" : "").($showcotime ? "" : "").($showanonymous ? "" : ""); - if ($showClient) { + if ($shouldShowClient) { $ret .= sprintf('', $lang_getusertorrentlistajax['col_client']); } $ret .= sprintf('', $lang_functions['std_action']); @@ -217,8 +222,11 @@ function maketable($res, $mode = 'seeding') $ret .= ""; if ($showanonymous) $ret .= ""; - if ($showClient) { + if ($shouldShowClient) { $ipArr = array_filter([$arr['ipv4'], $arr['ipv6']]); + foreach ($ipArr as &$_ip) { + $_ip = sprintf('%s', $_ip . $seedBoxRep->renderIcon($_ip, $arr['userid'])); + } $ret .= sprintf( '', get_agent($arr['peer_id'], $arr['agent']), $arr['port'], diff --git a/public/settings.php b/public/settings.php index 081737b9..7cfdfaed 100644 --- a/public/settings.php +++ b/public/settings.php @@ -134,7 +134,7 @@ elseif ($action == 'savesettings_account') // save account 'exutime', 'exudl', \App\Models\User::CLASS_EXTREME_USER . '_min_seed_points', 'exuprratio', 'exuderatio', \App\Models\User::CLASS_EXTREME_USER . '_alias', 'uutime', 'uudl', \App\Models\User::CLASS_ULTIMATE_USER . '_min_seed_points', 'uuprratio', 'uuderatio', \App\Models\User::CLASS_ULTIMATE_USER . '_alias', 'nmtime', 'nmdl', \App\Models\User::CLASS_NEXUS_MASTER . '_min_seed_points', 'nmprratio', 'nmderatio', \App\Models\User::CLASS_NEXUS_MASTER . '_alias', - 'getInvitesByPromotion' + 'getInvitesByPromotion', 'destroy_disabled' ); GetVar($validConfig); $ACCOUNT = []; @@ -486,8 +486,12 @@ elseif ($action == 'authoritysettings') //Authority settings tr($lang_settings['row_see_banned_torrents'], $lang_settings['text_minimum_class'].classlist('seebanned',$maxclass,$AUTHORITY['seebanned'],0,true).$lang_settings['text_default'].get_user_class_name(UC_UPLOADER,false,true,true).$lang_settings['text_see_banned_torrents_note'],1); tr($lang_settings['row_vote_against_offers'], $lang_settings['text_minimum_class'].classlist('againstoffer',$maxclass,$AUTHORITY['againstoffer'],0,true).$lang_settings['text_default'].get_user_class_name(UC_USER,false,true,true).$lang_settings['text_vote_against_offers_note'],1); tr($lang_settings['row_allow_userbar'], $lang_settings['text_minimum_class'].classlist('userbar',$maxclass,$AUTHORITY['userbar'],0,true).$lang_settings['text_default'].get_user_class_name(UC_POWER_USER,false,true,true).$lang_settings['text_allow_userbar_note'],1); - tr($lang_settings['row_save_settings'],"", 1); - print (""); + +// tr(nexus_trans('permission.not-counting-downloaded.text'), $lang_settings['text_minimum_class'].classlist('not-counting-downloaded',$maxclass,$AUTHORITY['not-counting-downloaded'] ?? '',0,true).nexus_trans('permission.not-counting-downloaded.desc'),1); +// tr(nexus_trans('permission.not-counting-hit-and-run.text'), $lang_settings['text_minimum_class'].classlist('not-counting-hit-and-run',$maxclass,$AUTHORITY['not-counting-hit-and-run'] ?? '',0,true).nexus_trans('permission.not-counting-hit-and-run.desc'),1); + + tr($lang_settings['row_save_settings'],"", 1); + print (""); } elseif ($action == 'basicsettings') // basic settings { @@ -651,6 +655,9 @@ elseif ($action == 'accountsettings'){ tr($lang_settings['row_delete_packed'],$lang_settings['text_delete_packed_note_one']."".$lang_settings['text_delete_packed_note_two'], 1); tr($lang_settings['row_delete_unpacked'],$lang_settings['text_delete_unpacked_note_one']."".$lang_settings['text_delete_unpacked_note_two'], 1); tr($lang_settings['row_delete_no_transfer'],$lang_settings['text_delete_transfer_note_one']."".$lang_settings['text_delete_transfer_note_two']."".$lang_settings['text_delete_transfer_note_three'], 1); + tr($lang_settings['row_destroy_disabled'],$lang_settings['text_destroy_disabled_note_one']."".$lang_settings['text_destroy_disabled_note_two'], 1); + + print(""); tr($lang_settings['row_ban_peasant_one'].get_user_class_name(UC_PEASANT,false,false,true).$lang_settings['row_ban_peasant_two'],get_user_class_name(UC_PEASANT,false,true,true).$lang_settings['text_ban_peasant_note_one']."".$lang_settings['text_ban_peasant_note_two'], 1); $inputAlias = "0_alias"; diff --git a/public/viewsnatches.php b/public/viewsnatches.php index 0d7c062d..1dd22577 100644 --- a/public/viewsnatches.php +++ b/public/viewsnatches.php @@ -13,7 +13,7 @@ begin_main_frame(); $torrent_name = get_single_value("torrents", "name", "WHERE id = ".sqlesc($id)); print("

          ".$lang_viewsnatches['text_snatch_detail_for'] . "".htmlspecialchars($torrent_name)."

          "); $count = get_row_count("snatched", "WHERE finished = 'yes' AND torrentid = ".sqlesc($id)); - +$seedBoxRep = new \App\Repositories\SeedBoxRepository(); if ($count){ $perpage = 25; list($pagertop, $pagerbottom, $limit) = pager($perpage, $count, $_SERVER["SCRIPT_NAME"] . "?id=" . htmlspecialchars($id) . "&" ); @@ -53,7 +53,7 @@ if ($count){ } else $username = get_username($arr['userid']); $reportImage = "\"Report\""; - print("".(user_can('userprofile') ? "" : "")."\n"); + print("".(user_can('userprofile') || $arr['userid'] == $CURUSER['id'] ? "" : "")."\n"); } print("
          ".$lang_getusertorrentlistajax['col_type']."".$lang_getusertorrentlistajax['col_name']."".$lang_getusertorrentlistajax['col_added']."\"size\"\"seeders\"\"leechers\"".$lang_getusertorrentlistajax['col_uploaded']."".$lang_getusertorrentlistajax['col_downloaded']."".$lang_getusertorrentlistajax['col_ratio']."".$lang_getusertorrentlistajax['col_se_time']."".$lang_getusertorrentlistajax['col_le_time']."".$lang_getusertorrentlistajax['col_time_completed']."".$lang_getusertorrentlistajax['col_anonymous']."%sIP%s"."". str_replace(" ", "
          ", gettime($arr['completedat'],false)). "
          ".$arr['anonymous']."%s
          %s
          %s
          ".$lang_settings['text_user_promotion_demotion']."
          " . $username ."".$arr['ip']."".$uploaded."@".$uprate.$lang_viewsnatches['text_per_second']."
          ".$downloaded."@".$downrate.$lang_viewsnatches['text_per_second']."
          $ratio$seedtime$leechtime".gettime($arr['completedat'],true,false)."".gettime($arr['last_action'],true,false)."".($userrow['privacy'] != 'strong' || user_can('viewanonymous') ? "$reportImage" : $reportImage)."
          " . $username ."".$arr['ip'].$seedBoxRep->renderIcon($arr['ip'], $arr['userid'])."".$uploaded."@".$uprate.$lang_viewsnatches['text_per_second']."
          ".$downloaded."@".$downrate.$lang_viewsnatches['text_per_second']."
          $ratio$seedtime$leechtime".gettime($arr['completedat'],true,false)."".gettime($arr['last_action'],true,false)."".($userrow['privacy'] != 'strong' || user_can('viewanonymous') ? "$reportImage" : $reportImage)."
          \n"); print($pagerbottom); diff --git a/resources/lang/en/cleanup.php b/resources/lang/en/cleanup.php index cefcc9fb..a4c212e2 100644 --- a/resources/lang/en/cleanup.php +++ b/resources/lang/en/cleanup.php @@ -2,9 +2,9 @@ return [ 'ban_user_with_leech_warning_expired' => 'Banned by system because of leech warning expired.', - 'delete_user_unconfirmed' => 'Disable by system because of unconfirmed excess deadline.', - 'delete_user_no_transfer_alt_last_access_time' => 'Disable inactive user accounts, no transfer. Alt: last access time.', - 'delete_user_no_transfer_alt_register_time' => 'Disable inactive user accounts, no transfer. Alt: register time.', - 'delete_user_not_parked' => 'Disable inactive user accounts, not parked.', - 'delete_user_parked' => 'Disable inactive user accounts, parked.', + 'disable_user_unconfirmed' => 'Disable by system because of unconfirmed excess deadline.', + 'disable_user_no_transfer_alt_last_access_time' => 'Disable inactive user accounts, no transfer. Alt: last access time.', + 'disable_user_no_transfer_alt_register_time' => 'Disable inactive user accounts, no transfer. Alt: register time.', + 'disable_user_not_parked' => 'Disable inactive user accounts, not parked.', + 'disable_user_parked' => 'Disable inactive user accounts, parked.', ]; diff --git a/resources/lang/zh_CN/cleanup.php b/resources/lang/zh_CN/cleanup.php index 9528b3b8..9d8ad4da 100644 --- a/resources/lang/zh_CN/cleanup.php +++ b/resources/lang/zh_CN/cleanup.php @@ -2,9 +2,9 @@ return [ 'ban_user_with_leech_warning_expired' => '上传警告到期,被系统禁用.', - 'delete_user_unconfirmed' => '超时未确认,被系统封禁.', - 'delete_user_no_transfer_alt_last_access_time' => '封禁非活跃的无流量账号,由最近访问时间断定.', - 'delete_user_no_transfer_alt_register_time' => '封禁非活跃的无流量账号,由注册时间时间断定.', - 'delete_user_not_parked' => '定时封禁未挂起的非活跃账号.', - 'delete_user_parked' => '定时封禁已挂起的非活跃账号.', + 'disable_user_unconfirmed' => '超时未确认,被系统封禁.', + 'disable_user_no_transfer_alt_last_access_time' => '封禁非活跃的无流量账号,由最近访问时间断定.', + 'disable_user_no_transfer_alt_register_time' => '封禁非活跃的无流量账号,由注册时间时间断定.', + 'disable_user_not_parked' => '定时封禁未挂起的非活跃账号.', + 'disable_user_parked' => '定时封禁已挂起的非活跃账号.', ]; diff --git a/resources/lang/zh_CN/permission.php b/resources/lang/zh_CN/permission.php index 5d1dbb7b..ba4a205c 100644 --- a/resources/lang/zh_CN/permission.php +++ b/resources/lang/zh_CN/permission.php @@ -213,4 +213,12 @@ return [ 'text' => '允许个性条', 'desc' => '允许用户使用个性条', ], +// 'not-counting-downloaded' => [ +// 'text' => '不计下载量', +// 'desc' => '用户下载量不增加', +// ], +// 'not-counting-hit-and-run' => [ +// 'text' => '不计 H&R', +// 'desc' => '下载带 H&R 标记的种子不记 H&R。注意:等级为 VIP 是固定不计的', +// ], ]; diff --git a/resources/lang/zh_TW/cleanup.php b/resources/lang/zh_TW/cleanup.php index f996b106..76358e15 100644 --- a/resources/lang/zh_TW/cleanup.php +++ b/resources/lang/zh_TW/cleanup.php @@ -2,9 +2,9 @@ return [ 'ban_user_with_leech_warning_expired' => '上傳警告到期,被系統禁用.', - 'delete_user_unconfirmed' => '超時未確認,被系統封禁.', - 'delete_user_no_transfer_alt_last_access_time' => '封禁非活躍的無流量賬號,由最近訪問時間斷定.', - 'delete_user_no_transfer_alt_register_time' => '封禁非活躍的無流量賬號,由註冊時間時間斷定.', - 'delete_user_not_parked' => '定時封禁未掛起的非活躍賬號.', - 'delete_user_parked' => '定時封禁已掛起的非活躍賬號.', + 'disable_user_unconfirmed' => '超時未確認,被系統封禁.', + 'disable_user_no_transfer_alt_last_access_time' => '封禁非活躍的無流量賬號,由最近訪問時間斷定.', + 'disable_user_no_transfer_alt_register_time' => '封禁非活躍的無流量賬號,由註冊時間時間斷定.', + 'disable_user_not_parked' => '定時封禁未掛起的非活躍賬號.', + 'disable_user_parked' => '定時封禁已掛起的非活躍賬號.', ]; From 29c9d488fb7fa3c0573f7fb7d8d88b7f139bfa67 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 17 Oct 2022 04:55:08 +0800 Subject: [PATCH 46/59] fix complain IP show to complainer --- public/complains.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/public/complains.php b/public/complains.php index 5d841230..9c994922 100644 --- a/public/complains.php +++ b/public/complains.php @@ -114,8 +114,8 @@ if($_SERVER['REQUEST_METHOD'] === 'POST'){ if ($user) { printf(' [%s]', urlencode($user->username), $lang_complains['text_view_band_log']); } + printf('
          IP: ' . htmlspecialchars($complain['ip'])); } - printf('
          IP: ' . htmlspecialchars($complain['ip'])); echo '
          ', format_comment($complain['body']); end_frame(); // REPLIES @@ -123,7 +123,11 @@ if($_SERVER['REQUEST_METHOD'] === 'POST'){ $res = sql_query(sprintf('SELECT * FROM `complain_replies` WHERE complain = %u ORDER BY id DESC', $complain['id'])) or sqlerr(__FILE__, __LINE__); if(mysql_num_rows($res)){ while($row = mysql_fetch_assoc($res)){ - printf('%s @ %s (%s): ', $row['userid'] ? get_plain_username($row['userid']) : $lang_complains['text_complainer'], gettime($row['added']), htmlspecialchars($row['ip'])); + printf('%s @ %s', $row['userid'] ? get_plain_username($row['userid']) : $lang_complains['text_complainer'], gettime($row['added'])); + if ($isAdmin) { + printf(' (%s)', htmlspecialchars($row['ip'])); + } + echo ': '; echo format_comment($row['body']) . '
          '; } }else{ From 68e96441e2e3555abf7c7a855f7b8bb889dc1c80 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Fri, 21 Oct 2022 00:26:39 +0800 Subject: [PATCH 47/59] user can not send invite can view invitee --- include/constants.php | 4 ++-- public/invite.php | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/constants.php b/include/constants.php index 1825f479..3dc834db 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@
  • "); + if (user_can('sendinvite')) { + print ("
    "); + } end_main_frame(); } if (($CURUSER['id'] != $id && !user_can('viewinvite')) || !is_valid_id($id)) stderr($lang_invite['std_sorry'],$lang_invite['std_permission_denied']); -if (!user_can('sendinvite')) -stderr($lang_invite['std_sorry'],$lang_invite['std_only'].get_user_class_name($sendinvite_class,false,true,true).$lang_invite['std_or_above_can_invite'],false); $res = sql_query("SELECT username FROM users WHERE id = ".mysql_real_escape_string($id)) or sqlerr(); $user = mysql_fetch_assoc($res); stdhead($lang_invite['head_invites']); @@ -46,6 +46,8 @@ if ($inv["invites"] != 1){ } if ($type == 'new'){ + if (!user_can('sendinvite')) + stderr($lang_invite['std_sorry'],$lang_invite['std_only'].get_user_class_name($sendinvite_class,false,true,true).$lang_invite['std_or_above_can_invite'],false, false); registration_check('invitesystem',true,false); if ($CURUSER['invites'] <= 0) { stdmsg($lang_invite['std_sorry'],$lang_invite['std_no_invites_left']. From 348112364cf68220af37496d06215d5e759b78ed Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 22 Oct 2022 01:49:34 +0800 Subject: [PATCH 48/59] [admin] change filter position above content --- app/Filament/PageList.php | 6 ++++++ app/Filament/PageListSingle.php | 16 ++++++++++++++ .../System/SeedBoxRecordResource.php | 10 +++++++++ .../System/UsernameChangeLogResource.php | 10 +++++++++ .../Pages/ManageUsernameChangeLogs.php | 5 ++--- .../Resources/Torrent/TorrentResource.php | 21 ++++++++++++++++--- .../TorrentResource/Pages/ListTorrents.php | 3 +++ app/Filament/Resources/User/ClaimResource.php | 11 +++++++++- .../Resources/User/ExamUserResource.php | 15 +++++++++++++ .../Resources/User/HitAndRunResource.php | 10 +++++++++ .../Resources/User/UserMedalResource.php | 16 +++++++++++++- app/Filament/Resources/User/UserResource.php | 9 ++++++++ .../User/UserResource/Pages/ListUsers.php | 6 +++++- nexus/Install/settings.default.php | 2 +- resources/lang/en/exam.php | 1 + resources/lang/en/medal.php | 1 + resources/lang/zh_CN/exam.php | 1 + resources/lang/zh_CN/medal.php | 1 + resources/lang/zh_TW/exam.php | 1 + resources/lang/zh_TW/medal.php | 1 + 20 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 app/Filament/PageListSingle.php diff --git a/app/Filament/PageList.php b/app/Filament/PageList.php index a1507d1c..ae28ce43 100644 --- a/app/Filament/PageList.php +++ b/app/Filament/PageList.php @@ -3,6 +3,7 @@ namespace App\Filament; use Filament\Resources\Pages\ListRecords; +use Filament\Tables\Filters\Layout; use Illuminate\Database\Eloquent\Model; class PageList extends ListRecords @@ -15,4 +16,9 @@ class PageList extends ListRecords return null; }; } + + protected function getTableFiltersLayout(): ?string + { + return Layout::AboveContent; + } } diff --git a/app/Filament/PageListSingle.php b/app/Filament/PageListSingle.php new file mode 100644 index 00000000..f75df167 --- /dev/null +++ b/app/Filament/PageListSingle.php @@ -0,0 +1,16 @@ +label(__('label.seed_box_record.status')), ]) ->filters([ + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->label('UID') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); + }) + , Tables\Filters\SelectFilter::make('type')->options(SeedBoxRecord::listTypes('text'))->label(__('label.seed_box_record.type')), Tables\Filters\SelectFilter::make('status')->options(SeedBoxRecord::listStatus('text'))->label(__('label.seed_box_record.status')), ]) diff --git a/app/Filament/Resources/System/UsernameChangeLogResource.php b/app/Filament/Resources/System/UsernameChangeLogResource.php index aff1d66b..b31a4b35 100644 --- a/app/Filament/Resources/System/UsernameChangeLogResource.php +++ b/app/Filament/Resources/System/UsernameChangeLogResource.php @@ -65,6 +65,16 @@ class UsernameChangeLogResource extends Resource ]) ->defaultSort('id', 'desc') ->filters([ + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->label('UID') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); + }) + , Tables\Filters\SelectFilter::make('change_type')->options(UsernameChangeLog::listChangeType())->label(__('username-change-log.labels.change_type')), ]) ->actions([ diff --git a/app/Filament/Resources/System/UsernameChangeLogResource/Pages/ManageUsernameChangeLogs.php b/app/Filament/Resources/System/UsernameChangeLogResource/Pages/ManageUsernameChangeLogs.php index c34d4cee..8dee8b4e 100644 --- a/app/Filament/Resources/System/UsernameChangeLogResource/Pages/ManageUsernameChangeLogs.php +++ b/app/Filament/Resources/System/UsernameChangeLogResource/Pages/ManageUsernameChangeLogs.php @@ -2,14 +2,13 @@ namespace App\Filament\Resources\System\UsernameChangeLogResource\Pages; +use App\Filament\PageListSingle; use App\Filament\Resources\System\UsernameChangeLogResource; use Filament\Pages\Actions; use Filament\Resources\Pages\ManageRecords; -class ManageUsernameChangeLogs extends ManageRecords +class ManageUsernameChangeLogs extends PageListSingle { - protected ?string $maxContentWidth = 'full'; - protected static string $resource = UsernameChangeLogResource::class; protected function getActions(): array diff --git a/app/Filament/Resources/Torrent/TorrentResource.php b/app/Filament/Resources/Torrent/TorrentResource.php index 04771692..41fb6bbf 100644 --- a/app/Filament/Resources/Torrent/TorrentResource.php +++ b/app/Filament/Resources/Torrent/TorrentResource.php @@ -92,9 +92,13 @@ class TorrentResource extends Resource Tables\Columns\BooleanColumn::make('hr') ->label(__('label.torrent.hr')) , - Tables\Columns\TextColumn::make('size')->label(__('label.torrent.size'))->formatStateUsing(fn ($state) => mksize($state)), - Tables\Columns\TextColumn::make('seeders')->label(__('label.torrent.seeders')), - Tables\Columns\TextColumn::make('leechers')->label(__('label.torrent.leechers')), + Tables\Columns\TextColumn::make('size') + ->label(__('label.torrent.size')) + ->formatStateUsing(fn ($state) => mksize($state)) + ->sortable() + , + Tables\Columns\TextColumn::make('seeders')->label(__('label.torrent.seeders'))->sortable(), + Tables\Columns\TextColumn::make('leechers')->label(__('label.torrent.leechers'))->sortable(), Tables\Columns\BadgeColumn::make('approval_status') ->visible($showApproval) ->label(__('label.torrent.approval_status')) @@ -108,6 +112,17 @@ class TorrentResource extends Resource ]) ->defaultSort('id', 'desc') ->filters([ + Tables\Filters\Filter::make('owner') + ->form([ + Forms\Components\TextInput::make('owner') + ->label(__('label.torrent.owner')) + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['owner'], fn (Builder $query, $owner) => $query->where("owner", $owner)); + }) + , + Tables\Filters\SelectFilter::make('visible') ->options(self::$yesOrNo) ->label(__('label.torrent.visible')), diff --git a/app/Filament/Resources/Torrent/TorrentResource/Pages/ListTorrents.php b/app/Filament/Resources/Torrent/TorrentResource/Pages/ListTorrents.php index e9f4e076..55da176d 100644 --- a/app/Filament/Resources/Torrent/TorrentResource/Pages/ListTorrents.php +++ b/app/Filament/Resources/Torrent/TorrentResource/Pages/ListTorrents.php @@ -7,6 +7,7 @@ use App\Filament\Resources\Torrent\TorrentResource; use Filament\Pages\Actions; use Filament\Resources\Pages\ListRecords; + class ListTorrents extends PageList { protected static string $resource = TorrentResource::class; @@ -17,4 +18,6 @@ class ListTorrents extends PageList // Actions\CreateAction::make(), ]; } + + } diff --git a/app/Filament/Resources/User/ClaimResource.php b/app/Filament/Resources/User/ClaimResource.php index 0bc70183..33633c6c 100644 --- a/app/Filament/Resources/User/ClaimResource.php +++ b/app/Filament/Resources/User/ClaimResource.php @@ -65,7 +65,16 @@ class ClaimResource extends Resource ]) ->defaultSort('id', 'desc') ->filters([ - // + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->label('UID') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); + }) + , ]) ->actions([ // Tables\Actions\EditAction::make(), diff --git a/app/Filament/Resources/User/ExamUserResource.php b/app/Filament/Resources/User/ExamUserResource.php index 9d439447..387597eb 100644 --- a/app/Filament/Resources/User/ExamUserResource.php +++ b/app/Filament/Resources/User/ExamUserResource.php @@ -4,6 +4,7 @@ namespace App\Filament\Resources\User; use App\Filament\Resources\User\ExamUserResource\Pages; use App\Filament\Resources\User\ExamUserResource\RelationManagers; +use App\Models\Exam; use App\Models\ExamUser; use App\Repositories\ExamRepository; use App\Repositories\HitAndRunRepository; @@ -66,6 +67,20 @@ class ExamUserResource extends Resource ]) ->defaultSort('id', 'desc') ->filters([ + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->label('UID') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); + }) + , + Tables\Filters\SelectFilter::make('exam_id') + ->options(Exam::query()->pluck('name', 'id')->toArray()) + ->label(__('exam.label')) + , Tables\Filters\SelectFilter::make('status')->options(ExamUser::listStatus(true))->label(__("label.status")), Tables\Filters\SelectFilter::make('is_done')->options(['0' => 'No', '1' => 'yes'])->label(__('label.exam_user.is_done')), ]) diff --git a/app/Filament/Resources/User/HitAndRunResource.php b/app/Filament/Resources/User/HitAndRunResource.php index dc90ede1..94558ec0 100644 --- a/app/Filament/Resources/User/HitAndRunResource.php +++ b/app/Filament/Resources/User/HitAndRunResource.php @@ -59,6 +59,16 @@ class HitAndRunResource extends Resource ]) ->defaultSort('id', 'desc') ->filters([ + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->label('UID') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); + }) + , Tables\Filters\SelectFilter::make('status')->options(HitAndRun::listStatus(true))->label(__('label.status')), ]) ->actions([ diff --git a/app/Filament/Resources/User/UserMedalResource.php b/app/Filament/Resources/User/UserMedalResource.php index 9ef4f34b..4d2b59c4 100644 --- a/app/Filament/Resources/User/UserMedalResource.php +++ b/app/Filament/Resources/User/UserMedalResource.php @@ -4,6 +4,7 @@ namespace App\Filament\Resources\User; use App\Filament\Resources\User\UserMedalResource\Pages; use App\Filament\Resources\User\UserMedalResource\RelationManagers; +use App\Models\Medal; use App\Models\UserMedal; use Filament\Forms; use Filament\Resources\Form; @@ -59,7 +60,20 @@ class UserMedalResource extends Resource ]) ->defaultSort('id', 'desc') ->filters([ - + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->label('UID') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); + }) + , + Tables\Filters\SelectFilter::make('medal_id') + ->options(Medal::query()->pluck('name', 'id')->toArray()) + ->label(__('medal.label')) + , ]) ->actions([ Tables\Actions\DeleteAction::make(), diff --git a/app/Filament/Resources/User/UserResource.php b/app/Filament/Resources/User/UserResource.php index 9e32fc54..a0a6417a 100644 --- a/app/Filament/Resources/User/UserResource.php +++ b/app/Filament/Resources/User/UserResource.php @@ -80,6 +80,15 @@ class UserResource extends Resource ]) ->defaultSort('added', 'desc') ->filters([ + Tables\Filters\Filter::make('id') + ->form([ + Forms\Components\TextInput::make('id') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['id'], fn (Builder $query, $id) => $query->where("id", $id)); + }) + , Tables\Filters\SelectFilter::make('class')->options(array_column(User::$classes, 'text'))->label(__('label.user.class')), Tables\Filters\SelectFilter::make('status')->options(['confirmed' => 'confirmed', 'pending' => 'pending'])->label(__('label.user.status')), Tables\Filters\SelectFilter::make('enabled')->options(self::$yesOrNo)->label(__('label.user.enabled')), diff --git a/app/Filament/Resources/User/UserResource/Pages/ListUsers.php b/app/Filament/Resources/User/UserResource/Pages/ListUsers.php index 897de5d4..bf81f3fb 100644 --- a/app/Filament/Resources/User/UserResource/Pages/ListUsers.php +++ b/app/Filament/Resources/User/UserResource/Pages/ListUsers.php @@ -7,6 +7,7 @@ use App\Filament\Resources\User\UserResource; use Filament\Pages\Actions; use Filament\Resources\Pages\ListRecords; use Illuminate\Database\Eloquent\Model; +use Filament\Tables\Filters\Layout; class ListUsers extends PageList { @@ -25,6 +26,9 @@ class ListUsers extends PageList // } - + protected function getTableFiltersLayout(): ?string + { + return Layout::AboveContent; + } } diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index ed7f04d5..1f8398ea 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -304,7 +304,7 @@ return array ( 8 => '5', 9 => '10', ), - 'destroy_disabled' => 500, + 'destroy_disabled' => 0, ), 'torrent' => array ( diff --git a/resources/lang/en/exam.php b/resources/lang/en/exam.php index c6c48728..b5163037 100644 --- a/resources/lang/en/exam.php +++ b/resources/lang/en/exam.php @@ -1,6 +1,7 @@ 'Exam', 'name' => 'Exam name', 'index' => 'Exam index', 'time_range' => 'Exam time', diff --git a/resources/lang/en/medal.php b/resources/lang/en/medal.php index 9c953e4d..1800bd16 100644 --- a/resources/lang/en/medal.php +++ b/resources/lang/en/medal.php @@ -1,6 +1,7 @@ 'Medal', 'action_wearing' => 'Wear', 'admin' => [ 'list' => [ diff --git a/resources/lang/zh_CN/exam.php b/resources/lang/zh_CN/exam.php index bff1252e..fd488e0d 100644 --- a/resources/lang/zh_CN/exam.php +++ b/resources/lang/zh_CN/exam.php @@ -1,6 +1,7 @@ '考核', 'name' => '考核名称', 'index' => '考核指标', 'time_range' => '考核时间', diff --git a/resources/lang/zh_CN/medal.php b/resources/lang/zh_CN/medal.php index 7993d4e5..b3099d15 100644 --- a/resources/lang/zh_CN/medal.php +++ b/resources/lang/zh_CN/medal.php @@ -1,6 +1,7 @@ '勋章', 'action_wearing' => '佩戴', 'admin' => [ 'list' => [ diff --git a/resources/lang/zh_TW/exam.php b/resources/lang/zh_TW/exam.php index e6e5a1b7..21490e57 100644 --- a/resources/lang/zh_TW/exam.php +++ b/resources/lang/zh_TW/exam.php @@ -1,6 +1,7 @@ '考核', 'name' => '考核名稱', 'index' => '考核指標', 'time_range' => '考核時間', diff --git a/resources/lang/zh_TW/medal.php b/resources/lang/zh_TW/medal.php index 3f6af04a..3ec07fd5 100644 --- a/resources/lang/zh_TW/medal.php +++ b/resources/lang/zh_TW/medal.php @@ -1,6 +1,7 @@ '勛章', 'action_wearing' => '佩戴', 'admin' => [ 'list' => [ From 505c7122b1f3c030ab40bbd7f0f8672a26ed2fa4 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 22 Oct 2022 20:52:08 +0800 Subject: [PATCH 49/59] add global search --- app/Filament/Resources/User/ClaimResource.php | 10 ++ app/Models/Torrent.php | 2 - include/constants.php | 2 +- include/functions.php | 78 +++++++---- lang/chs/lang_functions.php | 2 +- lang/cht/lang_functions.php | 2 +- lang/en/lang_functions.php | 6 +- public/search.php | 125 ++++++++++++++++++ public/torrents.php | 10 +- resources/lang/en/claim.php | 3 + resources/lang/en/search.php | 13 ++ resources/lang/en/searchbox.php | 4 +- resources/lang/zh_CN/claim.php | 4 + resources/lang/zh_CN/search.php | 13 ++ resources/lang/zh_TW/claim.php | 3 + resources/lang/zh_TW/search.php | 13 ++ 16 files changed, 252 insertions(+), 38 deletions(-) create mode 100644 public/search.php create mode 100644 resources/lang/en/search.php create mode 100644 resources/lang/zh_CN/search.php create mode 100644 resources/lang/zh_TW/search.php diff --git a/app/Filament/Resources/User/ClaimResource.php b/app/Filament/Resources/User/ClaimResource.php index 33633c6c..6559b76f 100644 --- a/app/Filament/Resources/User/ClaimResource.php +++ b/app/Filament/Resources/User/ClaimResource.php @@ -75,6 +75,16 @@ class ClaimResource extends Resource return $query->when($data['uid'], fn (Builder $query, $uid) => $query->where("uid", $uid)); }) , + Tables\Filters\Filter::make('torrent_id') + ->form([ + Forms\Components\TextInput::make('torrent_id') + ->label(__('claim.fields.torrent_id')) + ->placeholder(__('claim.fields.torrent_id')) + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['torrent_id'], fn (Builder $query, $value) => $query->where("torrent_id", $value)); + }) + , ]) ->actions([ // Tables\Actions\EditAction::make(), diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index a36faa4c..9f792ef1 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -5,8 +5,6 @@ namespace App\Models; use App\Repositories\TagRepository; use Carbon\Carbon; use Illuminate\Database\Eloquent\Casts\Attribute; -use JeroenG\Explorer\Application\Explored; -use Laravel\Scout\Searchable; class Torrent extends NexusModel { diff --git a/include/constants.php b/include/constants.php index 3dc834db..f92778d0 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ ] []: '.$lang_functions['text_attended'].'', $attendance->points, $CURUSER['attendance_card']); }else{ printf(' %s', $lang_functions['text_attendance']);}?> - : []: + = \App\Models\User::CLASS_ADMINISTRATOR) printf('[%s]', nexus_env('FILAMENT_PATH', 'nexusphp'), $lang_functions['text_management_system'])?>
    @@ -2648,27 +2648,47 @@ else { H&R: %s]', (new \App\Repositories\HitAndRunRepository())->getStatusStats($CURUSER['id']))?> %s]', $CURUSER['id'], (new \App\Repositories\ClaimRepository())->getStats($CURUSER['id']))?> - = \App\Models\User::CLASS_ADMINISTRATOR) printf('[%s]', nexus_env('FILAMENT_PATH', 'nexusphp'), $lang_functions['text_management_system'])?> -
    + +
    +
    +
    +
    + : + +
    +
    + : + 'width: 108px'])?> +
    +
    +
    +
    +
    + + get_value('staff_report_count'); - if ($totalreports == ""){ - $totalreports = get_row_count("reports"); - $Cache->cache_value('staff_report_count', $totalreports, 900); - } - $totalcheaters = $Cache->get_value('staff_cheater_count'); - if ($totalcheaters == ""){ - $totalcheaters = get_row_count("cheaters"); - $Cache->cache_value('staff_cheater_count', $totalcheaters, 900); - } - print( - "\"cheaterbox\" ".$totalcheaters - ." \"reportbox\" ".$totalreports - ); - } +if (user_can('staffmem')) { + $totalreports = $Cache->get_value('staff_report_count'); + if ($totalreports == ""){ + $totalreports = get_row_count("reports"); + $Cache->cache_value('staff_report_count', $totalreports, 900); + } + $totalcheaters = $Cache->get_value('staff_cheater_count'); + if ($totalcheaters == ""){ + $totalcheaters = get_row_count("cheaters"); + $Cache->cache_value('staff_cheater_count', $totalcheaters, 900); + } + print( + "\"cheaterbox\" ".$totalcheaters + ." \"reportbox\" ".$totalreports + ); +} +print(" \"Buddylist\""); +print(" \"RSS\""); +print '
    '; +//echo $lang_functions['text_the_time_is_now'].$datum['hours'].":".$datum['minutes'] . '
    '; // $cacheKey = "staff_message_count_" . $CURUSER['id']; // $totalsm = $Cache->get_value($cacheKey); $totalsm = \App\Repositories\MessageRepository::getStaffMessageCountCache($CURUSER['id'], 'total'); @@ -2683,8 +2703,7 @@ else { print("".$inboxpic." ".($messages ? $messages." (".$unread.$lang_functions['text_message_new'].")" : "0")); print(" \"sentbox\" ".($outmessages ? $outmessages : "0")); - print(" \"Buddylist\""); - print(" \"RSS\""); + ?>
    @@ -3544,7 +3563,7 @@ foreach ($rows as $row) } $stickyicon = apply_filter('sticky_icon', $stickyicon, $row); $sp_torrent = get_torrent_promotion_append($row['sp_state'],"",true,$row["added"], $row['promotion_time_type'], $row['promotion_until'], $row['__ignore_global_sp_state'] ?? false); - $hrImg = get_hr_img($row, $searchBoxId); + $hrImg = get_hr_img($row, $row['search_box_id']); //cover $coverSrc = $tdCover = ''; @@ -4730,7 +4749,7 @@ function get_hr_img(array $torrent, $searchBoxId) if ($mode == \App\Models\HitAndRun::MODE_GLOBAL || ($mode == \App\Models\HitAndRun::MODE_MANUAL && isset($torrent['hr']) && $torrent['hr'] == \App\Models\Torrent::HR_YES)) { $result = 'H&R'; } - do_log("mode: $mode, result: $result"); + do_log("searchBoxId: $searchBoxId, mode: $mode, result: $result"); return $result; } @@ -6073,4 +6092,17 @@ function build_bonus_table(array $user, array $bonusResult = [], array $options ]; } + +function build_search_area($searchArea, array $options = []) +{ + $result = sprintf(''; + return $result; +} ?> diff --git a/lang/chs/lang_functions.php b/lang/chs/lang_functions.php index 082dc32f..e5faaa57 100644 --- a/lang/chs/lang_functions.php +++ b/lang/chs/lang_functions.php @@ -87,7 +87,7 @@ $lang_functions = array 'title_torrents_seeding' => "当前做种", 'title_torrents_leeching' => "当前下载", 'text_connectable' => "可连接:", - 'text_the_time_is_now' => "当前时间:", + 'text_the_time_is_now' => "时间: ", 'text_message_new' => " 新", 'title_sentbox' => "发件箱", 'title_inbox' => "收件箱", diff --git a/lang/cht/lang_functions.php b/lang/cht/lang_functions.php index 96ff35d5..f7429a4a 100644 --- a/lang/cht/lang_functions.php +++ b/lang/cht/lang_functions.php @@ -87,7 +87,7 @@ $lang_functions = array 'title_torrents_seeding' => "當前做種", 'title_torrents_leeching' => "當前下載", 'text_connectable' => "可連接:", - 'text_the_time_is_now' => "當前時間:", + 'text_the_time_is_now' => "時間: ", 'text_message_new' => " 新", 'title_sentbox' => "發件箱", 'title_inbox' => "收件箱", diff --git a/lang/en/lang_functions.php b/lang/en/lang_functions.php index bc4fbe54..229d4047 100644 --- a/lang/en/lang_functions.php +++ b/lang/en/lang_functions.php @@ -83,11 +83,11 @@ $lang_functions = array 'text_ratio' => "Ratio:", 'text_uploaded' => "Uploaded:", 'text_downloaded' => "Downloaded:", - 'text_active_torrents' => "Active Torrents: ", + 'text_active_torrents' => "Active: ", 'title_torrents_seeding' => "Torrents Seeding", 'title_torrents_leeching' => "Torrents Leeching", 'text_connectable' => "Connectable: ", - 'text_the_time_is_now' => "The time is now: ", + 'text_the_time_is_now' => "Time: ", 'text_message_new' => " New", 'title_sentbox' => "sentbox", 'title_inbox' => "inbox", @@ -322,7 +322,7 @@ $lang_functions = array 'text_invalid' => 'Invalid', 'text_technical_info' => 'MediaInfo', 'text_technical_info_help_text' => 'MediaInfo comes from software MediaInfo,open file, click the view menu > text > right click in the box > select all > copy > past into this box.', - 'text_management_system' => 'Management system', + 'text_management_system' => 'Management', 'text_seed_points' => 'Seed points', 'spoiler_expand_collapse' => 'Click to expand/collapse', 'spoiler_default_title' => 'Collapse content', diff --git a/public/search.php b/public/search.php new file mode 100644 index 00000000..a3f7d7e0 --- /dev/null +++ b/public/search.php @@ -0,0 +1,125 @@ +join($tableCategory, "$tableTorrent.category", "=", "$tableCategory.id"); + if (get_setting('main.spsct') == 'yes' && !user_can('view_special_torrent')) { + $torrentQuery->where("$tableCategory.mode", get_setting('main.browsecat')); + } + if ($searchArea == \App\Repositories\SearchRepository::SEARCH_AREA_TITLE) { + foreach ($searchArr as $queryString) { + $q = "%{$queryString}%"; + $torrentQuery->where(function (\Illuminate\Database\Query\Builder $query) use ($q, $tableTorrent) { + return $query->where("$tableTorrent.name", 'like', $q)->orWhere("$tableTorrent.small_descr", "like", $q); + }); + } + } elseif ($searchArea == \App\Repositories\SearchRepository::SEARCH_AREA_DESC) { + foreach ($searchArr as $queryString) { + $q = "%{$queryString}%"; + $torrentQuery->where("$tableTorrent.descr", "like", $q); + } + } elseif ($searchArea == \App\Repositories\SearchRepository::SEARCH_AREA_OWNER) { + $torrentQuery->join($tableUser, "$tableTorrent.owner", "=", "$tableUser.id"); + foreach ($searchArr as $queryString) { + $q = "%{$queryString}%"; + $torrentQuery->where("$tableUser.username", "like", $q); + } + } elseif ($searchArea == \App\Repositories\SearchRepository::SEARCH_AREA_IMDB) { + foreach ($searchArr as $queryString) { + $q = "%{$queryString}%"; + $torrentQuery->where("$tableTorrent.url", "like", $q); + } + } else { + foreach ($searchArr as $queryString) { + $q = "%{$queryString}%"; + $torrentQuery->where("$tableTorrent.name", "like", $q); + } + write_log("User " . $CURUSER["username"] . "," . $CURUSER["ip"] . " is hacking search_area field in" . $_SERVER['SCRIPT_NAME'], 'mod'); + } + if ($approvalStatus !== null) { + $torrentQuery->where("$tableTorrent.approval_status", $approvalStatus); + } + $torrentQuery->where("$tableTorrent.visible", 'yes'); + + $count = $torrentQuery->count(); +} + +if ($CURUSER["torrentsperpage"]) + $torrentsperpage = (int)$CURUSER["torrentsperpage"]; +elseif ($torrentsperpage_main) + $torrentsperpage = $torrentsperpage_main; +else $torrentsperpage = 50; + +// sorting by MarkoStamcar +$column = 'id'; +$ascdesc = 'desc'; +$addparam = "?search=$search&"; +if (isset($_GET['sort']) && $_GET['sort'] && isset($_GET['type']) && $_GET['type']) { + + switch($_GET['sort']) { + case '1': $column = "name"; break; + case '2': $column = "numfiles"; break; + case '3': $column = "comments"; break; + case '4': $column = "added"; break; + case '5': $column = "size"; break; + case '6': $column = "times_completed"; break; + case '7': $column = "seeders"; break; + case '8': $column = "leechers"; break; + case '9': $column = "owner"; break; + default: $column = "id"; break; + } + + switch($_GET['type']) { + case 'asc': $ascdesc = "ASC"; $linkascdesc = "asc"; break; + case 'desc': $ascdesc = "DESC"; $linkascdesc = "desc"; break; + default: $ascdesc = "DESC"; $linkascdesc = "desc"; break; + } + + $addparam .= "sort=" . intval($_GET['sort']) . "&type=" . $linkascdesc . "&"; + +} + +list($pagertop, $pagerbottom, $limit, $offset, $size, $page) = pager($torrentsperpage, $count, $addparam); + +stdhead(nexus_trans('search.global_search')); +print("
    "); +if ($search && $count > 0) { + $fieldsStr = implode(', ', \App\Models\Torrent::getFieldsForList(true)); + $rows = $torrentQuery->selectRaw("$fieldsStr, categories.mode as search_box_id") + ->forPage($page + 1, $torrentsperpage) + ->orderBy("$tableTorrent.$column", $ascdesc) + ->get() + ->toArray(); + print($pagertop); + torrenttable(json_decode(json_encode($rows), true)); + print($pagerbottom); +} else { + stdmsg($lang_torrents['std_search_results_for'] . $search . "\"",$lang_torrents['std_try_again']); +} +print("
    "); +stdfoot(); + + + diff --git a/public/torrents.php b/public/torrents.php index 4ab1e8b7..491fe460 100644 --- a/public/torrents.php +++ b/public/torrents.php @@ -913,11 +913,11 @@ if ($count) list($pagertop, $pagerbottom, $limit, $offset, $size, $page) = pager($torrentsperpage, $count, "?" . $addparam); $fieldsStr = implode(', ', \App\Models\Torrent::getFieldsForList(true)); - if ($allsec == 1 || $enablespecial != 'yes') { - $query = "SELECT $fieldsStr FROM torrents ".($search_area == 3 || $column == "owner" ? "LEFT JOIN users ON torrents.owner = users.id " : "")." $tagFilter $where $orderby $limit"; - } else { - $query = "SELECT $fieldsStr FROM torrents ".($search_area == 3 || $column == "owner" ? "LEFT JOIN users ON torrents.owner = users.id " : "")." LEFT JOIN categories ON torrents.category=categories.id $tagFilter $where $orderby $limit"; - } +// if ($allsec == 1 || $enablespecial != 'yes') { +// $query = "SELECT $fieldsStr FROM torrents ".($search_area == 3 || $column == "owner" ? "LEFT JOIN users ON torrents.owner = users.id " : "")." $tagFilter $where $orderby $limit"; +// } else { + $query = "SELECT $fieldsStr, categories.mode as search_box_id FROM torrents ".($search_area == 3 || $column == "owner" ? "LEFT JOIN users ON torrents.owner = users.id " : "")." LEFT JOIN categories ON torrents.category=categories.id $tagFilter $where $orderby $limit"; +// } do_log("[TORRENT_LIST_SQL] $query", 'debug'); if (!$elasticsearchEnabled) { $res = sql_query($query); diff --git a/resources/lang/en/claim.php b/resources/lang/en/claim.php index a0f3d0e9..b2caf10b 100644 --- a/resources/lang/en/claim.php +++ b/resources/lang/en/claim.php @@ -31,4 +31,7 @@ return [ 'remove_claim_confirm' => 'Confirm to give up the claim?', 'already_claimed' => 'Claimed', 'not_claim_yet' => 'Unclaimed', + 'fields' => [ + 'torrent_id' => 'Torrent ID', + ], ]; diff --git a/resources/lang/en/search.php b/resources/lang/en/search.php new file mode 100644 index 00000000..7eb78151 --- /dev/null +++ b/resources/lang/en/search.php @@ -0,0 +1,13 @@ + 'Global Search', + 'search_keyword' => 'Keyword', + 'search_area' => 'Range', + 'search_area_options' => [ + '0' => 'Title', + '1' => 'Description', + '3' => 'Uploader', + '4' => 'IMDB URL' + ], +]; diff --git a/resources/lang/en/searchbox.php b/resources/lang/en/searchbox.php index 0fb6d6eb..c4396836 100644 --- a/resources/lang/en/searchbox.php +++ b/resources/lang/en/searchbox.php @@ -14,7 +14,7 @@ return [ \App\Models\SearchBox::EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST => 'Display seed box icon on torrent list', ], 'sections' => [ - 'browse' => 'Torrents section', - 'special' => 'Special section', + 'browse' => 'Torrents', + 'special' => 'Special', ], ]; diff --git a/resources/lang/zh_CN/claim.php b/resources/lang/zh_CN/claim.php index 1f510b5a..075539a7 100644 --- a/resources/lang/zh_CN/claim.php +++ b/resources/lang/zh_CN/claim.php @@ -31,4 +31,8 @@ return [ 'remove_claim_confirm' => '确认要放弃认领?', 'already_claimed' => '已认领', 'not_claim_yet' => '未认领', + + 'fields' => [ + 'torrent_id' => '种子 ID', + ], ]; diff --git a/resources/lang/zh_CN/search.php b/resources/lang/zh_CN/search.php new file mode 100644 index 00000000..edac195d --- /dev/null +++ b/resources/lang/zh_CN/search.php @@ -0,0 +1,13 @@ + '全站搜索', + 'search_keyword' => '关键字', + 'search_area' => '范围', + 'search_area_options' => [ + '0' => '标题', + '1' => '简介', + '3' => '发布者', + '4' => 'IMDB链接' + ], +]; diff --git a/resources/lang/zh_TW/claim.php b/resources/lang/zh_TW/claim.php index 473e4650..9fe68ede 100644 --- a/resources/lang/zh_TW/claim.php +++ b/resources/lang/zh_TW/claim.php @@ -30,4 +30,7 @@ return [ 'remove_claim_confirm' => '確認要放棄認領?', 'already_claimed' => '已認領', 'not_claim_yet' => '未認領', + 'fields' => [ + 'torrent_id' => '種子 ID', + ], ]; diff --git a/resources/lang/zh_TW/search.php b/resources/lang/zh_TW/search.php new file mode 100644 index 00000000..0862f011 --- /dev/null +++ b/resources/lang/zh_TW/search.php @@ -0,0 +1,13 @@ + '全站搜索', + 'search_keyword' => '關鍵字', + 'search_area' => '範圍', + 'search_area_options' => [ + '0' => '標題', + '1' => '簡介', + '3' => '發布者', + '4' => 'IMDB鏈接' + ], +]; From 12302a9056e237a28c21971001a03f65dbab6acb Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 22 Oct 2022 21:19:41 +0800 Subject: [PATCH 50/59] change entrance space --- include/functions.php | 4 ++-- lang/chs/lang_functions.php | 12 ++++++------ lang/en/lang_functions.php | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/functions.php b/include/functions.php index 977ce3d0..4aebc115 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2655,11 +2655,11 @@ else {
    - : + :
    - : + : 'width: 108px'])?>
    diff --git a/lang/chs/lang_functions.php b/lang/chs/lang_functions.php index e5faaa57..b55f6d5e 100644 --- a/lang/chs/lang_functions.php +++ b/lang/chs/lang_functions.php @@ -80,14 +80,14 @@ $lang_functions = array 'text_logout' => "退出", 'text_bonus' => "魔力值 ", 'text_use' => "使用", - 'text_ratio' => "分享率:", - 'text_uploaded' => "上传量:", - 'text_downloaded' => "下载量:", - 'text_active_torrents' => "当前活动:", + 'text_ratio' => "分享率:", + 'text_uploaded' => "上传量:", + 'text_downloaded' => "下载量:", + 'text_active_torrents' => "当前活动:", 'title_torrents_seeding' => "当前做种", 'title_torrents_leeching' => "当前下载", - 'text_connectable' => "可连接:", - 'text_the_time_is_now' => "时间: ", + 'text_connectable' => "可连接:", + 'text_the_time_is_now' => "时间:", 'text_message_new' => " 新", 'title_sentbox' => "发件箱", 'title_inbox' => "收件箱", diff --git a/lang/en/lang_functions.php b/lang/en/lang_functions.php index 229d4047..9e55c8ac 100644 --- a/lang/en/lang_functions.php +++ b/lang/en/lang_functions.php @@ -42,7 +42,7 @@ $lang_functions = array 'std_by' => 'By', 'row_security_image' => "Security Image:", 'row_security_code' => "Security Code:", - 'text_slots' => "Slots: ", + 'text_slots' => "Slots:", 'text_unlimited' => "Unlimited", 'std_server_load_very_high' => "The server load is very high at the moment. Retrying, please wait...", 'std_too_many_users' => "Too many users. Please press the Refresh button in your browser to retry.", @@ -83,7 +83,7 @@ $lang_functions = array 'text_ratio' => "Ratio:", 'text_uploaded' => "Uploaded:", 'text_downloaded' => "Downloaded:", - 'text_active_torrents' => "Active: ", + 'text_active_torrents' => "Active:", 'title_torrents_seeding' => "Torrents Seeding", 'title_torrents_leeching' => "Torrents Leeching", 'text_connectable' => "Connectable: ", From 15dc2af40623b9d0e4481415f10aa7982f05fb8a Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 22 Oct 2022 22:23:54 +0800 Subject: [PATCH 51/59] adjust --- include/functions.php | 6 ++---- lang/en/lang_functions.php | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/functions.php b/include/functions.php index 4aebc115..a2903fe3 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2655,12 +2655,10 @@ else {
    - : - +
    - : - 'width: 108px'])?> + 'width: 88px'])?>
    diff --git a/lang/en/lang_functions.php b/lang/en/lang_functions.php index 9e55c8ac..2f8d66ec 100644 --- a/lang/en/lang_functions.php +++ b/lang/en/lang_functions.php @@ -300,7 +300,7 @@ $lang_functions = array 'text_please_download_something_within' => "Please download something within ", 'text_inactive_account_be_deleted' => ". Inactive accounts (with no transfer amount) will be deleted.", 'text_attendance' => '[Attend get bouns]', - 'text_attended' => '[Attend got bouns %u, card: %d]', + 'text_attended' => '[Attend got: %u, card: %d]', 'row_pt_gen_douban_url' => "PT-Gen douban link", 'text_pt_gen_douban_url_note' => "(URL taken from douban. e.g. for movie Transformers the URL is https://movie.douban.com/subject/1794171//)", 'row_pt_gen_imdb_url' => "PT-Gen imdb link", From bd815e10dbe37aed0814b8c5ba1653a3815de6b4 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 22 Oct 2022 22:28:36 +0800 Subject: [PATCH 52/59] gloal search jump _blank or _self --- include/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/functions.php b/include/functions.php index a2903fe3..efaa47ba 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2651,7 +2651,7 @@ else { -
    +
    From 35acf573a387a0fc17d20005c0be11a33b7b13e5 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sat, 22 Oct 2022 23:53:02 +0800 Subject: [PATCH 53/59] fix search page css file --- include/functions.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/functions.php b/include/functions.php index efaa47ba..ebb8c6bf 100644 --- a/include/functions.php +++ b/include/functions.php @@ -2650,6 +2650,7 @@ else { %s]', $CURUSER['id'], (new \App\Repositories\ClaimRepository())->getStats($CURUSER['id']))?> +
    @@ -2665,6 +2666,7 @@ else {
    + whereIn('torrent_id', $torrentIdArr)->get(); $torrentTagResult = $torrentTagCollection->groupBy('torrent_id'); $showCover = false; - $showSeedBoxIcon = get_setting('seed_box.enabled') == 'yes'; + $showSeedBoxIcon = false; if ($searchBoxId) { $searchBoxExtra = get_searchbox_value($searchBoxId, "extra"); if (!empty($searchBoxExtra[\App\Models\SearchBox::EXTRA_DISPLAY_COVER_ON_TORRENT_LIST])) { $showCover = true; } + $showSeedBoxIcon = get_setting('seed_box.enabled') == 'yes'; if (empty($searchBoxExtra[\App\Models\SearchBox::EXTRA_DISPLAY_SEED_BOX_ICON_ON_TORRENT_LIST])) { $showSeedBoxIcon = false; } @@ -5710,6 +5713,7 @@ function list_require_search_box_id() 'userdetails' => [$setting['browsecat'], $setting['specialcat']], 'offers' => [$setting['browsecat'], $setting['specialcat']], 'details' => [$setting['browsecat'], $setting['specialcat']], + 'search' => [$setting['browsecat'], $setting['specialcat']], ]; return $maps[nexus()->getScript()] ?? []; } @@ -5796,7 +5800,7 @@ function get_ip_location_from_geoip($ip): bool|array function msgalert($url, $text, $bgcolor = "red") { print("
    \n"); - print("".$text.""); + print("".$text.""); print("

    "); } From 0486a316fecfaae1d7cacd7da5824cbc1921bd91 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 23 Oct 2022 00:09:24 +0800 Subject: [PATCH 54/59] fix search page pagination --- public/search.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/search.php b/public/search.php index a3f7d7e0..3c6c9b54 100644 --- a/public/search.php +++ b/public/search.php @@ -75,7 +75,7 @@ else $torrentsperpage = 50; // sorting by MarkoStamcar $column = 'id'; $ascdesc = 'desc'; -$addparam = "?search=$search&"; +$addparam = "?search=$search&search_area=$searchArea&"; if (isset($_GET['sort']) && $_GET['sort'] && isset($_GET['type']) && $_GET['type']) { switch($_GET['sort']) { From 8016f2b6decfb33b2418f6abd3a5b4106c117a70 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 23 Oct 2022 18:26:03 +0800 Subject: [PATCH 55/59] physical delete acount write to ban log --- app/Repositories/UserRepository.php | 26 +++++++++++++++++++++----- include/cleanup.php | 21 +++++++++++++-------- include/constants.php | 2 +- resources/lang/en/cleanup.php | 1 + resources/lang/en/user.php | 2 ++ resources/lang/zh_CN/cleanup.php | 1 + resources/lang/zh_CN/user.php | 2 ++ resources/lang/zh_TW/cleanup.php | 1 + resources/lang/zh_TW/user.php | 2 ++ 9 files changed, 44 insertions(+), 14 deletions(-) diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index b2b37efa..f09af9c9 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -162,12 +162,15 @@ class UserRepository extends BaseRepository return User::listClass(); } - public function disableUser(User $operator, $uid, $reason) + public function disableUser(User $operator, $uid, $reason = '') { $targetUser = User::query()->findOrFail($uid, ['id', 'enabled', 'username', 'class']); if ($targetUser->enabled == User::ENABLED_NO) { throw new NexusException('Already disabled !'); } + if (empty($reason)) { + $reason = nexus_trans("user.disable_by_admin"); + } $this->checkPermission($operator, $targetUser); $banLog = [ 'uid' => $uid, @@ -519,9 +522,13 @@ class UserRepository extends BaseRepository return true; } - public function destroy($id) + public function destroy($id, $reasonKey = 'user.destroy_by_admin') { - user_can('user-delete', true); + if (!isRunningInConsole()) { + user_can('user-delete', true); + } + $uidArr = Arr::wrap($id); + $users = User::query()->with('language')->whereIn('id', $uidArr)->get(['id', 'username', 'lang']); $tables = [ 'users' => 'id', 'hit_and_runs' => 'uid', @@ -530,9 +537,18 @@ class UserRepository extends BaseRepository 'exam_progress' => 'uid', ]; foreach ($tables as $table => $key) { - \Nexus\Database\NexusDB::table($table)->where($key, $id)->delete(); + \Nexus\Database\NexusDB::table($table)->whereIn($key, $uidArr)->delete(); } - do_log("[DESTROY_USER]: $id", 'error'); + do_log("[DESTROY_USER]: " . json_encode($uidArr), 'error'); + $userBanLogs = []; + foreach ($users as $user) { + $userBanLogs[] = [ + 'uid' => $user->id, + 'username' => $user->username, + 'reason' => nexus_trans($reasonKey, [], $user->locale) + ]; + } + UserBanLog::query()->insert($userBanLogs); return true; } diff --git a/include/cleanup.php b/include/cleanup.php index 3e301bfa..aa461cdb 100644 --- a/include/cleanup.php +++ b/include/cleanup.php @@ -664,10 +664,14 @@ function docleanup($forceAll = 0, $printProgress = false) { if ($destroyDisabledDays > 0) { $secs = $destroyDisabledDays*24*60*60; $dt = date("Y-m-d H:i:s",(TIMENOW - $secs)); - \App\Models\User::query() + $users = \App\Models\User::query() ->where('enabled', 'no') ->where("last_access","<", $dt) - ->delete(); + ->get(['id']); + if ($users->isNotEmpty()) { + $userRep = new \App\Repositories\UserRepository(); + $userRep->destroy($users->pluck('id')->toArray(), 'cleanup.destroy_disabled_account'); + } } $log = "destroy disabled accounts"; do_log($log); @@ -1037,12 +1041,13 @@ function docleanup($forceAll = 0, $printProgress = false) { } //remove duplicate user ban logs - $log = "clear user ban log duplicate"; - \App\Models\UserBanLog::clearUserBanLogDuplicate(); - do_log($log); - if ($printProgress) { - printProgress($log); - } + //No need to do that, disable + destroy will have two records, sometimes disable will enable again +// $log = "clear user ban log duplicate"; +// \App\Models\UserBanLog::clearUserBanLogDuplicate(); +// do_log($log); +// if ($printProgress) { +// printProgress($log); +// } $log = 'Full cleanup is done'; do_log($log); diff --git a/include/constants.php b/include/constants.php index f92778d0..89e7ebeb 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ 'Disable inactive user accounts, no transfer. Alt: register time.', 'disable_user_not_parked' => 'Disable inactive user accounts, not parked.', 'disable_user_parked' => 'Disable inactive user accounts, parked.', + 'destroy_disabled_account' => 'Timed physical deletion of disabled accounts', ]; diff --git a/resources/lang/en/user.php b/resources/lang/en/user.php index 33e2e17d..8524f42e 100644 --- a/resources/lang/en/user.php +++ b/resources/lang/en/user.php @@ -27,4 +27,6 @@ return [ \App\Models\User::CLASS_STAFF_LEADER => 'Staff Leader', ], 'change_username_lte_min_interval' => 'Last change time: :last_change_time, unmet minimum interval: :interval days', + 'destroy_by_admin' => 'Physical delete by administrator', + 'disable_by_admin' => 'Disable by administrator', ]; diff --git a/resources/lang/zh_CN/cleanup.php b/resources/lang/zh_CN/cleanup.php index 9d8ad4da..e74ced00 100644 --- a/resources/lang/zh_CN/cleanup.php +++ b/resources/lang/zh_CN/cleanup.php @@ -7,4 +7,5 @@ return [ 'disable_user_no_transfer_alt_register_time' => '封禁非活跃的无流量账号,由注册时间时间断定.', 'disable_user_not_parked' => '定时封禁未挂起的非活跃账号.', 'disable_user_parked' => '定时封禁已挂起的非活跃账号.', + 'destroy_disabled_account' => '定时物理删除已封禁账号', ]; diff --git a/resources/lang/zh_CN/user.php b/resources/lang/zh_CN/user.php index 68c51678..ad427709 100644 --- a/resources/lang/zh_CN/user.php +++ b/resources/lang/zh_CN/user.php @@ -27,4 +27,6 @@ return [ \App\Models\User::CLASS_STAFF_LEADER => '主管', ], 'change_username_lte_min_interval' => '上次修改时间::last_change_time,未满足最小间隔::interval 天', + 'destroy_by_admin' => '被管理员物理删除', + 'disable_by_admin' => '被管理員封禁', ]; diff --git a/resources/lang/zh_TW/cleanup.php b/resources/lang/zh_TW/cleanup.php index 76358e15..86de0547 100644 --- a/resources/lang/zh_TW/cleanup.php +++ b/resources/lang/zh_TW/cleanup.php @@ -7,4 +7,5 @@ return [ 'disable_user_no_transfer_alt_register_time' => '封禁非活躍的無流量賬號,由註冊時間時間斷定.', 'disable_user_not_parked' => '定時封禁未掛起的非活躍賬號.', 'disable_user_parked' => '定時封禁已掛起的非活躍賬號.', + 'destroy_disabled_account' => '定時物理刪除已封禁賬號', ]; diff --git a/resources/lang/zh_TW/user.php b/resources/lang/zh_TW/user.php index 9fa65910..9f5c1a80 100644 --- a/resources/lang/zh_TW/user.php +++ b/resources/lang/zh_TW/user.php @@ -27,4 +27,6 @@ return [ \App\Models\User::CLASS_STAFF_LEADER => '主管', ], 'change_username_lte_min_interval' => '上次修改時間::last_change_time,未滿足最小間隔::interval 天', + 'destroy_by_admin' => '被管理員物理刪除', + 'disable_by_admin' => '被管理员封禁', ]; From c98e5153d53a48ff2c9d90b4687a0060aecaef7e Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 23 Oct 2022 18:44:51 +0800 Subject: [PATCH 56/59] improve cleanup --- include/cleanup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cleanup.php b/include/cleanup.php index aa461cdb..c23af043 100644 --- a/include/cleanup.php +++ b/include/cleanup.php @@ -810,7 +810,7 @@ function docleanup($forceAll = 0, $printProgress = false) { } //17.update total seeding and leeching time of users - $res = sql_query("SELECT * FROM users") or sqlerr(__FILE__, __LINE__); + $res = sql_query("SELECT id FROM users where enabled = 'yes' and status = 'confirmed'") or sqlerr(__FILE__, __LINE__); while($arr = mysql_fetch_assoc($res)) { //die("s" . $arr['id']); From 71bd2ad3f7fe93b0efdfd163dfee22006be9df82 Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 23 Oct 2022 19:42:08 +0800 Subject: [PATCH 57/59] add clear shout box --- lang/chs/lang_index.php | 2 ++ lang/cht/lang_index.php | 2 ++ lang/en/lang_index.php | 2 ++ public/ajax.php | 8 ++++++++ public/index.php | 27 +++++++++++++++++++++++++-- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lang/chs/lang_index.php b/lang/chs/lang_index.php index c0ce3bd3..f1109feb 100644 --- a/lang/chs/lang_index.php +++ b/lang/chs/lang_index.php @@ -105,6 +105,8 @@ $lang_index = array 'top_uploader_toggle_time_range_tab' => '点击切换时间范围', 'top_uploader_toggle_time_range_recently' => '最近 30 天', 'top_uploader_toggle_time_range_all' => '全部时间', + 'clear_shout_box' => '清空群聊区', + 'sure_to_clear_shout_box' => '确定要清空群聊区吗?', ); diff --git a/lang/cht/lang_index.php b/lang/cht/lang_index.php index 593a43ba..2d80f9f1 100644 --- a/lang/cht/lang_index.php +++ b/lang/cht/lang_index.php @@ -104,6 +104,8 @@ $lang_index = array 'top_uploader_toggle_time_range_tab' => '點擊切換時間範圍', 'top_uploader_toggle_time_range_recently' => '最近 30 天', 'top_uploader_toggle_time_range_all' => '全部時間', + 'clear_shout_box' => '清空群聊區', + 'sure_to_clear_shout_box' => '確定要清空群聊區嗎?', ); ?> diff --git a/lang/en/lang_index.php b/lang/en/lang_index.php index 93a190db..d4dede07 100644 --- a/lang/en/lang_index.php +++ b/lang/en/lang_index.php @@ -104,6 +104,8 @@ $lang_index = array 'top_uploader_toggle_time_range_tab' => 'Click to toggle the time range', 'top_uploader_toggle_time_range_recently' => 'Last 30 days', 'top_uploader_toggle_time_range_all' => 'All time', + 'clear_shout_box' => 'Clear shout box', + 'sure_to_clear_shout_box' => 'Are you sure you want to clear the shout box?', ); ?> diff --git a/public/ajax.php b/public/ajax.php index 97115177..8fe245a5 100644 --- a/public/ajax.php +++ b/public/ajax.php @@ -123,3 +123,11 @@ function consumeBenefit($params) $rep = new \App\Repositories\UserRepository(); return $rep->consumeBenefit($CURUSER['id'], $params); } + +function clearShoutBox($params) +{ + global $CURUSER; + user_can('sbmanage', true); + \Nexus\Database\NexusDB::table('shoutbox')->delete(); + return true; +} diff --git a/public/index.php b/public/index.php index 46130b2f..5f1626d6 100644 --- a/public/index.php +++ b/public/index.php @@ -137,10 +137,33 @@ if ($showfunbox_main == "yes" && (!isset($CURUSER) || $CURUSER['showfb'] == "yes // ------------- start: shoutbox ------------------// if ($showshoutbox_main == "yes") { ?> -

    -

    +

    + - + + ['.$lang_index['clear_shout_box'].']'; + $clearShoutBoxJs = << +

    \n"); - print("

    \n"); + print("

    \n"); print("
    \n"); print('
    '); print(" "); From d9e5cbdcbc28f3b3bd6acbe66fae1c074e97aadd Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Sun, 23 Oct 2022 20:35:42 +0800 Subject: [PATCH 58/59] fix: disable invite system error msg duplicate head --- include/functions.php | 8 ++++---- public/invite.php | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/functions.php b/include/functions.php index ebb8c6bf..2fc510ec 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1664,13 +1664,13 @@ function registration_check($type = "invitesystem", $maxuserscheck = true, $ipch global $invitesystem, $registration, $maxusers, $SITENAME, $maxip; if ($type == "invitesystem") { if ($invitesystem == "no") { - stderr($lang_functions['std_oops'], $lang_functions['std_invite_system_disabled'], 0); + stderr($lang_functions['std_oops'], $lang_functions['std_invite_system_disabled'], 0, false); } } if ($type == "normal") { if ($registration == "no") { - stderr($lang_functions['std_sorry'], $lang_functions['std_open_registration_disabled'], 0); + stderr($lang_functions['std_sorry'], $lang_functions['std_open_registration_disabled'], 0, false); } } @@ -1678,14 +1678,14 @@ function registration_check($type = "invitesystem", $maxuserscheck = true, $ipch $res = sql_query("SELECT COUNT(*) FROM users") or sqlerr(__FILE__, __LINE__); $arr = mysql_fetch_row($res); if ($arr[0] >= $maxusers) - stderr($lang_functions['std_sorry'], $lang_functions['std_account_limit_reached'], 0); + stderr($lang_functions['std_sorry'], $lang_functions['std_account_limit_reached'], 0, false); } if ($ipcheck) { $ip = getip () ; $a = (@mysql_fetch_row(@sql_query("select count(*) from users where ip='" . mysql_real_escape_string($ip) . "'"))) or sqlerr(__FILE__, __LINE__); if ($a[0] > $maxip) - stderr($lang_functions['std_sorry'], $lang_functions['std_the_ip']."" . htmlspecialchars($ip) ."". $lang_functions['std_used_many_times'],false); + stderr($lang_functions['std_sorry'], $lang_functions['std_the_ip']."" . htmlspecialchars($ip) ."". $lang_functions['std_used_many_times'],false, false); } return true; } diff --git a/public/invite.php b/public/invite.php index 0fd81274..11f92378 100644 --- a/public/invite.php +++ b/public/invite.php @@ -10,12 +10,12 @@ $menuSelected = $_REQUEST['menu'] ?? 'invitee'; $pageSize = 50; function inviteMenu ($selected = "invitee") { - global $lang_invite, $id, $CURUSER; + global $lang_invite, $id, $CURUSER, $invitesystem; begin_main_frame("", false, "100%"); print ("
    "); } end_main_frame(); From b738fca498ba754f304f721f71e3b7a60be468bf Mon Sep 17 00:00:00 2001 From: xiaomlove Date: Mon, 24 Oct 2022 22:37:37 +0800 Subject: [PATCH 59/59] improve hit and run disable user + signup link --- app/Repositories/HitAndRunRepository.php | 55 +++++++++++++----------- include/constants.php | 2 +- lang/chs/lang_invite.php | 3 +- lang/cht/lang_invite.php | 2 + lang/en/lang_invite.php | 2 + public/invite.php | 9 +++- 6 files changed, 45 insertions(+), 28 deletions(-) diff --git a/app/Repositories/HitAndRunRepository.php b/app/Repositories/HitAndRunRepository.php index f976598e..bcb6cac5 100644 --- a/app/Repositories/HitAndRunRepository.php +++ b/app/Repositories/HitAndRunRepository.php @@ -98,6 +98,7 @@ class HitAndRunRepository extends BaseRepository $setting['diff_in_section'] = $diffInSection; $setting['search_box_id'] = $browseMode; $this->doCronjobUpdateStatus($setting, $uid, $torrentId, $ignoreTime); + $this->checkAndDisableUser($setting); $specialMode = Setting::get('main.specialcat'); if ($diffInSection && $browseMode != $specialMode) { @@ -105,6 +106,7 @@ class HitAndRunRepository extends BaseRepository $setting['diff_in_section'] = $diffInSection; $setting['search_box_id'] = $specialMode; $this->doCronjobUpdateStatus($setting, $uid, $torrentId, $ignoreTime); + $this->checkAndDisableUser($setting); } } @@ -333,37 +335,43 @@ class HitAndRunRepository extends BaseRepository ]; Message::query()->insert($message); - if (!$disableUser) { - do_log("[DO_NOT_DISABLE_USER], return"); - return true; - } - if ($hitAndRun->user->enabled == 'no') { - do_log("[USER_ALREADY_DISABLED], return"); - return true; - } - //disable user - /** @var User $user */ - $user = $hitAndRun->user; - $countsQuery = $user->hitAndRuns()->where('status', HitAndRun::STATUS_UNREACHED); + return true; + } + + private function checkAndDisableUser(array $setting): void + { + $disableCounts = HitAndRun::getConfig('ban_user_when_counts_reach', $setting['search_box_id']); + $query = HitAndRun::query() + ->selectRaw("count(*) as counts, uid") + ->where('status', HitAndRun::STATUS_UNREACHED) + ->groupBy('uid') + ->having("counts", '>=', $disableCounts) + ; if ($setting['diff_in_section']) { - $countsQuery->whereHas('torrent.basic_category', function (Builder $query) use ($setting) { + $query->whereHas('torrent.basic_category', function (Builder $query) use ($setting) { return $query->where('mode', $setting['search_box_id']); }); } - $counts = $countsQuery->count(); - $disableCounts = HitAndRun::getConfig('ban_user_when_counts_reach', $setting['search_box_id']); - do_log("user: {$user->id}, H&R counts: $counts, disableCounts: $disableCounts", 'notice'); - if ($counts >= $disableCounts) { - do_log("[DISABLE_USER_DUE_TO_H&R_UNREACHED]", 'notice'); - $comment = nexus_trans('hr.unreached_disable_comment', [], $user->locale); - $user->updateWithModComment(['enabled' => User::ENABLED_NO], $comment); + $result = $query->get(); + if ($result->isEmpty()) { + do_log("No user to disable"); + return; + } + $users = User::query() + ->with('language') + ->where('enabled', User::ENABLED_YES) + ->find($result->pluck('id')->toArray(), ['id', 'username', 'lang']); + foreach ($users as $user) { + $locale = $user->locale; + $comment = nexus_trans('hr.unreached_disable_comment', [], $locale); + $user->updateWithModComment(['enabled' => User::ENABLED_NO], sprintf('%s - %s', date('Y-m-d'), $comment)); $message = [ - 'receiver' => $hitAndRun->uid, + 'receiver' => $user->id, 'added' => Carbon::now()->toDateTimeString(), 'subject' => $comment, 'msg' => nexus_trans('hr.unreached_disable_message_content', [ 'ban_user_when_counts_reach' => Setting::get('hr.ban_user_when_counts_reach'), - ], $hitAndRun->user->locale), + ], $locale), ]; Message::query()->insert($message); $userBanLog = [ @@ -372,9 +380,8 @@ class HitAndRunRepository extends BaseRepository 'reason' => $comment ]; UserBanLog::query()->insert($userBanLog); + do_log("Disable user: " . nexus_json_encode($userBanLog)); } - - return true; } public function getStatusStats($uid, $formatted = true) diff --git a/include/constants.php b/include/constants.php index 89e7ebeb..a8d55c01 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ "只有", 'std_or_above_can_invite' => "及以上的用户才能发送邀请。", 'text_email_restriction_note' => "你只能发送邀请给以下邮箱:", - 'harem_addition' => '后宫加成', + 'signup_link_help' => '右键复制', + 'signup_link' => '注册链接', ); ?> diff --git a/lang/cht/lang_invite.php b/lang/cht/lang_invite.php index 27840ebc..bfe290c5 100644 --- a/lang/cht/lang_invite.php +++ b/lang/cht/lang_invite.php @@ -49,6 +49,8 @@ $lang_invite = array 'std_or_above_can_invite' => "及以上的用戶才能發送邀請。", 'text_email_restriction_note' => "你只能發送邀請給以下郵箱:", 'harem_addition' => '後宮加成', + 'signup_link_help' => '右鍵復製', + 'signup_link' => '註冊鏈接', ); ?> diff --git a/lang/en/lang_invite.php b/lang/en/lang_invite.php index 55710fa1..4185e322 100644 --- a/lang/en/lang_invite.php +++ b/lang/en/lang_invite.php @@ -52,6 +52,8 @@ Best Regards, 'std_or_above_can_invite' => " or above can send invitation.", 'text_email_restriction_note' => "You could only send invitation to email from those domains: ", 'harem_addition' => 'Harem addition', + 'signup_link_help' => 'Right click to copy', + 'signup_link' => 'Signup link', ); ?> diff --git a/public/invite.php b/public/invite.php index 11f92378..01efb9bd 100644 --- a/public/invite.php +++ b/public/invite.php @@ -166,12 +166,17 @@ if ($type == 'new'){ for ($i = 0; $i < $num1; ++$i) { $arr1 = mysql_fetch_assoc($rer); + $isHashValid = $arr1['valid'] == \App\Models\Invite::VALID_YES; + $registerLink = ''; + if ($isHashValid) { + $registerLink = sprintf(' [%s]', $arr1['hash'], $lang_invite['signup_link_help'], $lang_invite['signup_link']); + } $tr = ""; $tr .= "{$arr1['invitee']}"; - $tr .= "{$arr1['hash']}"; + $tr .= sprintf('%s%s', $arr1['hash'], $registerLink); $tr .= "{$arr1['time_invited']}"; $tr .= "".\App\Models\Invite::$validInfo[$arr1['valid']]['text'].""; - if ($arr1['valid'] == \App\Models\Invite::VALID_NO) { + if (!$isHashValid) { $tr .= "".$arr1['invitee_register_username'].""; } else { $tr .= "";