Merge branch 'php8' into section

This commit is contained in:
xiaomlove
2022-10-25 19:16:56 +08:00
168 changed files with 3072 additions and 621 deletions
+2
View File
@@ -25,6 +25,7 @@ class BonusLogs extends NexusModel
const BUSINESS_TYPE_NO_AD = 11;
const BUSINESS_TYPE_GIFT_TO_LOW_SHARE_RATIO = 12;
const BUSINESS_TYPE_LUCKY_DRAW = 13;
const BUSINESS_TYPE_EXCHANGE_DOWNLOAD = 14;
public static array $businessTypes = [
self::BUSINESS_TYPE_CANCEL_HIT_AND_RUN => ['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()
+59 -5
View File
@@ -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,13 +19,18 @@ 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'],
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';
@@ -39,17 +46,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 +114,35 @@ 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 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
+15
View File
@@ -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;
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
class Plugin extends NexusModel
{
protected $fillable = ['display_name', 'package_name', 'remote_url', 'installed_version', 'status', 'description', 'status_result'];
const STATUS_NOT_INSTALLED = -1;
const STATUS_NORMAL = 0;
const STATUS_PRE_INSTALL = 1;
const STATUS_INSTALLING = 2;
const STATUS_INSTALL_FAILED = 3;
const STATUS_PRE_UPDATE = 11;
const STATUS_UPDATING = 12;
const STATUS_UPDATE_FAILED = 13;
const STATUS_PRE_DELETE = 101;
const STATUS_DELETING = 102;
const STATUS_DELETE_FAILED = 103;
public function statusText(): Attribute
{
return new Attribute(
get: fn($value, $attributes) => __('plugin.status.' . $attributes['status'])
);
}
}
+37
View File
@@ -24,6 +24,13 @@ class SearchBox extends NexusModel
];
const EXTRA_TAXONOMY_LABELS = 'taxonomy_labels';
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';
@@ -89,6 +96,36 @@ class SearchBox extends NexusModel
return array_combine(array_keys(self::$taxonomies), array_keys(self::$taxonomies));
}
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)) {
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');
+8
View File
@@ -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');
+56 -11
View File
@@ -3,9 +3,8 @@
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
{
@@ -15,11 +14,9 @@ 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;
const VISIBLE_YES = 'yes';
const VISIBLE_NO = 'no';
@@ -30,11 +27,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', 'category'
];
public static $basicRelations = [
@@ -129,6 +128,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;
@@ -153,6 +162,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;
@@ -193,11 +210,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
@@ -256,9 +280,30 @@ 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;
$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');
// $hrMode = Setting::get('hr.mode');
$hrMode = HitAndRun::getConfig('mode', $this->basic_category->mode);
if ($hrMode == HitAndRun::MODE_GLOBAL) {
return self::HR_YES;
}
+5 -1
View File
@@ -2,13 +2,14 @@
namespace App\Models;
use Nexus\Database\NexusDB;
class TorrentCustomField extends NexusModel
{
protected $table = 'torrents_custom_fields';
protected $fillable = [
'name', 'label', 'type', 'required', 'is_single_row', 'options', 'help'
'name', 'label', 'type', 'required', 'is_single_row', 'options', 'help', 'display', 'priority'
];
public static function getCheckboxOptions(): array
@@ -20,4 +21,7 @@ class TorrentCustomField extends NexusModel
}
return $result;
}
public $timestamps = true;
}
+11
View File
@@ -2,12 +2,23 @@
namespace App\Models;
<<<<<<< HEAD
=======
use Nexus\Database\NexusDB;
>>>>>>> php8
class TorrentCustomFieldValue extends NexusModel
{
protected $table = 'torrents_custom_field_values';
<<<<<<< HEAD
protected $fillable = [
'torrent_id', 'custom_field_id', 'custom_field_value',
];
=======
public $timestamps = true;
protected $fillable = ['torrent_id', 'custom_field_id', 'custom_field_value', ];
>>>>>>> php8
}
+3 -1
View File
@@ -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
}
}
+19
View File
@@ -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");
}
}