diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php
index 63fce469..4d1b14bf 100644
--- a/app/Http/Resources/UserResource.php
+++ b/app/Http/Resources/UserResource.php
@@ -42,11 +42,16 @@ class UserResource extends JsonResource
'bonus_human' => number_format($this->seedbonus, 1),
'seed_points' => floatval($this->seed_points),
'seed_points_human' => number_format($this->seed_points, 1),
+ 'seed_points_per_hour' => floatval($this->seed_points_per_hour),
+ 'seed_points_per_hour_human' => number_format($this->seed_points_per_hour, 1),
+ 'seed_bonus_per_hour' => floatval($this->seed_bonus_per_hour),
+ 'seed_bonus_per_hour_human' => number_format($this->seed_bonus_per_hour, 1),
'seedtime' => $this->seedtime,
'seedtime_text' => mkprettytime($this->seedtime),
'leechtime' => $this->leechtime,
'leechtime_text' => mkprettytime($this->leechtime),
'share_ratio' => get_ratio($this->id),
+ 'seeding_leeching_data' => $this->whenHas('seeding_leeching_data'),
'inviter' => new UserResource($this->whenLoaded('inviter')),
'valid_medals' => MedalResource::collection($this->whenLoaded('valid_medals')),
];
diff --git a/app/Jobs/CalculateUserSeedBonus.php b/app/Jobs/CalculateUserSeedBonus.php
index afdf998b..69ba369f 100644
--- a/app/Jobs/CalculateUserSeedBonus.php
+++ b/app/Jobs/CalculateUserSeedBonus.php
@@ -96,7 +96,7 @@ class CalculateUserSeedBonus implements ShouldQueue
$logFile = getLogFile("seed-bonus-points");
do_log("$logPrefix, [GET_UID_REAL], count: " . count($results) . ", logFile: $logFile");
$fd = fopen($logFile, 'a');
- $seedPointsUpdates = $seedPointsPerHourUpdates = $seedBonusUpdates = [];
+ $seedPointsUpdates = $seedPointsPerHourUpdates = $seedBonusPerHourUpdates = $seedBonusUpdates = [];
$seedingTorrentCountUpdates = $seedingTorrentSizeUpdates = [];
$logStr = "";
$bonusLogInsert = [];
@@ -159,6 +159,7 @@ class CalculateUserSeedBonus implements ShouldQueue
// NexusDB::statement($sql);
$seedPointsUpdates[] = sprintf("when %d then ifnull(seed_points, 0) + %f", $uid, $seed_points);
$seedPointsPerHourUpdates[] = sprintf("when %d then %f", $uid, $seedBonusResult['seed_points']);
+ $seedBonusPerHourUpdates[] = sprintf("when %d then %f", $uid, $seedBonusResult['seed_bonus']);
$seedingTorrentCountUpdates[] = sprintf("when %d then %f", $uid, $seedBonusResult['torrent_peer_count']);
$seedingTorrentSizeUpdates[] = sprintf("when %d then %f", $uid, $seedBonusResult['size']);
$seedBonusUpdates[] = sprintf("when %d then seedbonus + %f", $uid, $all_bonus);
@@ -177,8 +178,8 @@ class CalculateUserSeedBonus implements ShouldQueue
}
$nowStr = now()->toDateTimeString();
$sql = sprintf(
- "update users set seed_points = case id %s end, seed_points_per_hour = case id %s end, seedbonus = case id %s end, seeding_torrent_count = case id %s end, seeding_torrent_size = case id %s end, seed_points_updated_at = '%s' where id in (%s)",
- implode(" ", $seedPointsUpdates), implode(" ", $seedPointsPerHourUpdates), implode(" ", $seedBonusUpdates), implode(" ", $seedingTorrentCountUpdates), implode(" ", $seedingTorrentSizeUpdates), $nowStr, $idStr
+ "update users set seed_points = case id %s end, seed_points_per_hour = case id %s end, seed_bonus_per_hour = case id %s end, seedbonus = case id %s end, seeding_torrent_count = case id %s end, seeding_torrent_size = case id %s end, seed_points_updated_at = '%s' where id in (%s)",
+ implode(" ", $seedPointsUpdates), implode(" ", $seedPointsPerHourUpdates), implode(" ", $seedBonusPerHourUpdates), implode(" ", $seedBonusUpdates), implode(" ", $seedingTorrentCountUpdates), implode(" ", $seedingTorrentSizeUpdates), $nowStr, $idStr
);
$result = NexusDB::statement($sql);
if ($delIdRedisKey) {
diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php
index 9e320c15..a3b2dfb4 100644
--- a/app/Repositories/UserRepository.php
+++ b/app/Repositories/UserRepository.php
@@ -36,6 +36,9 @@ use Nexus\Database\NexusDB;
class UserRepository extends BaseRepository
{
+ private static array $allowIncludes = ['inviter', 'valid_medals'];
+ private static array $allowIncludeFields = ['seeding_leeching_data'];
+ private static array $allowIncludeCounts = [];
public function getList(array $params)
{
$query = User::query();
@@ -66,28 +69,34 @@ class UserRepository extends BaseRepository
{
//query this info default
$query = User::query()->with([]);
- $allowIncludes = ['inviter', 'valid_medals'];
- $allowIncludeCounts = [];
- $allowIncludeFields = [];
$apiQueryBuilder = ApiQueryBuilder::for(UserResource::NAME, $query)
- ->allowIncludes($allowIncludes)
- ->allowIncludeCounts($allowIncludeCounts)
- ->allowIncludeFields($allowIncludeFields)
+ ->allowIncludes(self::$allowIncludes)
+ ->allowIncludeCounts(self::$allowIncludeCounts)
+ ->allowIncludeFields(self::$allowIncludeFields)
;
$query = $apiQueryBuilder->build();
$user = $query->findOrFail($id);
Gate::authorize('view', $user);
- return $this->appendIncludeFields($apiQueryBuilder, $currentUser, $user);
+ $userList = $this->appendIncludeFields($apiQueryBuilder, $currentUser, [$user]);
+ return $userList[0];
}
- private function appendIncludeFields(ApiQueryBuilder $apiQueryBuilder, Authenticatable $currentUser, User $user): User
+ private function appendIncludeFields(ApiQueryBuilder $apiQueryBuilder, Authenticatable $currentUser, $userList)
{
-// $id = $torrent->id;
-// if ($apiQueryBuilder->hasIncludeField('has_bookmarked')) {
-// $torrent->has_bookmarked = (int)$user->bookmarks()->where('torrentid', $id)->exists();;
-// }
-
- return $user;
+ $idArr = [];
+ foreach ($userList as $user) {
+ $idArr[] = $user->id;
+ }
+ if ($hasFieldSeedingData = $apiQueryBuilder->hasIncludeField('seeding_leeching_data')) {
+ $seedingData = $this->listUserSeedingLeechingData($idArr);
+ }
+ foreach ($userList as $user) {
+ $id = $user->id;
+ if ($hasFieldSeedingData && isset($seedingData[$id])) {
+ $user->seeding_leeching_data = $seedingData[$id];
+ }
+ }
+ return $userList;
}
/**
@@ -259,7 +268,7 @@ class UserRepository extends BaseRepository
private function setEnableLatelyCache(int $userId): void
{
- NexusDB::cache_put(User::getUserEnableLatelyCacheKey($userId), now()->toDateTimeString());
+ NexusDB::cache_put(User::getUserEnableLatelyCacheKey($userId), now()->toDateTimeString(), 86400);
}
public function getInviteInfo($id)
@@ -814,4 +823,38 @@ class UserRepository extends BaseRepository
return $loginLog;
}
+ /**
+ * get user seeding/leeching count and size
+ *
+ * @see calculate_seed_bonus()
+ * @param array $userIdArr
+ * @return array
+ */
+ private function listUserSeedingLeechingData(array $userIdArr)
+ {
+ $minSize = get_setting('bonus.min_size', 0);
+ $idStr = implode(",", $userIdArr);
+ $sql = "select peers.userid, peers.seeder, torrents.size from torrents LEFT JOIN peers ON peers.torrent = torrents.id WHERE peers.userid in ($idStr) and torrents.size > $minSize group by peers.torrent, peers.peer_id, peers.userid, peers.seeder";
+ $data = NexusDB::select($sql);
+ $result = [];
+ foreach ($data as $row) {
+ if (!isset($result[$row['userid']])) {
+ $result[$row['userid']] = [
+ 'seeding_count' => 0,
+ 'seeding_size' => 0,
+ 'leeching_count' => 0,
+ 'leeching_size' => 0,
+ ];
+ }
+ if ($row['seeder'] == 'yes') {
+ $result[$row['userid']]['seeding_count'] += 1;
+ $result[$row['userid']]['seeding_size'] += $row['size'];
+ } else {
+ $result[$row['userid']]['leeching_count'] += 1;
+ $result[$row['userid']]['leeching_size'] += $row['size'];
+ }
+ }
+ return $result;
+ }
+
}
diff --git a/database/migrations/2025_11_19_033120_add_seeding_bonus_per_hour_to_users_table.php b/database/migrations/2025_11_19_033120_add_seeding_bonus_per_hour_to_users_table.php
new file mode 100644
index 00000000..f5850946
--- /dev/null
+++ b/database/migrations/2025_11_19_033120_add_seeding_bonus_per_hour_to_users_table.php
@@ -0,0 +1,28 @@
+decimal('seed_bonus_per_hour', 20, 1)->default(0)->after('seed_points_per_hour');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('users', function (Blueprint $table) {
+ $table->dropColumn('seed_bonus_per_hour');
+ });
+ }
+};
diff --git a/include/cleanup.php b/include/cleanup.php
index 5de5c51c..3a88daf6 100644
--- a/include/cleanup.php
+++ b/include/cleanup.php
@@ -341,7 +341,7 @@ function docleanup($forceAll = 0, $printProgress = false) {
//rest seed_points_per_hour
$seedPointsUpdatedAtMin = $carbonNow->subSeconds(2*intval($autoclean_interval_one))->toDateTimeString();
- sql_query("update users set seed_points_per_hour = 0 where seed_points_updated_at < " . sqlesc($seedPointsUpdatedAtMin));
+ sql_query("update users set seed_points_per_hour = 0, seed_bonus_per_hour = 0, seeding_torrent_count = 0, seeding_torrent_size = 0 where seed_points_updated_at < " . sqlesc($seedPointsUpdatedAtMin));
\App\Repositories\CleanupRepository::runBatchJobCalculateUserSeedBonus($requestId);
diff --git a/include/constants.php b/include/constants.php
index b8122a79..9649eb04 100644
--- a/include/constants.php
+++ b/include/constants.php
@@ -1,6 +1,6 @@
");
+ $actions[] = "
";
}
- print("
\n");
+ $actions[] = "
";
+ echo sprintf("