From 5735156ee19cda7d6f4dac61f6227fd035fd4a9b Mon Sep 17 00:00:00 2001 From: Zayrex <478576442@qq.com> Date: Sat, 27 Sep 2025 20:54:02 +0800 Subject: [PATCH 1/4] =?UTF-8?q?*=E5=B0=86=E6=96=87=E4=BB=B6=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E6=93=8D=E4=BD=9C=E5=88=86=E7=A6=BB=20+=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=81=87=E5=88=B0=E9=94=99=E8=AF=AF=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commands/pixiv/Download.java | 160 +++++++----------- .../commands/pixiv/Fetcher.java | 29 ++-- .../acgpicdownload/commands/pixiv/Filter.java | 5 + .../acgpicdownload/commands/pixiv/Loader.java | 53 ++++++ .../acgpicdownload/commands/pixiv/Pixiv.java | 132 ++++++++------- .../acgpicdownload/commands/pixiv/Saver.java | 20 ++- .../zcraft/acgpicdownload/util/Logger.java | 6 + 7 files changed, 217 insertions(+), 188 deletions(-) create mode 100644 src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java create mode 100644 src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java index 25a3f3f..d2c7f30 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java @@ -1,7 +1,5 @@ package xyz.zcraft.acgpicdownload.commands.pixiv; -import com.alibaba.fastjson2.JSONArray; -import com.alibaba.fastjson2.JSONObject; import xyz.zcraft.acgpicdownload.util.Logger; import xyz.zcraft.acgpicdownload.util.dl.DownloadUtil; import xyz.zcraft.acgpicdownload.util.pixiv.ArtworkCondition; @@ -10,7 +8,6 @@ import xyz.zcraft.acgpicdownload.util.pixiv.PixivDownload; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.LinkedList; @@ -21,91 +18,78 @@ public class Download { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Download.class); + private static final Logger out = new Logger("Download"); + public int threads = 5; - private String fileName = null; private String target = "downloads"; - private List art; - public static void startDownload(String cookie, String proxyHost, int proxyPort, List art, int threads, String target) { AtomicInteger completed = new AtomicInteger(0); final ArrayList cur = new ArrayList<>(art.size()); for (int i1 = 0; i1 < threads; i1++) cur.add(null); - final ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(threads); - - final LinkedList err = new LinkedList<>(); - - art.forEach(e -> tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, cookie, proxyHost, proxyPort, target))); - - boolean first = true; - while (true) { - if (!first) - System.out.print("\033[" + (1 + threads) + "F"); - first = false; - System.out.println( - "\033[32mCompleted:" + completed + "/" + art.size() - + (err.isEmpty() ? "" : " \033[31mError:" + err.size()) + "\033[0m" - ); - for (int k = 0; k < threads; k++) { - System.out.print("\033[K"); - if (cur.get(k) == null) { - System.out.println("IDLE"); - } else { - PixivDownload dl = cur.get(k); - System.out.print("["); - int v = (int) (Math.floor(((double) dl.getProgress() / dl.getTotal()) * 16.0)); - for (int j = 0; j < v; j++) { - System.out.print("="); - } - for (int j = 0; j < 16 - v; j++) { - System.out.print(" "); + try (ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(threads)) { + + final LinkedList err = new LinkedList<>(); + + art.forEach(e -> tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, cookie, proxyHost, proxyPort, target))); + + boolean first = true; + while (true) { + if (!first) + System.out.print("\033[" + (1 + threads) + "F"); + first = false; + System.out.println( + "\033[32mCompleted:" + completed + "/" + art.size() + + (err.isEmpty() ? "" : " \033[31mError:" + err.size()) + "\033[0m" + ); + for (int k = 0; k < threads; k++) { + System.out.print("\033[K"); + if (cur.get(k) == null) { + System.out.println("IDLE"); + } else { + PixivDownload dl = cur.get(k); + System.out.print("["); + int v = (int) (Math.floor(((double) dl.getProgress() / dl.getTotal()) * 16.0)); + for (int j = 0; j < v; j++) { + System.out.print("="); + } + for (int j = 0; j < 16 - v; j++) { + System.out.print(" "); + } + System.out.print("] " + + dl.getArtwork().getId() + " \t" + + dl.getProgress() + "/" + dl.getTotal() + + (dl.getArtwork().getIllustType() == 2 ? " GIF" : "") + ); + System.out.println(); } - System.out.print("] " + - dl.getArtwork().getId() + " \t" + - dl.getProgress() + "/" + dl.getTotal() + - (dl.getArtwork().getIllustType() == 2 ? " GIF" : "") - ); - System.out.println(); } - } - if (completed.get() == art.size()) break; + if (completed.get() == art.size()) break; - try { - //noinspection BusyWait - Thread.sleep(500); - } catch (InterruptedException e) { - throw new RuntimeException(e); + try { + //noinspection BusyWait + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } } - tpe.shutdown(); } public void invoke(List argList, String cookie, - String proxyHost, int proxyPort, Logger logger, List previous) { + String proxyHost, int proxyPort, List previous) { for (int i = 1; i < argList.size(); i++) { if (!argList.get(i).startsWith("-")) break; switch (argList.get(i).toLowerCase()) { - case "-f", "-file": { - if (argList.size() > i + 1) { - i++; - this.fileName = argList.get(i); - } else { - logger.err("Please specify file name"); - return; - } - - break; - } - case "-o", "-output": { if (argList.size() > i + 1) { i++; this.target = argList.get(i); } else { - logger.err("Please specify a output path"); - return; + out.err("Please specify a output path"); + throw new IllegalArgumentException("Please specify a output path"); } break; @@ -117,16 +101,16 @@ public void invoke(List argList, String cookie, try { this.threads = Integer.parseInt(argList.get(i)); if (this.threads < 1) { - logger.err("Threads must be at least 1"); - return; + out.err("Threads must be at least 1"); + throw new IllegalArgumentException("Threads must be at least 1"); } } catch (NumberFormatException e) { - logger.err("Invalid number format: " + argList.get(i)); - return; + out.err("Invalid number format: " + argList.get(i)); + throw new NumberFormatException("Invalid number format: " + argList.get(i)); } } else { - logger.err("Please specify a number value"); - return; + out.err("Please specify a number value"); + throw new IllegalArgumentException("Please specify a number value"); } break; @@ -134,44 +118,16 @@ public void invoke(List argList, String cookie, } } - if (fileName == null && previous == null) { - logger.err("No artwork source to download!"); - return; - } - - if (fileName != null && previous != null) { - logger.warn("Both file and previous result are provided, using file"); - } - - if (fileName != null) { - try { - final String s = Files.readString(Path.of(fileName)); - final List parse = JSONArray.parse(s).toList(JSONObject.class); - art = new LinkedList<>(); - parse.forEach(e -> { - final var t = e.to(PixivArtwork.class); - t.setOrigJson(e); - art.add(t); - }); - } catch (IOException e) { - logger.err("Cannot read file " + fileName + ": " + e.getMessage()); - log.error("Cannot read file " + fileName, e); - return; - } - } else { - art = previous; - } - - if (art.isEmpty()) { - logger.warn("No artwork to download!"); + if (previous.isEmpty()) { + out.warn("No artwork to download!"); return; } - logger.info(art.size() + " artworks to download!"); + out.info(previous.size() + " artworks to download!"); - startDownload(cookie, proxyHost, proxyPort, art, threads, target); + startDownload(cookie, proxyHost, proxyPort, previous, threads, target); - logger.info("DONE Downloading"); + out.info("DONE Downloading"); } private record DownloadTask(int threads, PixivArtwork e, ArrayList cur, diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java index c73eb9c..b8806a7 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java @@ -12,10 +12,11 @@ public class Fetcher { @SuppressWarnings("unused") private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Fetcher.class); + private static final Logger out = new Logger("Fetcher"); private ArtProvider ap; - public List invoke(List argList, String cookie, String proxyHost, int proxyPort, Logger logger, Mode mode) { + public List invoke(List argList, String cookie, String proxyHost, int proxyPort, Mode mode) { switch (mode) { case Discovery -> { int discMode = 0; @@ -28,14 +29,14 @@ public List invoke(List argList, String cookie, String pro if (argList.size() > i + 1) { i++; if (!List.of(PixivFetchUtil.DISCOVERY_MODES).contains(argList.get(i))) { - logger.err("Unknown mode " + argList.get(i)); - return null; + out.err("Unknown mode " + argList.get(i)); + throw new IllegalArgumentException("Unknown mode " + argList.get(i)); } discMode = argList.indexOf(argList.get(i)); } else { - logger.err("Please specify a mode"); - return null; + out.err("Please specify a mode"); + throw new IllegalArgumentException("Please specify a mode"); } break; } @@ -44,22 +45,22 @@ public List invoke(List argList, String cookie, String pro if (argList.size() > i + 1) { i++; final int c = Integer.parseInt(argList.get(i)); - if (c < 0 || c > 50) { - logger.err("Count must be between 1 and 50."); - return null; + if (c < 0 || c > 100) { + out.err("Count must be between 1 and 100."); + throw new IllegalArgumentException("Count must be between 1 and 100"); } count = c; } else { - logger.err("Please specify a number."); - return null; + out.err("Please specify a number."); + throw new IllegalArgumentException("Please specify a number."); } break; } } } - logger.info("Ready to get discovery: mode=" + discMode + ",count=" + count + + out.info("Ready to get discovery: mode=" + discMode + ",count=" + count + (proxyHost != null ? ",proxy=" + proxyHost + ":" + proxyPort : "")); int finalCount = count; @@ -104,12 +105,12 @@ public List invoke(List argList, String cookie, String pro List art = f.getResult(); if (f.getException() != null) { - logger.err("Error getting " + mode + ": " + f.getException().getMessage()); - return null; + out.err("Error getting " + mode + ": " + f.getException().getMessage()); + throw new RuntimeException(f.getException()); } if (art == null || art.isEmpty()) { - logger.warn("No artworks found!"); + out.warn("No artworks found!"); return new LinkedList<>(); } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java new file mode 100644 index 0000000..f31f0bb --- /dev/null +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java @@ -0,0 +1,5 @@ +package xyz.zcraft.acgpicdownload.commands.pixiv; + +public class Filter { + +} diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java new file mode 100644 index 0000000..762bce2 --- /dev/null +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java @@ -0,0 +1,53 @@ +package xyz.zcraft.acgpicdownload.commands.pixiv; + +import com.alibaba.fastjson2.JSONArray; +import xyz.zcraft.acgpicdownload.util.Logger; +import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +public class Loader { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Loader.class); + private static final Logger out = new Logger("Loader"); + private String fileName; + + public List invoke(List argList) throws Exception { + for (int i = 1; i < argList.size(); i++) { + if (!argList.get(i).startsWith("-")) break; + switch (argList.get(i).toLowerCase()) { + case "-f", "-file": { + if (argList.size() > i + 1) { + i++; + this.fileName = argList.get(i); + } else { + out.err("Please specify file name"); + throw new IllegalArgumentException("Please specify file name"); + } + + break; + } + } + } + + if (fileName == null) { + out.err("Please specify a file name to read."); + throw new IllegalArgumentException("Please specify a file name to read."); + } + + out.info("Reading artwork data from file: " + fileName); + + try { + final String s = Files.readString(Path.of(fileName)); + final List list = JSONArray.parseArray(s, PixivArtwork.class); + + out.info("Read " + list.size() + " artwork data from file: " + fileName); + return list; + } catch (Exception e) { + log.error("Error reading file", e); + out.err("Error reading file: " + fileName); + throw new Exception("Error reading file: " + fileName, e); + } + } +} diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java index 4db5643..c166bca 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java @@ -12,15 +12,19 @@ public class Pixiv { private final List subCommands = List.of( - "discovery", "download", "ranking", "user", "disc", "dl", "rk", "save" + "discovery", "download", "ranking", "user", "save", "load" ); private final List fragments = new LinkedList<>(List.of(1)); private String cookie = null; private String proxyHost = null; private int proxyPort = -1; private List previous; + private boolean ignoreError = false; + private Logger logger; public void invoke(ArrayList argList, Logger logger) { + this.logger = logger; + for (int i = 1; i < argList.size(); i++) { if (subCommands.contains(argList.get(i).toLowerCase())) { fragments.add(i); @@ -31,76 +35,78 @@ public void invoke(ArrayList argList, Logger logger) { for (int i = 0; i < fragments.size() - 1; i++) { if (i == 0) { - for (int j = 1; j < fragments.get(i + 1); j++) { - switch (argList.get(j).toLowerCase()) { - case "-c", "-cookie": { - if (argList.size() > j + 1) { - j++; - try { - var p = argList.get(j); - if (p.startsWith("\"") && p.endsWith("\"")) p = p.substring(1, p.length() - 1); - cookie = Files.readString(Path.of(p)); - } catch (IOException e) { - logger.err("Cannot read cookie file " + argList.get(j)); - return; - } - } else { - logger.err("Please specify a cookie file"); - return; - } - break; - } - - case "-p", "-proxy": { - if (argList.size() > j + 1) { - j++; - try { - final String[] split = argList.get(j).split(":"); - proxyHost = split[0]; - proxyPort = Integer.parseInt(split[1]); - - System.getProperties().put("proxySet", "true"); - System.getProperties().put("proxyHost", proxyHost); - System.getProperties().put("proxyPort", String.valueOf(proxyPort)); - } catch (Exception e) { - logger.err("Cannot parse proxy " + argList.get(j)); - } - } else { - logger.err("Please specify a proxy"); - return; - } - break; - } - } - } + if (parseArgs(argList, i)) return; } else { - switch (argList.get(fragments.get(i)).toLowerCase()) { - case "discovery", "disc": { - previous = new Fetcher().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), cookie, proxyHost, proxyPort, logger, Fetcher.Mode.Discovery); - break; - } - - case "download", "dl": { - new Download().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), cookie, proxyHost, proxyPort, logger, previous); - break; - } - - case "save": { - new Saver().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), logger, previous); - break; + try { + executeSubCommand(argList, i); + } catch (Exception e) { + logger.err("Error executing sub-command " + argList.get(fragments.get(i)) + ": " + e.getMessage()); + if (ignoreError) { + logger.info("Ignoring error and continuing..."); + } else { + logger.info("Terminating due to error."); + return; } + } + } + } + } - case "ranking", "rk": { - previous = new Fetcher().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), cookie, proxyHost, proxyPort, logger, Fetcher.Mode.Ranking); - break; + private boolean parseArgs(ArrayList argList, int i) { + for (int j = 1; j < fragments.get(i + 1); j++) { + switch (argList.get(j).toLowerCase()) { + case "-c", "-cookie" -> { + if (argList.size() > j + 1) { + j++; + try { + var p = argList.get(j); + if (p.startsWith("\"") && p.endsWith("\"")) p = p.substring(1, p.length() - 1); + cookie = Files.readString(Path.of(p)); + } catch (IOException e) { + logger.err("Cannot read cookie file " + argList.get(j)); + return true; + } + } else { + logger.err("Please specify a cookie file"); + return true; } + } + case "-p", "-proxy" -> { + if (argList.size() > j + 1) { + j++; + try { + final String[] split = argList.get(j).split(":"); + proxyHost = split[0]; + proxyPort = Integer.parseInt(split[1]); - case "user", "u": { - previous = new Fetcher().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), cookie, proxyHost, proxyPort, logger, Fetcher.Mode.User); - break; + System.getProperties().put("proxySet", "true"); + System.getProperties().put("proxyHost", proxyHost); + System.getProperties().put("proxyPort", String.valueOf(proxyPort)); + } catch (Exception e) { + logger.err("Cannot parse proxy " + argList.get(j)); + } + } else { + logger.err("Please specify a proxy"); + return true; } } + case "-i", "-ignore" -> ignoreError = true; } } + return false; + } + + private void executeSubCommand(ArrayList argList, int i) throws Exception { + final List subArgs = argList.subList(fragments.get(i), fragments.get(i + 1)); + switch (argList.get(fragments.get(i)).toLowerCase()) { + case "discovery" -> + previous = new Fetcher().invoke(subArgs, cookie, proxyHost, proxyPort, Fetcher.Mode.Discovery); + case "download" -> new Download().invoke(subArgs, cookie, proxyHost, proxyPort, previous); + case "save" -> new Saver().invoke(subArgs, previous); + case "ranking" -> + previous = new Fetcher().invoke(subArgs, cookie, proxyHost, proxyPort, Fetcher.Mode.Ranking); + case "user" -> previous = new Fetcher().invoke(subArgs, cookie, proxyHost, proxyPort, Fetcher.Mode.User); + case "load" -> previous = new Loader().invoke(subArgs); + } } } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java index 5d4dbb7..d0f27fd 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java @@ -13,12 +13,13 @@ public class Saver { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Saver.class); + private static final Logger out = new Logger("Saver"); private String fileName; private boolean format = false; - public void invoke(List argList, Logger logger, List previous) { + public void invoke(List argList, List previous) throws Exception { if (previous == null || previous.isEmpty()) { - logger.warn("No artwork data to save."); + out.warn("No artwork data to save."); return; } @@ -30,8 +31,8 @@ public void invoke(List argList, Logger logger, List previ i++; this.fileName = argList.get(i); } else { - logger.err("Please specify file name"); - return; + out.err("Please specify file name"); + throw new IllegalArgumentException("Please specify file name"); } break; @@ -45,11 +46,11 @@ public void invoke(List argList, Logger logger, List previ } if (fileName == null) { - logger.err("Please specify a file name to save."); - return; + out.err("Please specify a file name to save."); + throw new IllegalArgumentException("Please specify a file name to save."); } - logger.info("Saving " + previous.size() + " artwork data to file: " + fileName); + out.info("Saving " + previous.size() + " artwork data to file: " + fileName); try { Files.writeString(Path.of(fileName), @@ -59,10 +60,11 @@ public void invoke(List argList, Logger logger, List previ ).toList() , (format ? new JSONWriter.Feature[]{JSONWriter.Feature.PrettyFormat} : new JSONWriter.Feature[]{})) ); - logger.info("File written to " + fileName); + out.info("File written to " + fileName); } catch (Exception e) { log.error("Error writing file", e); - logger.err("Error writing file: " + fileName); + out.err("Error writing file: " + fileName); + throw new Exception("Error writing file: " + fileName, e); } } } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java b/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java index 4001cb5..8028c42 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java @@ -25,6 +25,12 @@ public Logger(String name, PrintStream... out) { parentLogger = null; } + public Logger(String name) { + this.name = name; + this.out = new PrintStream[]{System.out}; + parentLogger = null; + } + public String getName() { if (parentLogger != null) { return parentLogger.getName() + "|" + name; From 66ed4e5cb3bcacd969aa70192df632ff5634c2ce Mon Sep 17 00:00:00 2001 From: Zayrex <478576442@qq.com> Date: Mon, 29 Sep 2025 21:54:15 +0800 Subject: [PATCH 2/4] =?UTF-8?q?+=E5=A2=9E=E5=8A=A0=E8=A1=A5=E5=85=A8?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=8C=87=E4=BB=A4=20+=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E6=8C=87=E4=BB=A4=20*=E5=B0=86JDK=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=9B=9E=E9=80=80=E5=88=B021?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/package.yml | 12 +-- .idea/misc.xml | 2 +- pom.xml | 14 +-- .../commands/pixiv/Complete.java | 100 ++++++++++++++++++ .../commands/pixiv/Download.java | 10 +- .../commands/pixiv/Fetcher.java | 6 +- .../acgpicdownload/commands/pixiv/Filter.java | 80 ++++++++++++++ .../acgpicdownload/commands/pixiv/Pixiv.java | 16 +-- .../commands/pixiv/Profile.java | 4 + .../xyz/zcraft/acgpicdownload/gui/GUI.java | 4 +- .../gui/controllers/FetchPaneController.java | 16 +-- .../gui/controllers/MainPaneController.java | 8 +- .../PixivAccountPaneController.java | 9 +- .../PixivDiscoveryPaneController.java | 2 +- .../PixivDownloadPaneController.java | 16 +-- .../controllers/PixivLoginPaneController.java | 2 +- .../controllers/PixivMenuPaneController.java | 2 +- .../PixivRankingPaneController.java | 4 +- .../PixivRelatedPaneController.java | 2 +- .../PixivSearchPaneController.java | 4 +- .../controllers/PixivUserPaneController.java | 2 +- .../util/pixiv/PixivArtwork.java | 2 + 22 files changed, 252 insertions(+), 65 deletions(-) create mode 100644 src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java create mode 100644 src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Profile.java diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 0c15291..6060b46 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -17,10 +17,10 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Set up JDK 25 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '25' + java-version: '21' distribution: 'temurin' server-id: github settings-path: ${{ github.workspace }} @@ -39,10 +39,10 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Set up JDK 25 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '25' + java-version: '21' distribution: 'temurin' server-id: github settings-path: ${{ github.workspace }} @@ -61,10 +61,10 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Set up JDK 25 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '25' + java-version: '21' distribution: 'temurin' server-id: github settings-path: ${{ github.workspace }} diff --git a/.idea/misc.xml b/.idea/misc.xml index 1fdfaa3..5c7a211 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -17,7 +17,7 @@ - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 672aaf9..e51cea6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,11 +6,11 @@ xyz.zcraft ACGPicDownload - 3.4.0 + 3.5.0 - 25 - 25 + 21 + 21 UTF-8 @@ -94,17 +94,17 @@ org.openjfx javafx-base - 25 + 21 org.openjfx javafx-controls - 25 + 21 org.openjfx javafx-fxml - 25 + 21 io.github.palexdev @@ -136,7 +136,7 @@ org.openjfx javafx-web - 25 + 21 \ No newline at end of file diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java new file mode 100644 index 0000000..433ba9b --- /dev/null +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java @@ -0,0 +1,100 @@ +package xyz.zcraft.acgpicdownload.commands.pixiv; + +import xyz.zcraft.acgpicdownload.util.Logger; +import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork; +import xyz.zcraft.acgpicdownload.util.pixiv.PixivFetchUtil; + +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.stream.Stream; + +public class Complete { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Complete.class); + private static final Logger out = new Logger("Complete"); + + private int threads = 2; + private int retries = 5; + + public List invoke(List argList, Profile profile, List previous) throws Exception { + for (int i = 1; i < argList.size(); i++) { + switch (argList.get(i).toLowerCase()) { + case "-t", "-thread" -> { + if (argList.size() > i + 1) { + i++; + this.threads = Integer.parseInt(argList.get(i)); + } else { + out.err("Please specify a thread count"); + throw new IllegalArgumentException("Please specify a thread count"); + } + + } + + case "-r", "-retry" -> { + if (argList.size() > i + 1) { + i++; + this.retries = Integer.parseInt(argList.get(i)); + } else { + out.err("Please specify time of retries"); + throw new IllegalArgumentException("Please specify time of retries"); + } + + } + } + } + + final List result = new LinkedList<>(); + + previous.stream().filter(p -> p.getLikeCount() != 0 || p.getBookmarkData() != null).forEach(result::add); + final List list = previous.stream().filter(p -> p.getLikeCount() == 0 && p.getBookmarkData() == null).toList(); + final List failedList = new LinkedList<>(); + + out.info("Got " + list.size() + " artworks to complete data."); + + AtomicInteger completed = new AtomicInteger(); + AtomicInteger failed = new AtomicInteger(); + + try (ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(threads)) { + list.forEach(t -> tpe.execute(() -> { + int tries = 1; + while (tries <= retries) { + try { + result.add(PixivFetchUtil.getArtwork(t.getId(), profile.cookie(), profile.proxyHost(), profile.proxyPort())); + completed.getAndIncrement(); + return; + } catch (IOException e) { + tries++; + } + } + + failedList.add(t); + failed.getAndIncrement(); + })); + + while (completed.get() + failed.get() < list.size()) { + System.out.print("\033[0K\033[32mCompleted: " + completed + "/" + list.size() + + (failed.get() == 0 ? "" : " \033[31mFailed: " + failed + "\033[32m") + "\033[0m\n"); + System.out.print("\033[0K["); + int v = (int) (Math.floor(((double) (completed.get() + failed.get()) / list.size()) * 16.0)); + for (int j = 0; j < v; j++) System.out.print("="); + for (int k = 0; k < (16 - v); k++) System.out.print(" "); + System.out.print("]\n"); + Thread.sleep(1000); + System.out.print("\033[2F"); + } + } + + final String failedIds = failedList.stream() + .flatMap((Function>) pixivArtwork -> Stream.of(pixivArtwork.getId())) + .toList().toString(); + + if (failed.get() > 0) out.err("Failed to complete " + failed + " artworks: " + failedIds); + else out.info("All artworks completed."); + + return result; + } +} diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java index d2c7f30..f93646d 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java @@ -24,7 +24,7 @@ public class Download { private String target = "downloads"; - public static void startDownload(String cookie, String proxyHost, int proxyPort, List art, int threads, String target) { + public static void startDownload(Profile profile, List art, int threads, String target) { AtomicInteger completed = new AtomicInteger(0); final ArrayList cur = new ArrayList<>(art.size()); for (int i1 = 0; i1 < threads; i1++) cur.add(null); @@ -32,7 +32,8 @@ public static void startDownload(String cookie, String proxyHost, int proxyPort, final LinkedList err = new LinkedList<>(); - art.forEach(e -> tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, cookie, proxyHost, proxyPort, target))); + art.forEach(e -> tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, + profile.cookie(), profile.proxyHost(), profile.proxyPort(), target))); boolean first = true; while (true) { @@ -78,8 +79,7 @@ public static void startDownload(String cookie, String proxyHost, int proxyPort, } } - public void invoke(List argList, String cookie, - String proxyHost, int proxyPort, List previous) { + public void invoke(List argList, Profile profile, List previous) { for (int i = 1; i < argList.size(); i++) { if (!argList.get(i).startsWith("-")) break; switch (argList.get(i).toLowerCase()) { @@ -125,7 +125,7 @@ public void invoke(List argList, String cookie, out.info(previous.size() + " artworks to download!"); - startDownload(cookie, proxyHost, proxyPort, previous, threads, target); + startDownload(profile, previous, threads, target); out.info("DONE Downloading"); } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java index b8806a7..397cfb6 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java @@ -16,7 +16,7 @@ public class Fetcher { private ArtProvider ap; - public List invoke(List argList, String cookie, String proxyHost, int proxyPort, Mode mode) { + public List invoke(List argList, Profile profile, Mode mode) { switch (mode) { case Discovery -> { int discMode = 0; @@ -61,11 +61,11 @@ public List invoke(List argList, String cookie, String pro } out.info("Ready to get discovery: mode=" + discMode + ",count=" + count + - (proxyHost != null ? ",proxy=" + proxyHost + ":" + proxyPort : "")); + (profile.proxyHost() != null ? ",proxy=" + profile.proxyHost() + ":" + profile.proxyPort() : "")); int finalCount = count; int finalDiscMode = discMode; - ap = () -> PixivFetchUtil.getDiscovery(finalDiscMode, finalCount, cookie, proxyHost, proxyPort); + ap = () -> PixivFetchUtil.getDiscovery(finalDiscMode, finalCount, profile.cookie(), profile.proxyHost(), profile.proxyPort()); } case User -> { // TODO diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java index f31f0bb..77827c9 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java @@ -1,5 +1,85 @@ package xyz.zcraft.acgpicdownload.commands.pixiv; +import xyz.zcraft.acgpicdownload.util.Logger; +import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork; + +import java.util.LinkedList; +import java.util.List; + public class Filter { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Filter.class); + private static final Logger out = new Logger("Filter"); + + private int bookmark = -1; + private int view = -1; + private int like = -1; + private boolean ignoreIncomplete = false; + + public List invoke(List argList, Profile profile, List previous) throws Exception { + for (int i = 1; i < argList.size(); i++) { + switch (argList.get(i).toLowerCase()) { + case "-b", "-bookmark" -> { + if (argList.size() > i + 1) { + i++; + this.bookmark = Integer.parseInt(argList.get(i)); + } else { + out.err("Please specify a bookmark count"); + throw new IllegalArgumentException("Please specify a bookmark count"); + } + + } + case "-v", "-view" -> { + if (argList.size() > i + 1) { + i++; + this.view = Integer.parseInt(argList.get(i)); + } else { + out.err("Please specify a view count"); + throw new IllegalArgumentException("Please specify a view count"); + } + + } + case "-l", "-like" -> { + if (argList.size() > i + 1) { + i++; + this.like = Integer.parseInt(argList.get(i)); + } else { + out.err("Please specify a like count"); + throw new IllegalArgumentException("Please specify a like count"); + } + } + case "-i" -> ignoreIncomplete = true; + } + } + + out.info("Got " + previous.size() + " artworks to filter with conditions:"); + if (like != -1) out.info(" - Minimum likes: " + like); + if (bookmark != -1) out.info(" - Minimum bookmarks: " + bookmark); + if (view != -1) out.info(" - Minimum views: " + view); + if (ignoreIncomplete) out.info(" - Ignoring incomplete artworks"); + + final List result = new LinkedList<>(); + + for (PixivArtwork p : previous) { + if (p.getLikeCount() == 0 && p.getBookmarkData() == null) { + if (!ignoreIncomplete) { + throw new IllegalArgumentException("Artwork " + p.getId() + " is incomplete, use -i to ignore."); + } + + out.warn("Artwork " + p.getId() + " is incomplete, skipping."); + continue; + } + + if ((like != -1 && p.getLikeCount() < like) + || (bookmark != -1 && p.getBookmarkCount() < bookmark) + || (view != -1 && p.getViewCount() < view)) { + continue; + } + + result.add(p); + } + + out.info("Filtered down to " + result.size() + " artworks. (" + (previous.size() - result.size()) + " filtered out)"); + return result; + } } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java index c166bca..cc6c434 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java @@ -12,7 +12,7 @@ public class Pixiv { private final List subCommands = List.of( - "discovery", "download", "ranking", "user", "save", "load" + "discovery", "download", "ranking", "user", "save", "load", "complete", "filter" ); private final List fragments = new LinkedList<>(List.of(1)); private String cookie = null; @@ -21,6 +21,7 @@ public class Pixiv { private List previous; private boolean ignoreError = false; private Logger logger; + private Profile profile; public void invoke(ArrayList argList, Logger logger) { this.logger = logger; @@ -36,6 +37,7 @@ public void invoke(ArrayList argList, Logger logger) { for (int i = 0; i < fragments.size() - 1; i++) { if (i == 0) { if (parseArgs(argList, i)) return; + profile = new Profile(cookie, proxyHost, proxyPort); } else { try { executeSubCommand(argList, i); @@ -99,14 +101,14 @@ private boolean parseArgs(ArrayList argList, int i) { private void executeSubCommand(ArrayList argList, int i) throws Exception { final List subArgs = argList.subList(fragments.get(i), fragments.get(i + 1)); switch (argList.get(fragments.get(i)).toLowerCase()) { - case "discovery" -> - previous = new Fetcher().invoke(subArgs, cookie, proxyHost, proxyPort, Fetcher.Mode.Discovery); - case "download" -> new Download().invoke(subArgs, cookie, proxyHost, proxyPort, previous); + case "discovery" -> previous = new Fetcher().invoke(subArgs, profile, Fetcher.Mode.Discovery); + case "download" -> new Download().invoke(subArgs, profile, previous); case "save" -> new Saver().invoke(subArgs, previous); - case "ranking" -> - previous = new Fetcher().invoke(subArgs, cookie, proxyHost, proxyPort, Fetcher.Mode.Ranking); - case "user" -> previous = new Fetcher().invoke(subArgs, cookie, proxyHost, proxyPort, Fetcher.Mode.User); + case "ranking" -> previous = new Fetcher().invoke(subArgs, profile, Fetcher.Mode.Ranking); + case "user" -> previous = new Fetcher().invoke(subArgs, profile, Fetcher.Mode.User); case "load" -> previous = new Loader().invoke(subArgs); + case "complete" -> previous = new Complete().invoke(subArgs, profile, previous); + case "filter" -> previous = new Filter().invoke(subArgs, profile, previous); } } } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Profile.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Profile.java new file mode 100644 index 0000000..3548fa5 --- /dev/null +++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Profile.java @@ -0,0 +1,4 @@ +package xyz.zcraft.acgpicdownload.commands.pixiv; + +public record Profile(String cookie, String proxyHost, int proxyPort) { +} diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/GUI.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/GUI.java index 966ff7e..de76708 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/GUI.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/GUI.java @@ -170,7 +170,7 @@ public void start(Stage stage) throws Exception { mainPaneController.init(); - stage.setOnCloseRequest(_ -> { + stage.setOnCloseRequest(a -> { stage.hide(); System.exit(0); }); @@ -323,7 +323,7 @@ private void initWindow() { .setContentText(ResourceBundleUtil.getString("gui.seriousERR") + "\n" + sw) .setShowClose(true) .setHeaderText(ResourceBundleUtil.getString("gui.fetch.err")).get(); - content.addActions(Map.entry(new MFXButton("OK"), _ -> System.exit(1))); + content.addActions(Map.entry(new MFXButton("OK"), a -> System.exit(1))); MFXGenericDialogBuilder.build(content) .toStageDialogBuilder() .initOwner(stage) diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/FetchPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/FetchPaneController.java index b2d182d..ab27138 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/FetchPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/FetchPaneController.java @@ -146,7 +146,7 @@ public void initialize(URL url, ResourceBundle resourceBundle) { initTable(); fetchBtn.disableProperty().bind(sourcesComboBox.selectedIndexProperty().isEqualTo(-1)); - data.addListener((ListChangeListener) _ -> downloadBtn.setDisable(data.isEmpty())); + data.addListener((ListChangeListener) a -> downloadBtn.setDisable(data.isEmpty())); try { ConfigManager.readConfig(); @@ -171,9 +171,9 @@ private void initTable() { MFXTableColumn statusColumn = new MFXTableColumn<>( ResourceBundleUtil.getString("gui.fetch.table.column.status"), true); - titleColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(arg01 -> arg01.getResult().getFileName())); - linkColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(arg01 -> arg01.getResult().getUrl())); - statusColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(DownloadResult::getStatusString)); + titleColumn.setRowCellFactory(a -> new MFXTableRowCell<>(arg01 -> arg01.getResult().getFileName())); + linkColumn.setRowCellFactory(a -> new MFXTableRowCell<>(arg01 -> arg01.getResult().getUrl())); + statusColumn.setRowCellFactory(a -> new MFXTableRowCell<>(DownloadResult::getStatusString)); titleColumn.setAlignment(Pos.CENTER); linkColumn.setAlignment(Pos.CENTER); @@ -198,7 +198,7 @@ private void initTable() { dataTable.getSelectionModel().setAllowsMultipleSelection(false); dataTable.getSelectionModel().selectionProperty() - .addListener((_, _, _) -> { + .addListener((a, b, c) -> { List selectedValues = dataTable.getSelectionModel().getSelectedValues(); if (!selectedValues.isEmpty()) { if (selectedValues.getFirst().getStatus() == DownloadStatus.COMPLETED && @@ -275,7 +275,7 @@ public void updateFromGithub() { ft.setFromValue(1); ft.setToValue(0); ft.play(); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); } }).start(); } @@ -338,7 +338,7 @@ public void handle(Exception e) { ft.setFromValue(1); ft.setToValue(0); data.addAll(r); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); }); @@ -380,7 +380,7 @@ private void updateSource() { Main.logError(e); } ft.play(); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); }).start(); ft.setFromValue(1); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/MainPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/MainPaneController.java index a5a24c1..fe9f5a5 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/MainPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/MainPaneController.java @@ -116,11 +116,11 @@ public void loadDone() { ft.setFromValue(1); ft.setDuration(Duration.millis(10)); ft.setRate(0.1); - ft.setOnFinished((_) -> initPane.setVisible(false)); + ft.setOnFinished((a) -> initPane.setVisible(false)); ft.play(); ft.setNode(blurImg); - ft.setOnFinished((_) -> blurImg.setVisible(false)); + ft.setOnFinished((a) -> blurImg.setVisible(false)); ft.play(); } @@ -141,11 +141,11 @@ public void reload() { ft.setFromValue(0); ft.setDuration(Duration.millis(10)); ft.setRate(0.1); - ft.setOnFinished((_) -> initPane.setVisible(false)); + ft.setOnFinished((a) -> initPane.setVisible(false)); ft.play(); ft.setNode(blurImg); - ft.setOnFinished((_) -> blurImg.setVisible(false)); + ft.setOnFinished((a) -> blurImg.setVisible(false)); ft.play(); } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivAccountPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivAccountPaneController.java index 0539c0a..aadbcc3 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivAccountPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivAccountPaneController.java @@ -72,7 +72,7 @@ public PixivAccount fromString(String string) { accountCombo.getItems().clear(); accountCombo.getItems().addAll(ConfigManager.getAccounts()); - accountCombo.selectedIndexProperty().addListener(_ -> { + accountCombo.selectedIndexProperty().addListener(a -> { ConfigManager.setSelectedAccount(accountCombo.getSelectedItem()); if (gui != null) gui.pixivPaneController.reloadAccount(); }); @@ -92,7 +92,7 @@ public void hide() { ft.setAutoReverse(false); ft.setRate(0.05); ft.setDuration(Duration.millis(5)); - ft.setOnFinished(_ -> Platform.runLater(() -> mainPane.setVisible(false))); + ft.setOnFinished(a -> Platform.runLater(() -> mainPane.setVisible(false))); ft.play(); } @@ -232,10 +232,9 @@ public void browserLoginBtnOnAction() { Notice.showError(ResourceBundleUtil.getString("gui.pixiv.account.addFailed"), gui.mainPane); } }, () -> Notice.showError(ResourceBundleUtil.getString("gui.pixiv.account.addFailed"), gui.mainPane)); - } catch (IOException e) { + } catch (Exception e) { Notice.showError(ResourceBundleUtil.getString("gui.pixiv.account.addFailed"), gui.mainPane); - } catch (URISyntaxException e) { - throw new RuntimeException(e); + logger.error("Failed to add account", e); } } } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDiscoveryPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDiscoveryPaneController.java index 5bad338..7396717 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDiscoveryPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDiscoveryPaneController.java @@ -94,7 +94,7 @@ public void fetchBtnOnAction() { ft.stop(); ft.setFromValue(1); ft.setToValue(0); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); } }).start(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDownloadPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDownloadPaneController.java index 90e7249..e196415 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDownloadPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivDownloadPaneController.java @@ -154,13 +154,13 @@ private void initTable() { MFXTableColumn typeColumn = new MFXTableColumn<>( ResourceBundleUtil.getString("gui.pixiv.download.column.type"), true); - titleColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(o -> o.getArtwork().getTitle())); - authorColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(o -> o.getArtwork().getUserName())); - fromColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(o -> o.getArtwork().getFromString())); - tagColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(o -> o.getArtwork().getTagsString())); - idColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(o -> o.getArtwork().getId())); - statusColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(PixivDownload::getStatusString)); - typeColumn.setRowCellFactory(_ -> new MFXTableRowCell<>(o -> o.getArtwork().getTypeString())); + titleColumn.setRowCellFactory(a -> new MFXTableRowCell<>(o -> o.getArtwork().getTitle())); + authorColumn.setRowCellFactory(a -> new MFXTableRowCell<>(o -> o.getArtwork().getUserName())); + fromColumn.setRowCellFactory(a -> new MFXTableRowCell<>(o -> o.getArtwork().getFromString())); + tagColumn.setRowCellFactory(a -> new MFXTableRowCell<>(o -> o.getArtwork().getTagsString())); + idColumn.setRowCellFactory(a -> new MFXTableRowCell<>(o -> o.getArtwork().getId())); + statusColumn.setRowCellFactory(a -> new MFXTableRowCell<>(PixivDownload::getStatusString)); + typeColumn.setRowCellFactory(a -> new MFXTableRowCell<>(o -> o.getArtwork().getTypeString())); titleColumn.setAlignment(Pos.CENTER); authorColumn.setAlignment(Pos.CENTER); @@ -206,7 +206,7 @@ public void initialize(URL location, ResourceBundle resources) { ResourceBundleUtil.getString("gui.pixiv.download.multiPageRule.gathered") ); - multiPageCombo.selectedIndexProperty().addListener((_, _, t1) -> folderNamingRuleField.setDisable(t1.intValue() != 0)); + multiPageCombo.selectedIndexProperty().addListener((a, b, t1) -> folderNamingRuleField.setDisable(t1.intValue() != 0)); multiPageCombo.selectFirst(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivLoginPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivLoginPaneController.java index 1901dc3..8c0a3de 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivLoginPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivLoginPaneController.java @@ -13,7 +13,7 @@ public class PixivLoginPaneController implements Initializable { @Override public void initialize(URL location, ResourceBundle resources) { webView.setZoom(0.8); - webView.getEngine().locationProperty().addListener((_, _, newValue) -> { + webView.getEngine().locationProperty().addListener((a, b, newValue) -> { if (newValue.startsWith("https://www.pixiv.net/")) { webView.getScene().getWindow().hide(); } diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivMenuPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivMenuPaneController.java index e471f84..78663e9 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivMenuPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivMenuPaneController.java @@ -99,7 +99,7 @@ public void fetchBtnOnAction() { ft.stop(); ft.setFromValue(1); ft.setToValue(0); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); } }).start(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRankingPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRankingPaneController.java index d42b268..6483f16 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRankingPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRankingPaneController.java @@ -55,7 +55,7 @@ public void initialize(URL url, ResourceBundle resourceBundle) { ResourceBundleUtil.getString("gui.pixiv.ranking.female") ); - majorCombo.selectedIndexProperty().addListener((_, _, t1) -> { + majorCombo.selectedIndexProperty().addListener((a, b, t1) -> { int i = t1.intValue(); if (i == 0 || i == 1 || i == 5 || i == 6 || i == 7) { resToggle.setDisable(false); @@ -183,7 +183,7 @@ public void fetchBtnOnAction() { ft.stop(); ft.setFromValue(1); ft.setToValue(0); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); } }).start(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRelatedPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRelatedPaneController.java index df313ab..ee662b3 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRelatedPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivRelatedPaneController.java @@ -85,7 +85,7 @@ public void fetchBtnOnAction() { ft.stop(); ft.setFromValue(1); ft.setToValue(0); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); } }).start(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivSearchPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivSearchPaneController.java index fda63b5..fa136f0 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivSearchPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivSearchPaneController.java @@ -66,7 +66,7 @@ public void initialize(URL url, ResourceBundle resourceBundle) { ResourceBundleUtil.getString("gui.pixiv.disc.mode.adult") ); - typeCombo.selectedIndexProperty().addListener((_, _, t1) -> { + typeCombo.selectedIndexProperty().addListener((a, b, t1) -> { int i = t1.intValue(); modeCombo.setDisable(i == 0); pageSlider.setDisable(i == 0); @@ -146,7 +146,7 @@ public void fetchBtnOnAction() { ft.stop(); ft.setFromValue(1); ft.setToValue(0); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); } }).start(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivUserPaneController.java b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivUserPaneController.java index e9328ba..a086d44 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivUserPaneController.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/gui/controllers/PixivUserPaneController.java @@ -94,7 +94,7 @@ public void fetchBtnOnAction() { ft.stop(); ft.setFromValue(1); ft.setToValue(0); - ft.setOnFinished((_) -> loadingPane.setVisible(false)); + ft.setOnFinished((a) -> loadingPane.setVisible(false)); ft.play(); } }).start(); diff --git a/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivArtwork.java b/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivArtwork.java index 406244e..ad625a7 100644 --- a/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivArtwork.java +++ b/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivArtwork.java @@ -69,6 +69,8 @@ public class PixivArtwork { private int bookmarkCount; @JSONField(name = "likeCount") private int likeCount; + @JSONField(name = "viewCount") + private int viewCount; private LinkedHashSet translatedTags = new LinkedHashSet<>(); private String imageUrl; From e919207cdabd61cd88762045ed0a0d5a1bef6de4 Mon Sep 17 00:00:00 2001 From: Zayrex Date: Mon, 29 Sep 2025 21:55:15 +0800 Subject: [PATCH 3/4] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b88272f..3f6d946 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ GUI: ![image](https://user-images.githubusercontent.com/73475219/206438395-89e1eec5-f734-484f-94d9-2b82a6c63f69.png) 命令行: +![demo](https://github.com/user-attachments/assets/26091bfd-c9ec-47a0-9e62-21d39f9fc667) ![2022-11-18 19-42-43_2](https://user-images.githubusercontent.com/73475219/202701179-2b8439ac-0f0a-4f12-9fbc-9574a1620411.gif) # 如何使用 From 73332a67e798f396248d703e6a124037765ca113 Mon Sep 17 00:00:00 2001 From: Zayrex Date: Mon, 29 Sep 2025 21:56:49 +0800 Subject: [PATCH 4/4] Update README.en.md --- README.en.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.en.md b/README.en.md index d7c25e8..9bc4ac1 100644 --- a/README.en.md +++ b/README.en.md @@ -16,6 +16,8 @@ A convenient tool to download pictures from various pixiv and APIs. - Highly customizable naming rules and fetching urls # Screenshots + +![demo](https://github.com/user-attachments/assets/26091bfd-c9ec-47a0-9e62-21d39f9fc667) ![gif](https://user-images.githubusercontent.com/73475219/206824795-d3332057-41e5-4271-abdd-446a02a9db3c.gif) ![image](https://user-images.githubusercontent.com/73475219/206455033-dc49237b-b8f1-4a39-bfa5-3f64b6f71fb1.png)