Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracker 列表操作能力 #912

Merged
merged 16 commits into from
Jan 15, 2025
Merged

Tracker 列表操作能力 #912

merged 16 commits into from
Jan 15, 2025

Conversation

Ghost-chu
Copy link
Collaborator

@Ghost-chu Ghost-chu commented Jan 15, 2025

为下列下载器添加了 Tracker 列表操作能力:

  • qBittorrent
  • Transmission
  • BiglyBT

并同时添加了工具控制器:

  • replaceTracker(批量替换 PBH 上所有下载器的所有种子的 Tracker 列表,可将指定 A Tracker 批量替换为 B Tracker)

这也为 PTEP 协议做了铺垫:https://github.com/PBH-BTN/PTEP-Spec

Summary by CodeRabbit

版本发布说明

  • 新功能

    • 添加了跨下载器的通用跟踪器管理功能
    • 新增了一个用于替换跟踪器的实用程序 API 端点
    • 支持获取和修改不同下载器中的跟踪器列表
  • 改进

    • 增强了多个下载器(BiglyBT、BitComet、Deluge、qBittorrent、Transmission)的跟踪器处理能力
    • 添加了更详细的错误消息和状态报告
  • 技术更新

    • 引入了新的 Tracker 接口和 TrackerImpl 实现
    • 扩展了下载器接口以支持更多跟踪器相关操作
  • 语言支持

    • 更新了英文、中文简体的错误消息和状态提示

@Ghost-chu Ghost-chu requested a review from a team as a code owner January 15, 2025 18:26
Copy link
Contributor

coderabbitai bot commented Jan 15, 2025

Warning

Rate limit exceeded

@Ghost-chu has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 42 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 69fe559 and 6fef194.

