Skip to content

Commit

Permalink
完善 qB
Browse files Browse the repository at this point in the history
  • Loading branch information
paulzzh committed Nov 20, 2024
1 parent 0b20a9e commit 12377d4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public abstract class AbstractQbittorrent extends AbstractDownloader {
protected final String apiEndpoint;
protected final HttpClient httpClient;
protected final QBittorrentConfig config;
protected final Cache<String, Boolean> isPrivateCache;
protected final Cache<String, TorrentProperties> torrentPropertiesCache;

public AbstractQbittorrent(String name, QBittorrentConfig config, AlertManager alertManager) {
super(name, alertManager);
Expand Down Expand Up @@ -77,7 +77,7 @@ public PasswordAuthentication requestPasswordAuthenticationInstance(String host,
this.httpClient = builder.build();

YamlConfiguration profileConfig = Main.getProfileConfig();
this.isPrivateCache = CacheBuilder.newBuilder()
this.torrentPropertiesCache = CacheBuilder.newBuilder()
.maximumSize(2000)
.expireAfterAccess(
profileConfig.getLong("check-interval", 5000) + (1000 * 60),
Expand Down Expand Up @@ -156,56 +156,60 @@ public List<Torrent> getTorrents() {
List<QBittorrentTorrent> qbTorrent = JsonUtil.getGson().fromJson(request.body(), new TypeToken<List<QBittorrentTorrent>>() {
}.getType());

if (config.isIgnorePrivate()) {
fillTorrentPrivateField(qbTorrent);
}
fillTorrentProperties(qbTorrent);

return qbTorrent.stream().map(t -> (Torrent) t)
.filter(t -> !config.isIgnorePrivate() || !t.isPrivate())
.collect(Collectors.toList());
}

protected void fillTorrentPrivateField(List<QBittorrentTorrent> qbTorrent) {
Semaphore privateStatusLimit = new Semaphore(5);
protected void fillTorrentProperties(List<QBittorrentTorrent> qbTorrent) {
Semaphore torrentPropertiesLimit = new Semaphore(5);
try (ExecutorService service = Executors.newVirtualThreadPerTaskExecutor()) {
qbTorrent.stream()
.filter(torrent -> torrent.getPrivateTorrent() == null)
.filter(torrent -> (config.isIgnorePrivate() && torrent.getPrivateTorrent() == null)
|| torrent.getPieceSize() <= 0 || torrent.getPiecesHave() <= 0)
.forEach(detail -> service.submit(() -> {
if (detail.getPrivateTorrent() == null) {
try {
privateStatusLimit.acquire();
detail.setPrivateTorrent(getPrivateStatus(detail));
} catch (Exception e) {
log.debug("Failed to load private cache", e);
} finally {
privateStatusLimit.release();
try {
torrentPropertiesLimit.acquire();
TorrentProperties properties = getTorrentProperties(detail);
if (detail.getCompleted() != properties.completed) {
// completed value changed, invalidate cache and fetch again.
torrentPropertiesCache.invalidate(detail.getHash());
properties = getTorrentProperties(detail);
}
if (config.isIgnorePrivate() && detail.getPrivateTorrent() == null) {
log.debug("Field is_private is not present, query from properties api, hash: {}", detail.getHash());
detail.setPrivateTorrent(properties.isPrivate);
}
if (detail.getPieceSize() <= 0 || detail.getPiecesHave() <= 0) {
log.debug("Field piece_size,pieces_have is not present, query from properties api, hash: {}", detail.getHash());
detail.setPieceSize(properties.pieceSize);
detail.setPiecesHave(properties.piecesHave);
}
} catch (Exception e) {
log.debug("Failed to load properties cache", e);
} finally {
torrentPropertiesLimit.release();
}
}));
}
}

protected Boolean getPrivateStatus(QBittorrentTorrent torrent) {
if (torrent.getPrivateTorrent() != null) {
return torrent.getPrivateTorrent();
}
protected TorrentProperties getTorrentProperties(QBittorrentTorrent torrent) {
try {
return isPrivateCache.get(torrent.getHash(), () -> {
try {
log.debug("Field is_private is not present and cache miss, query from properties api, hash: {}", torrent.getHash());
HttpResponse<String> res = httpClient.send(
MutableRequest.GET(apiEndpoint + "/torrents/properties?hash=" + torrent.getHash()),
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
);
if (res.statusCode() == 200) {
var newDetail = JsonUtil.getGson().fromJson(res.body(), QBittorrentTorrent.class);
return newDetail.getPrivateTorrent();
} else {
log.warn("Error fetching properties for torrent hash: {}, status: {}", torrent.getHash(), res.statusCode());
}
} catch (Exception e) {
log.warn("Error fetching properties for torrent hash: {}", torrent.getHash(), e);
return torrentPropertiesCache.get(torrent.getHash(), () -> {
log.debug("torrent properties cache miss, query from properties api, hash: {}", torrent.getHash());
HttpResponse<String> res = httpClient.send(
MutableRequest.GET(apiEndpoint + "/torrents/properties?hash=" + torrent.getHash()),
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
);
if (res.statusCode() == 200) {
var newDetail = JsonUtil.getGson().fromJson(res.body(), QBittorrentTorrent.class);
return new TorrentProperties(newDetail.getPrivateTorrent(), torrent.getCompleted(), newDetail.getPieceSize(), newDetail.getPiecesHave());
}
return null;
// loader must not return null; it may either return a non-null value or throw an exception.
throw new IllegalStateException(String.format("Error fetching properties for torrent hash: %s, status: %d", torrent.getHash(), res.statusCode()));
});
} catch (Exception e) {
return null;
Expand Down Expand Up @@ -322,5 +326,5 @@ public void close() throws Exception {

}


public record TorrentProperties(boolean isPrivate, long completed, long pieceSize, long piecesHave) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public final class QBittorrentTorrent implements Torrent {
// @SerializedName("f_l_piece_prio")
// private Boolean fLPiecePrio;

@SerializedName("piece_size")
private long pieceSize;

@SerializedName("pieces_have")
private long piecesHave;

@SerializedName("force_start")
private boolean forceStart;

Expand Down Expand Up @@ -192,7 +198,7 @@ public long getSize() {

@Override
public long getCompletedSize() {
return completed;
return (pieceSize > 0 && piecesHave > 0) ? pieceSize * piecesHave : -1;
}

@Override
Expand Down

0 comments on commit 12377d4

Please sign in to comment.