diff --git a/.github/workflows/jvm-ci.yml b/.github/workflows/jvm-ci.yml index 466e193e60..93fd34bd4b 100644 --- a/.github/workflows/jvm-ci.yml +++ b/.github/workflows/jvm-ci.yml @@ -63,7 +63,7 @@ jobs: type=raw,ci type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.10.0 + uses: docker/build-push-action@v6.11.0 with: context: . file: ./Dockerfile @@ -98,7 +98,7 @@ jobs: type=raw,ci type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.10.0 + uses: docker/build-push-action@v6.11.0 with: context: . file: ./Dockerfile diff --git a/.github/workflows/jvm-release.yml b/.github/workflows/jvm-release.yml index d7c4bb334c..9277ff9357 100644 --- a/.github/workflows/jvm-release.yml +++ b/.github/workflows/jvm-release.yml @@ -159,7 +159,7 @@ jobs: type=raw,latest type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.10.0 + uses: docker/build-push-action@v6.11.0 with: context: . file: ./Dockerfile @@ -195,7 +195,7 @@ jobs: type=raw,latest type=sha - name: Build and push Aliyun ACR - uses: docker/build-push-action@v6.10.0 + uses: docker/build-push-action@v6.11.0 with: context: . file: ./Dockerfile-Release diff --git a/.gitignore b/.gitignore index 66171cba55..88a9dc8e3a 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ dependency-reduced-pom.xml PeerBanHelper.jar *.pkg install4j/output +install4j/project.install4j~ diff --git a/pom.xml b/pom.xml index 4a5e4ba0eb..75f275ae5b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.ghostchu.peerbanhelper peerbanhelper - 7.3.1 + 7.3.2 jar PeerBanHelper @@ -258,7 +258,7 @@ org.bspfsystems yamlconfiguration - 3.0.1 + 3.0.2 compile @@ -398,7 +398,7 @@ org.apache.james apache-mime4j-dom - 0.8.11 + 0.8.12 commons-io @@ -409,7 +409,7 @@ org.apache.james apache-mime4j-core - 0.8.11 + 0.8.12 commons-io @@ -420,7 +420,7 @@ org.apache.james apache-mime4j-storage - 0.8.11 + 0.8.12 commons-io diff --git a/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java b/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java index 592acb6080..01e2167250 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java +++ b/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java @@ -201,6 +201,10 @@ private void runTestCode() { return; } // run some junky test code here +// ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory +// .getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); +// root.setLevel(ch.qos.logback.classic.Level.TRACE); + } diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java b/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java index e3387de430..cb506f6b28 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java @@ -75,6 +75,11 @@ private void performUpgrade() throws SQLException { TableUtils.createTableIfNotExists(database.getDataSource(), AlertEntity.class); v = 7; } + if (v == 7) { + TableUtils.dropTable(getDataSource(), AlertEntity.class, true); + TableUtils.createTableIfNotExists(database.getDataSource(), AlertEntity.class); + v = 8; + } version.setValue(String.valueOf(v)); metadata.update(version); } diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java index 709e8f1d5a..47909e6cd1 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java @@ -44,15 +44,16 @@ public Page getBannedIps(Pageable pageable, String filter) throws .selectRaw("ip, COUNT(*) AS count") .groupBy("ip") .orderByRaw("count DESC"); + String[] args = new String[0]; if (filter != null) { - builder.setWhere(builder.where().like("ip", new SelectArg(filter + "%"))); + builder.setWhere(builder.where().like("ip", new SelectArg())); + args = new String[]{filter + "%"}; } - List mapped; - try (GenericRawResults banLogs = builder + var queryBuilder = builder .limit(pageable.getSize()) - .offset(pageable.getZeroBasedPage() * pageable.getSize()) - // .where().ge("banAt", twoWeeksAgo) - .queryRaw()) { + .offset(pageable.getZeroBasedPage() * pageable.getSize()); + List mapped; + try (GenericRawResults banLogs = queryRaw(queryBuilder.prepareStatementString(), args)) { var results = banLogs.getResults(); mapped = results.stream().map(arr -> new PeerBanCount(arr[0], Long.parseLong(arr[1]))).toList(); } diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java b/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java index 872f1dcab1..ffb43214be 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java +++ b/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java @@ -1,8 +1,8 @@ package com.ghostchu.peerbanhelper.database.table; import com.ghostchu.peerbanhelper.alert.AlertLevel; +import com.ghostchu.peerbanhelper.database.TranslationComponentPersistener; import com.ghostchu.peerbanhelper.text.TranslationComponent; -import com.j256.ormlite.field.DataType; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; import lombok.AllArgsConstructor; @@ -26,8 +26,8 @@ public final class AlertEntity { private AlertLevel level; @DatabaseField(canBeNull = false, index = true) private String identifier; - @DatabaseField(canBeNull = false, dataType = DataType.SERIALIZABLE) + @DatabaseField(canBeNull = false, persisterClass = TranslationComponentPersistener.class) private TranslationComponent title; - @DatabaseField(canBeNull = false, dataType = DataType.SERIALIZABLE) + @DatabaseField(canBeNull = false, persisterClass = TranslationComponentPersistener.class) private TranslationComponent content; } \ No newline at end of file diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java index 9e62b65a0f..7cf95818f9 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java +++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java @@ -162,7 +162,6 @@ public boolean isLoggedIn() { } return !info.getQt().isBlank(); } catch (Exception e) { - log.error("Failed to check login status", e); return false; } } diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java index c4b7649696..89e9f43719 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java @@ -153,7 +153,7 @@ private void handleInfo(Context ctx) throws SQLException { private void handleBanHistory(Context ctx) throws SQLException { - String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toString(); + String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toNormalizedString(); Pageable pageable = new Pageable(ctx); var builder = historyDao.queryBuilder() .orderBy("banAt", false); @@ -168,7 +168,7 @@ private void handleBanHistory(Context ctx) throws SQLException { private void handleAccessHistory(Context ctx) throws SQLException { activeMonitoringModule.flush(); - String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toString(); + String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toNormalizedString(); Pageable pageable = new Pageable(ctx); var builder = peerRecordDao.queryBuilder() .orderBy("lastTimeSeen", false); diff --git a/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java b/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java index e9e9369629..88dbd3c4a7 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java +++ b/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java @@ -1,5 +1,6 @@ package com.ghostchu.peerbanhelper.util.json; +import com.ghostchu.peerbanhelper.text.TranslationComponent; import com.google.gson.*; import org.jetbrains.annotations.NotNull; @@ -13,6 +14,7 @@ public class JsonUtil { .setExclusionStrategies(new HiddenAnnotationExclusionStrategy()) .serializeNulls() .registerTypeAdapter(Timestamp.class, TimestampTypeAdapter.INSTANCE) + .registerTypeAdapter(TranslationComponent.class, TranslationComponentTypeAdapter.INSTANCE) .disableHtmlEscaping() .create(); diff --git a/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java b/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java index 5a4521deb1..f109186eaa 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java +++ b/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java @@ -1,20 +1,72 @@ package com.ghostchu.peerbanhelper.util.json; import com.ghostchu.peerbanhelper.text.TranslationComponent; -import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; -import java.lang.reflect.Type; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; -import static com.ghostchu.peerbanhelper.text.TextManager.tlUI; - -public class TranslationComponentTypeAdapter implements JsonSerializer { +public class TranslationComponentTypeAdapter extends TypeAdapter { public static final TranslationComponentTypeAdapter INSTANCE = new TranslationComponentTypeAdapter(); @Override - public JsonElement serialize(TranslationComponent ts, Type t, JsonSerializationContext jsc) { - return new JsonPrimitive(tlUI(ts)); + public void write(JsonWriter out, TranslationComponent value) throws IOException { + out.beginObject(); + out.name("key").value(value.getKey()); + out.name("params"); + out.beginArray(); // 开始 JSON 数组 + // 遍历 params 数组并写入元素 + for (Object param : value.getParams()) { + if (param instanceof TranslationComponent) { + // 如果是 TranslationComponent,递归调用 write 方法 + TranslationComponentTypeAdapter.INSTANCE.write(out, (TranslationComponent) param); + } else { + out.value(param.toString()); + } + } + out.endArray(); // 结束 JSON 数组 + out.endObject(); // 结束 JSON 对象 + + // 特别注意嵌套里面不允许出现除了 TranslationComponent 以外的 JsonObject,否则必翻车 + } + + @Override + public TranslationComponent read(JsonReader in) throws IOException { + String key = null; + List params = new ArrayList<>(); + + in.beginObject(); // 开始读取 JSON 对象 + + while (in.hasNext()) { // 循环读取每个字段 + String name = in.nextName(); + if ("key".equals(name)) { + key = in.nextString(); // 读取 key 字段 + } else if ("params".equals(name)) { + in.beginArray(); // 开始读取 JSON 数组 + while (in.hasNext()) { + // 判断当前元素是字符串还是 TranslationComponent + if (in.peek() == JsonToken.STRING) { + params.add(in.nextString()); // 如果是字符串,直接添加到 params 列表 + } else if (in.peek() == JsonToken.BEGIN_OBJECT) { + // 如果是对象,则递归读取 TranslationComponent + params.add(TranslationComponentTypeAdapter.INSTANCE.read(in)); + } else { + in.skipValue(); // 跳过不需要的值 + } + } + in.endArray(); // 结束数组读取 + } else { + in.skipValue(); // 跳过不需要的字段 + } + } + + in.endObject(); // 结束 JSON 对象的读取 + + // 构造并返回 TranslationComponent 对象 + return new TranslationComponent(key, params.toArray(new Object[0])); } } \ No newline at end of file diff --git a/webui/src/stores/endpoint.ts b/webui/src/stores/endpoint.ts index e2993f2101..85c642a153 100644 --- a/webui/src/stores/endpoint.ts +++ b/webui/src/stores/endpoint.ts @@ -210,6 +210,8 @@ export const useEndpointStore = defineStore('endpoint', () => { throw new IncorrectTokenError() } else if (res.status === 303) { throw new NeedInitError() + } else if (res.status === 401) { + throw new IncorrectTokenError() } }, getGlobalConfig, diff --git a/webui/src/views/banlist/components/banListItem.vue b/webui/src/views/banlist/components/banListItem.vue index b503b644fd..c5ce36eceb 100644 --- a/webui/src/views/banlist/components/banListItem.vue +++ b/webui/src/views/banlist/components/banListItem.vue @@ -136,7 +136,7 @@ - + {{ item.banMetadata.torrent.name }}