📒 Files selected for processing (6)
  • src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (6 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java (5 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1 hunks)

概述

演练

此次拉取请求引入了一系列增强功能,主要围绕跟踪器(Tracker)管理和下载器(Downloader)接口。新增了一个名为 PBHUtilitiesController 的实用控制器,支持跟踪器替换功能。多个下载器实现(如 BiglyBT、BitComet、Transmission)新增了获取和设置跟踪器的方法,同时引入了 Tracker 接口和 TrackerImpl 实现类,以标准化跟踪器处理。

变更

文件路径 变更摘要
src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java 注册 PBHUtilitiesController 模块
src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java 新增 getAllTorrents()getTrackers()setTrackers() 方法
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java 新增 getAllTorrents()getTrackers()setTrackers() 方法
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java 新增 getAllTorrents()getTrackers()setTrackers() 方法
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java 新增 getAllTorrents()getTrackers()setTrackers() 方法
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java 新增 getAllTorrents()getTrackers()setTrackers() 方法
src/main/java/com/ghostchu/peerbanhelper/torrent/Tracker.java 新增跟踪器接口
src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java 新增跟踪器实现类
src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java 新增跟踪器替换 Web API 端点
src/main/java/com/ghostchu/peerbanhelper/text/Lang.java 新增跟踪器相关的错误消息常量
src/main/resources/lang/en_us/messages.yml 新增跟踪器相关的错误消息
src/main/resources/lang/messages_fallback.yml 新增跟踪器相关的错误消息
src/main/resources/lang/zh_cn/messages.yml 新增跟踪器相关的错误消息
src/main/java/raccoonfink/deluge/DelugeServer.java 移除 updateUI 方法

序列图

sequenceDiagram
    participant Client
    participant PBHUtilitiesController
    participant Downloader
    participant Torrent

    Client->>PBHUtilitiesController: POST /api/utilities/replaceTracker
    PBHUtilitiesController->>Downloader: getAllTorrents()
    Downloader-->>PBHUtilitiesController: 返回所有种子
    loop 遍历种子
        PBHUtilitiesController->>Downloader: getTrackers(torrent)
        Downloader-->>PBHUtilitiesController: 返回跟踪器列表
        PBHUtilitiesController->>PBHUtilitiesController: 替换跟踪器
        PBHUtilitiesController->>Downloader: setTrackers(torrent, newTrackers)
    end
    PBHUtilitiesController-->>Client: 返回替换结果
Loading

可能相关的 PR

建议的审阅者

  • Gaojianli

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

🧹 Nitpick comments (20)
src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java (1)

60-90: 建议改进线程池的使用方式

handleReplaceTracker 方法中,每次遍历一个下载器都会创建一个新的虚拟线程池。建议在循环外创建线程池,以避免频繁创建和销毁线程池带来的性能开销。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (1)

200-229: 避免代码重复,提升代码可读性

getAllTorrents 方法与 getTorrents 方法的大部分代码重复,建议提取公共逻辑,减少代码重复,提升可维护性。

可以提取一个私有方法来获取种子列表,例如:

private List<Torrent> fetchTorrents(String filters) {
    // 公共的获取种子列表的代码
}

然后在 getTorrentsgetAllTorrents 中调用:

@Override
public List<Torrent> getTorrents() {
    return fetchTorrents("?filter=" + BiglyBTDownloadStateConst.ST_DOWNLOADING + "&filter=" + BiglyBTDownloadStateConst.ST_SEEDING + "&filter=" + BiglyBTDownloadStateConst.ST_ERROR);
}

@Override
public List<Torrent> getAllTorrents() {
    return fetchTorrents("");
}
src/main/java/com/ghostchu/peerbanhelper/torrent/Tracker.java (1)

5-10: 建议为接口方法添加文档注释

Tracker 接口中的方法缺少文档注释,建议添加,以提高代码的可读性和可维护性,便于其他开发者理解接口的用途和方法的含义。

例如:

/**
 * 获取此 Tracker 组中的所有 Tracker URL 列表。
 *
 * @return Tracker URL 的列表
 */
List<String> getTrackersInGroup();

/**
 * 获取此 Tracker 组中的主 Tracker。
 *
 * @return 主 Tracker 的 URL
 */
String getLeadingTracker();
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentTorrentTrackers.java (1)

9-26: 建议添加类和字段的文档注释

这个类作为 qBittorrent Tracker 信息的数据传输对象,建议添加以下改进:

  • 为类添加 JavaDoc 注释,说明其用途和与 qBittorrent API 的关系
  • 为每个字段添加注释,解释其含义和可能的取值范围
  • 为 status 字段添加枚举值说明

示例改进:

+/**
+ * 表示 qBittorrent Tracker 的状态信息
+ * 用于与 qBittorrent WebAPI 进行数据交互
+ */
 @NoArgsConstructor
 @Data
 public class QBittorrentTorrentTrackers {
+    /** Tracker 返回的消息 */
     @JsonProperty("msg")
     private String msg;
+    /** 从该 Tracker 完成下载的用户数 */
     @JsonProperty("num_downloaded")
     private Integer numDownloaded;
     // ... 其他字段的文档
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/DownloadRecord.java (1)

33-33: 建议优化 trackers 字段的类型定义和文档

当前的 List<List<String>> 结构虽然能满足需求,但建议做以下改进:

  1. 添加字段说明文档,解释嵌套列表的结构和用途
  2. 考虑使用不可变集合类型以增加类型安全性
+    /**
+     * Tracker 列表的分组信息
+     * 外层 List 表示不同的 Tracker 组
+     * 内层 List 包含每组中的 Tracker URL
+     */
-    private List<List<String>> trackers;
+    private final List<List<String>> trackers = new ArrayList<>();
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/resp/BCTaskTrackersResponse.java (1)

22-41: 建议在 TrackersDTO 中添加字段验证

为确保数据的有效性,建议添加以下验证:

  1. 对数值类型字段添加范围检查
  2. 为必填字段添加非空检查
  3. 规范化 status 和 flag 的可能值

建议添加验证注解:

     @JsonProperty("seeders")
+    @Min(0)
     private Integer seeders;
     
     @JsonProperty("leechers")
+    @Min(0)
     private Integer leechers;
     
     @JsonProperty("name")
+    @NotBlank
     private String name;
src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1)

41-44: 建议优化比较逻辑

当前的比较实现可能存在以下问题:

  1. 未处理 null 参数情况
  2. 字符串比较可能不符合业务需求
  3. 可能产生不一致的比较结果

建议改进比较逻辑:

     @Override
     public int compareTo(@NotNull Tracker o) {
-        return toString().compareTo(o.toString());
+        Objects.requireNonNull(o, "比较对象不能为 null");
+        return getLeadingTracker().compareTo(o.getLeadingTracker());
     }
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java (1)

74-76: 建议添加空值检查

建议在调用 backend.getTrackerList() 时添加空值检查,以防止可能的 NPE。

 public List<Tracker> getTrackers() {
+    List<String> trackerList = backend.getTrackerList();
+    if (trackerList == null) {
+        return List.of();
+    }
-    return TrackerImpl.parseFromTrackerList(backend.getTrackerList());
+    return TrackerImpl.parseFromTrackerList(trackerList);
 }
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/BiglyBTTorrent.java (2)

10-10: 建议使用不可变集合

为了保证线程安全和防止外部修改,建议使用不可变集合类型。

-    private final List<List<String>> trackers;
+    private final ImmutableList<ImmutableList<String>> trackers;

79-81: 建议返回防御性副本

为了防止外部修改内部状态,建议返回集合的防御性副本。

 public List<List<String>> getTrackers() {
-    return trackers;
+    return trackers.stream()
+            .map(ArrayList::new)
+            .collect(Collectors.toList());
 }
src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java (3)

83-88: 建议补充方法返回值的非空说明

建议在方法文档中补充返回值是否可能为 null 的说明。

     /**
      * 获取此下载器的所有 Torrents
      *
      * @return 返回所有的 Torrents
+     * @return 永不为 null,如果没有种子则返回空列表
      */
     List<Torrent> getAllTorrents();

98-104: 建议补充参数验证说明

建议在方法文档中补充参数验证和异常说明。

     /**
      * 获取指定 Torrent 的 Tracker 列表
      * @param torrent Torrent
      * @return Tracker 列表
+     * @throws IllegalArgumentException 如果 torrent 为 null
+     * @return 永不为 null,如果没有 Tracker 则返回空列表
      */
     List<Tracker> getTrackers(Torrent torrent);

105-110: 建议补充参数验证说明

建议在方法文档中补充参数验证和异常说明。

     /**
      * 设置指定 Torrent 的 Tracker 列表
      * @param torrent Torrent
      * @param trackers Tracker 列表
+     * @throws IllegalArgumentException 如果 torrent 或 trackers 为 null
      */
     void setTrackers(Torrent torrent, List<Tracker> trackers);
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (2)

163-167: 建议添加空值检查

为了提高代码的健壮性,建议在类型转换前添加对 torrent 参数的非空检查。

 @Override
 public List<Tracker> getTrackers(Torrent torrent) {
+    if (torrent == null) {
+        throw new IllegalArgumentException("torrent cannot be null");
+    }
     TRTorrent trTorrent = (TRTorrent) torrent;
     return trTorrent.getTrackers();
 }

Line range hint 237-246: 建议统一系统属性命名风格

系统属性的命名应与其他属性保持一致的风格。建议修改如下:

-if (System.getProperty("pbh.transmission.disable-torrent-relaunch") != null) {
+if (System.getProperty("pbh.downloader.transmission.disable-torrent-relaunch") != null) {
src/main/java/com/ghostchu/peerbanhelper/text/Lang.java (1)

499-501: 建议优化枚举常量的排序

新添加的与 Tracker 相关的枚举常量应该按照功能分组放置,建议将它们移动到其他 Tracker 相关常量附近,以提高代码的可维护性。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (1)

372-397: 建议优化魔法数字的使用

代码实现完整,但建议将魔法数字提取为常量以提高可维护性:

+private static final String HTTP_PROTOCOL_PREFIX = "http";
+private static final String UDP_PROTOCOL_PREFIX = "udp";
+private static final String WS_PROTOCOL_PREFIX = "ws";

 @Override
 public List<Tracker> getTrackers(Torrent torrent) {
     // ... 现有代码 ...
     return trackers.getTrackers().stream()
-            .filter(t -> t.getName().startsWith("http") || 
-                        t.getName().startsWith("udp") || 
-                        t.getName().startsWith("ws"))
+            .filter(t -> t.getName().startsWith(HTTP_PROTOCOL_PREFIX) || 
+                        t.getName().startsWith(UDP_PROTOCOL_PREFIX) || 
+                        t.getName().startsWith(WS_PROTOCOL_PREFIX))
             .map(t -> (Tracker) new TrackerImpl(t.getName())).toList();
src/main/resources/lang/zh_cn/messages.yml (1)

566-566: 建议:添加文件末尾的换行符

YAML 文件应该以换行符结尾,这是一个最佳实践。

 UTILITIES_TRACKER_REPLACED: "已成功替换 {} 个种子的 Tracker"
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 566-566: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/messages_fallback.yml (1)

569-569: 建议:添加文件末尾的换行符

YAML 文件应该以换行符结尾,这是一个最佳实践。

 UTILITIES_TRACKER_REPLACED: "已成功替换 {} 个种子的 Tracker"
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/en_us/messages.yml (1)

569-569: 建议:添加文件末尾的换行符

YAML 文件应该以换行符结尾,这是一个最佳实践。

 UTILITIES_TRACKER_REPLACED: "Successfully replaced {} torrent's tracker"
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33d8c6a and ca6c853.

📒 Files selected for processing (21)
  • src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (6 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/BiglyBTTorrent.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/network/wrapper/DownloadRecord.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BCEndpoint.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/resp/BCTaskTrackersResponse.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java (3 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/impl/QBittorrentTorrentTrackers.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/TRTorrent.java (2 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (4 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/text/Lang.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/torrent/Tracker.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1 hunks)
  • src/main/java/raccoonfink/deluge/DelugeServer.java (0 hunks)
  • src/main/resources/lang/en_us/messages.yml (1 hunks)
  • src/main/resources/lang/messages_fallback.yml (1 hunks)
  • src/main/resources/lang/zh_cn/messages.yml (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/raccoonfink/deluge/DelugeServer.java
✅ Files skipped from review due to trivial changes (1)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BCEndpoint.java
🧰 Additional context used
🪛 yamllint (1.35.1)
src/main/resources/lang/en_us/messages.yml

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/messages_fallback.yml

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/zh_cn/messages.yml

[error] 566-566: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: Build_Installers / install4jc
  • GitHub Check: Build_SPK / pkgcreate
  • GitHub Check: Build_PKG / pkg (14.1)
  • GitHub Check: Build_PKG / pkg (13.4)
  • GitHub Check: Build_Docker
🔇 Additional comments (8)
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (1)

217-227: 确保类型兼容性

在创建 BiglyBTTorrent 对象时,直接使用 detail.getTrackers()。需要确保 detail.getTrackers() 返回的类型与 BiglyBTTorrent 构造函数期望的参数类型一致。

请确认 detail.getTrackers() 的返回类型与构造函数匹配,避免类型不匹配引发的运行时异常。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/deluge/Deluge.java (1)

179-182: 建议补充未实现功能的说明

当前方法为空实现,建议添加 TODO 注释说明未实现原因,或添加相应的实现代码。

     @Override
     public void setTrackers(Torrent torrent, List<Tracker> trackers) {
+        // TODO: Deluge 暂不支持设置 Tracker 列表功能
+        throw new UnsupportedOperationException("Deluge 暂不支持设置 Tracker 列表功能");
     }
✅ Verification successful

建议在空方法中明确标识不支持的功能

建议采用以下方式实现:

@Override
public void setTrackers(Torrent torrent, List<Tracker> trackers) {
    throw new UnsupportedOperationException("Deluge 客户端不支持修改 Tracker 列表功能");
}

这样可以:

  • 明确告知用户该功能不受支持
  • 与其他下载器实现(如 BitComet)保持一致的异常处理方式
  • 避免静默失败可能造成的困扰
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find the interface or parent class definition
ast-grep --pattern 'interface $_ { $$$ void setTrackers(Torrent torrent, List<Tracker> trackers); $$$ }'

# Find all implementations of setTrackers
ast-grep --pattern 'void setTrackers(Torrent torrent, List<Tracker> trackers) { $$$ }'

# Search for any documentation about tracker support
rg -i "tracker" "README.md" || true

Length of output: 228


Script:

#!/bin/bash
# Find files related to downloaders
fd -e java -e kt downloader

# Find Tracker-related code
rg -l "Tracker" --type java --type kotlin

# Find interface definitions
rg -l "interface.*Downloader" --type java --type kotlin

# Find any documentation about tracker support in source files
rg -i "tracker.*support" --type java --type kotlin

Length of output: 2560


Script:

#!/bin/bash
# Check the Downloader interface
cat src/main/java/com/ghostchu/peerbanhelper/downloader/Downloader.java

# Check other implementations of setTrackers
rg -A 5 "setTrackers.*\(" src/main/java/com/ghostchu/peerbanhelper/downloader/impl/

# Check for feature flags
cat src/main/java/com/ghostchu/peerbanhelper/downloader/DownloaderFeatureFlag.java

Length of output: 7851

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/transmission/Transmission.java (1)

149-155: 实现正确且完整!

获取所有种子的实现逻辑完整,复用了现有的字段定义,且正确地移除了过滤条件。

src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java (1)

222-247: 实现完整且健壮!

tracker 获取实现考虑周全:

  • 包含了适当的错误处理
  • 正确过滤了无效的 tracker
  • 合理使用了状态码检查
src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java (1)

740-740: 代码变更正确!

registerModules() 方法中添加 PBHUtilitiesController 的注册是合适的,它遵循了现有的模块注册模式。

src/main/resources/lang/zh_cn/messages.yml (1)

563-566: 消息翻译准确!

新增的错误和状态消息翻译准确,符合现有的消息风格。

🧰 Tools
🪛 yamllint (1.35.1)

[error] 566-566: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/messages_fallback.yml (1)

566-569: 备用消息翻译正确!

新增的备用错误和状态消息翻译准确,与中文版本保持一致。

🧰 Tools
🪛 yamllint (1.35.1)

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

src/main/resources/lang/en_us/messages.yml (1)

566-569: 英文消息翻译准确!

新增的英文错误和状态消息翻译准确自然,符合英语表达习惯。

🧰 Tools
🪛 yamllint (1.35.1)

[error] 569-569: no new line character at the end of file

(new-line-at-end-of-file)

Comment on lines +73 to +80
List<Tracker> liveTrackers = downloader.getTrackers(torrent);
List<Tracker> newTrackers = createTrackerListForReplace(dto.from(), dto.to(), liveTrackers);
if (newTrackers != null) {
downloader.setTrackers(torrent, newTrackers);
count.incrementAndGet();
}
} catch (Exception e) {
log.error("Failed to replace tracker for torrent: {}", torrent.getName(), e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

避免潜在的空指针异常

liveTrackersnewTrackers 可能为 null 的情况下,直接使用可能导致空指针异常。建议在使用前进行空值检查。

Comment on lines +249 to +254
@Override
public void setTrackers(Torrent torrent, List<Tracker> trackers) {
List<Tracker> trackerList = getTrackers(torrent);
removeTracker(torrent, trackerList);
addTracker(torrent, trackers);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

建议增加事务处理机制

当前实现在删除和添加 tracker 的过程中可能出现部分失败的情况,建议添加错误回滚机制:

 @Override
 public void setTrackers(Torrent torrent, List<Tracker> trackers) {
+    List<Tracker> originalTrackers = null;
+    try {
+        originalTrackers = getTrackers(torrent);
         removeTracker(torrent, trackerList);
         addTracker(torrent, trackers);
+    } catch (Exception e) {
+        if (originalTrackers != null) {
+            // 发生错误时恢复原始 tracker 列表
+            addTracker(torrent, originalTrackers);
+        }
+        throw new IllegalStateException("Failed to update trackers with rollback: " + e.getMessage(), e);
+    }
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 399 to 402
@Override
public void setTrackers(Torrent torrent, List<Tracker> trackers) {
// Unsupported Operation
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

建议完善未支持操作的异常处理

对于不支持的操作,应抛出适当的异常并提供清晰的错误信息:

 @Override
 public void setTrackers(Torrent torrent, List<Tracker> trackers) {
-    // Unsupported Operation
+    throw new UnsupportedOperationException("BitComet 客户端暂不支持设置 Tracker 操作");
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
public void setTrackers(Torrent torrent, List<Tracker> trackers) {
// Unsupported Operation
}
@Override
public void setTrackers(Torrent torrent, List<Tracker> trackers) {
throw new UnsupportedOperationException("BitComet 客户端暂不支持设置 Tracker 操作");
}

@Ghost-chu Ghost-chu requested a review from paulzzh January 15, 2025 18:30
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (1)
src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java (1)

35-36: 移除未使用的依赖注入

AlertDao 被注入但在整个类中都未被使用,建议移除这个未使用的依赖。

-    @Autowired
-    private AlertDao alertDao;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca6c853 and 5b75964.

📒 Files selected for processing (3)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (6 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java (1 hunks)
  • src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Java CI (push)
src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java

[error] 39-39: Cannot find symbol 'Collections' in class com.ghostchu.peerbanhelper.torrent.TrackerImpl

🔇 Additional comments (6)
src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHUtilitiesController.java (2)

100-120: ⚠️ Potential issue

改进 Tracker URL 替换逻辑

当前使用简单的字符串替换可能导致误替换 URL 中的其他部分。建议使用 URI 解析来确保只替换主机名部分。

     private List<Tracker> createTrackerListForReplace(String from, String to, List<Tracker> trackers) {
         boolean anyModification = false;
         List<Tracker> newTrackers = new ArrayList<>();
         for (Tracker tracker : trackers) {
             List<String> newTrackerGroup = new ArrayList<>();
             for (String trackerUrl : tracker.getTrackersInGroup()) {
-                if (trackerUrl.contains(from)) {
-                    newTrackerGroup.add(trackerUrl.replace(from, to));
-                    anyModification = true;
-                } else {
+                try {
+                    URI uri = new URI(trackerUrl);
+                    if (uri.getHost().equals(from)) {
+                        URI newUri = new URI(
+                            uri.getScheme(),
+                            uri.getUserInfo(),
+                            to,
+                            uri.getPort(),
+                            uri.getPath(),
+                            uri.getQuery(),
+                            uri.getFragment()
+                        );
+                        newTrackerGroup.add(newUri.toString());
+                        anyModification = true;
+                    } else {
+                        newTrackerGroup.add(trackerUrl);
+                    }
+                } catch (URISyntaxException e) {
+                    log.warn("Invalid tracker URL: {}", trackerUrl);
                     newTrackerGroup.add(trackerUrl);
-                }
+                }
             }
             newTrackers.add(new TrackerImpl(newTrackerGroup));
         }

Likely invalid or redundant comment.


73-80: ⚠️ Potential issue

添加空值检查以提高代码健壮性

在访问 liveTrackers 和处理返回值时缺少必要的空值检查。

-                                List<Tracker> liveTrackers = downloader.getTrackers(torrent);
-                                List<Tracker> newTrackers = createTrackerListForReplace(dto.from(), dto.to(), liveTrackers);
-                                if (newTrackers != null) {
+                                List<Tracker> liveTrackers = downloader.getTrackers(torrent);
+                                if (liveTrackers == null || liveTrackers.isEmpty()) {
+                                    log.warn("No trackers found for torrent: {}", torrent.getName());
+                                    return;
+                                }
+                                List<Tracker> newTrackers = createTrackerListForReplace(dto.from(), dto.to(), liveTrackers);
+                                if (newTrackers != null && !newTrackers.isEmpty()) {
                                     downloader.setTrackers(torrent, newTrackers);
                                     count.incrementAndGet();
                                 }

Likely invalid or redundant comment.

src/main/java/com/ghostchu/peerbanhelper/torrent/TrackerImpl.java (1)

14-21: 实现完善,处理得当!

构造函数实现了以下良好实践:

  • 使用 Objects.requireNonNull 进行空值检查
  • 使用 Stream API 优雅地处理字符串
  • 包含了适当的空白处理和排序
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/biglybt/BiglyBT.java (3)

Line range hint 184-194: 实现完善,处理得当!

getTorrents 方法的更改:

  • 正确处理了私有种子的配置选项
  • 适当地包含了 tracker 信息

231-235: 添加类型检查以防止 ClassCastException

当前实现直接将 torrent 强制转换为 BiglyBTTorrent,可能导致类型转换异常。

     @Override
     public List<Tracker> getTrackers(Torrent torrent) {
+        if (!(torrent instanceof BiglyBTTorrent)) {
+            throw new IllegalArgumentException("Torrent must be an instance of BiglyBTTorrent");
+        }
         BiglyBTTorrent biglyBTTorrent = (BiglyBTTorrent) torrent;
         return biglyBTTorrent.getTrackers().stream().map(t -> (Tracker) new TrackerImpl(t)).toList();
     }

237-256: 实现完善,处理得当!

setTrackers 方法实现了:

  • 正确的 tracker 列表格式化
  • 适当的错误处理
  • 正确的 URL 构造

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (3)

Line range hint 281-331: 建议优化:fetchTorrents() 方法的错误处理和并发性能

方法实现基本正确,但有以下几点建议:

  1. 建议将 Semaphore 的许可数设置为可配置项,而不是硬编码为 4
  2. 建议添加超时机制,避免在网络问题时长时间阻塞
  3. 建议对 torrentResponses 使用 ArrayList 的初始容量构造函数,避免动态扩容
-List<BCTaskTorrentResponse> torrentResponses = Collections.synchronizedList(new ArrayList<>(response.getTasks().size()));
+List<BCTaskTorrentResponse> torrentResponses = Collections.synchronizedList(new ArrayList<>(response.getTasks().size()));
+var timeout = Duration.ofSeconds(30);
 try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
     response.getTasks().stream().filter(t -> t.getType().equals("BT"))
             .forEach(torrent -> executor.submit(() -> {
                 try {
-                    semaphore.acquire();
+                    if (!semaphore.tryAcquire(timeout.toMillis(), TimeUnit.MILLISECONDS)) {
+                        log.warn("获取信号量超时,跳过处理种子 {}", torrent.getTaskId());
+                        return;
+                    }

333-358: 建议优化:getTrackers() 方法的错误处理

方法实现正确,但建议改进以下几点:

  1. 建议在 354 行添加对空 tracker 的过滤
  2. 建议添加对重复 tracker 的去重处理
 return trackers.getTrackers().stream()
         .filter(t -> t.getName().startsWith("http") || t.getName().startsWith("udp") || t.getName().startsWith("ws"))
+        .filter(t -> !t.getName().trim().isEmpty())
+        .distinct()
         .map(t -> (Tracker) new TrackerImpl(t.getName())).toList();

398-399: 建议:简化 getPeers() 方法中的 group 判断逻辑

当前的实现使用了多个条件来判断不同版本的 group 值,建议将这些值统一到一个集合中,提高代码的可维护性。

-stream = stream.filter(dto -> dto.getGroup().equals("connected")
-        || dto.getGroup().equals("connected_peers")
-        || dto.getGroup().equals("peers_connected"));
+private static final Set<String> VALID_PEER_GROUPS = Set.of(
+    "connected",        // 2.10 正式版
+    "connected_peers",  // 2.11 Beta 1-2
+    "peers_connected"   // 2.11 Beta 3
+);
+stream = stream.filter(dto -> VALID_PEER_GROUPS.contains(dto.getGroup()));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b75964 and 69fe559.

📒 Files selected for processing (1)
  • src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (java-kotlin)
  • GitHub Check: Build_Docker_Standalone
🔇 Additional comments (3)
src/main/java/com/ghostchu/peerbanhelper/downloader/impl/bitcomet/BitComet.java (3)

268-269: 重构:getTorrents() 方法现在使用了新的 fetchTorrents() 方法

方法重构得当,通过复用 fetchTorrents() 方法减少了代码重复。


271-278: 新增:getAllTorrents() 方法实现完整

方法实现正确,通过设置 group_state=ALL 获取所有种子,并且正确处理了私有种子。


360-362: 建议完善未支持操作的异常处理

对于不支持的操作,应抛出适当的异常并提供清晰的错误信息。

 @Override
 public void setTrackers(Torrent torrent, List<Tracker> trackers) {
-    // Unsupported Operation
+    throw new UnsupportedOperationException("BitComet 客户端暂不支持设置 Tracker 操作");
 }

@Ghost-chu Ghost-chu merged commit 3731d74 into dev Jan 15, 2025
14 checks passed
@Ghost-chu Ghost-chu deleted the tracker-operation branch January 15, 2025 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant