diff --git a/README.en.md b/README.en.md
index 9bc4ac1..eb7a915 100644
--- a/README.en.md
+++ b/README.en.md
@@ -23,14 +23,4 @@ A convenient tool to download pictures from various pixiv and APIs.
# Usage
-- Download the latest Release in [Releases](https://github.com/zxzxy/ACGPicDownload/releases)
-
-> If you already have Java17+ installed, then you can download `ACGPicDownload.version.jar` and run it through command
-> line. Or
-> download `ACGPicDownload.version.win.exe` on Windows and run.
-
-> If you don't, then you can download JDK17+ [here](https://adoptium.net/en-US/temurin/archive), or
-> download `ACGPicDownload.version.win.7z`, which has JDK17 included
-
-
Please go to [wiki](https://github.com/zxzxy/ACGPicDownload/wiki) for usage...
diff --git a/README.md b/README.md
index 3f6d946..29715ec 100644
--- a/README.md
+++ b/README.md
@@ -26,12 +26,4 @@ GUI:
# 如何使用
-- 在[Releases](https://github.com/zxzxy/ACGPicDownload/releases)下载最新版本
-
-> 如果你的设备已经安装了Java17+,那么可以下载 `ACGPicDownload.版本号.jar` 并直接使用命令行运行,或在 Windows
-> 上下载 `ACGPicDownload.版本号.win.exe` 并直接运行
-
-> 如果并没有Java17+安装,那么可以在[这里](https://adoptium.net/zh-CN/temurin/archive)
-> 下载安装Java17以上的版本,或者如果你是Windows,则可以下载 `ACGPicDownload.版本号.win.jdk.7z`, 里面自带JDK17
-
-- 请在[wiki](https://github.com/zxzxy/ACGPicDownload/wiki)查看详细使用教程~
+- 请在[wiki](https://github.com/ZayrexDev/ACGPicDownload/wiki)查看详细使用教程~
diff --git a/pom.xml b/pom.xml
index e51cea6..3ff6202 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
xyz.zcraft
ACGPicDownload
- 3.5.0
+ 3.5.1
21
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 cc6c434..cc0e2a3 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java
@@ -1,5 +1,6 @@
package xyz.zcraft.acgpicdownload.commands.pixiv;
+import xyz.zcraft.acgpicdownload.commands.pixiv.sub.*;
import xyz.zcraft.acgpicdownload.util.Logger;
import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
@@ -12,7 +13,7 @@
public class Pixiv {
private final List subCommands = List.of(
- "discovery", "download", "ranking", "user", "save", "load", "complete", "filter"
+ "download", "fetch", "save", "load", "complete", "filter", "add"
);
private final List fragments = new LinkedList<>(List.of(1));
private String cookie = null;
@@ -100,15 +101,21 @@ 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, 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, 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);
- }
+
+ SubCommand subCommand = switch (argList.get(fragments.get(i)).toLowerCase()) {
+ case "fetch" -> new Fetch();
+ case "download" -> new Download();
+ case "save" -> new Save();
+ case "load" -> new Load();
+ case "complete" -> new Complete();
+ case "filter" -> new Filter();
+ case "add" -> new Add();
+ default -> {
+ logger.err("Unknown sub-command: " + argList.get(fragments.get(i)));
+ throw new IllegalArgumentException("Unknown sub-command: " + argList.get(fragments.get(i)));
+ }
+ };
+
+ previous = subCommand.invoke(subArgs, profile, previous);
}
}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/SubCommand.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/SubCommand.java
new file mode 100644
index 0000000..e574d27
--- /dev/null
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/SubCommand.java
@@ -0,0 +1,18 @@
+package xyz.zcraft.acgpicdownload.commands.pixiv;
+
+import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
+
+import java.util.List;
+
+public abstract class SubCommand {
+ protected final org.apache.log4j.Logger log;
+ protected final Logger out;
+
+ public SubCommand() {
+ log = org.apache.log4j.Logger.getLogger(this.getClass());
+ out = new Logger(this.getClass().getSimpleName());
+ }
+
+ public abstract List invoke(List argList, Profile profile, List previous) throws Exception;
+}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Add.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Add.java
new file mode 100644
index 0000000..2b57fc1
--- /dev/null
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Add.java
@@ -0,0 +1,42 @@
+package xyz.zcraft.acgpicdownload.commands.pixiv.sub;
+
+import xyz.zcraft.acgpicdownload.commands.pixiv.Profile;
+import xyz.zcraft.acgpicdownload.commands.pixiv.SubCommand;
+import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class Add extends SubCommand {
+ public List invoke(List argList, Profile profile, List previous) throws Exception {
+ List idStrings = new LinkedList<>();
+
+ for (int i = 1; i < argList.size(); i++) {
+ String e = argList.get(i);
+ idStrings.addAll(List.of(e.split(",")));
+ }
+
+ List result = new LinkedList<>();
+
+ for (String idString : idStrings) {
+ if (idString.trim().isEmpty()) continue;
+ try {
+ int id = Integer.parseInt(idString.trim());
+ PixivArtwork newArtwork = new PixivArtwork();
+ newArtwork.setId(String.valueOf(id));
+ result.add(newArtwork);
+ } catch (NumberFormatException e) {
+ out.err("Invalid artwork ID: " + idString + ", skipping.");
+ }
+ }
+
+ out.info("Added " + result.size() + " artworks.");
+ if (previous != null && !previous.isEmpty()) {
+ out.info("Appending to previous " + previous.size() + " artwork data, now total: " + (previous.size() + result.size()));
+ previous.addAll(result);
+ return previous;
+ } else {
+ return result;
+ }
+ }
+}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Complete.java
similarity index 93%
rename from src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java
rename to src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Complete.java
index 433ba9b..748dc14 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Complete.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Complete.java
@@ -1,6 +1,7 @@
-package xyz.zcraft.acgpicdownload.commands.pixiv;
+package xyz.zcraft.acgpicdownload.commands.pixiv.sub;
-import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.commands.pixiv.Profile;
+import xyz.zcraft.acgpicdownload.commands.pixiv.SubCommand;
import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
import xyz.zcraft.acgpicdownload.util.pixiv.PixivFetchUtil;
@@ -13,10 +14,7 @@
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");
-
+public class Complete extends SubCommand {
private int threads = 2;
private int retries = 5;
@@ -83,6 +81,7 @@ public List invoke(List argList, Profile profile, List art, int threads, String target) {
@@ -79,7 +76,7 @@ public static void startDownload(Profile profile, List art, int th
}
}
- public void invoke(List argList, Profile profile, List previous) {
+ public List 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()) {
@@ -120,7 +117,7 @@ public void invoke(List argList, Profile profile, List pre
if (previous.isEmpty()) {
out.warn("No artwork to download!");
- return;
+ return previous;
}
out.info(previous.size() + " artworks to download!");
@@ -128,6 +125,8 @@ public void invoke(List argList, Profile profile, List pre
startDownload(profile, previous, threads, target);
out.info("DONE Downloading");
+
+ return previous;
}
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/sub/Fetch.java
similarity index 76%
rename from src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java
rename to src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Fetch.java
index 397cfb6..33d5625 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Fetch.java
@@ -1,7 +1,9 @@
-package xyz.zcraft.acgpicdownload.commands.pixiv;
+package xyz.zcraft.acgpicdownload.commands.pixiv.sub;
+
import lombok.Getter;
-import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.commands.pixiv.Profile;
+import xyz.zcraft.acgpicdownload.commands.pixiv.SubCommand;
import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
import xyz.zcraft.acgpicdownload.util.pixiv.PixivFetchUtil;
@@ -9,23 +11,34 @@
import java.util.LinkedList;
import java.util.List;
-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");
-
+public class Fetch extends SubCommand {
private ArtProvider ap;
+ private boolean append = false;
- public List invoke(List argList, Profile profile, Mode mode) {
+ public List invoke(List argList, Profile profile, List previous) {
+ if (argList.isEmpty()) {
+ out.err("Please specify a fetch mode: -discovery, -user, -ranking, -search");
+ throw new IllegalArgumentException("Please specify a fetch mode: -discovery, -user, -ranking, -search");
+ }
+ Mode mode = switch (argList.get(1).toLowerCase()) {
+ case "-discovery" -> Mode.Discovery;
+ case "-user" -> Mode.User;
+ case "-ranking" -> Mode.Ranking;
+ case "-search" -> Mode.Search;
+ default -> {
+ out.err("Unknown fetch mode: " + argList.getFirst());
+ throw new IllegalArgumentException("Unknown fetch mode: " + argList.getFirst());
+ }
+ };
switch (mode) {
case Discovery -> {
int discMode = 0;
int count = 1;
- for (int i = 1; i < argList.size(); i++) {
+ for (int i = 2; i < argList.size(); i++) {
if (!argList.get(i).startsWith("-")) break;
switch (argList.get(i).toLowerCase()) {
- case "-m", "-mode": {
+ case "-m", "-mode" -> {
if (argList.size() > i + 1) {
i++;
if (!List.of(PixivFetchUtil.DISCOVERY_MODES).contains(argList.get(i))) {
@@ -38,10 +51,8 @@ public List invoke(List argList, Profile profile, Mode mod
out.err("Please specify a mode");
throw new IllegalArgumentException("Please specify a mode");
}
- break;
}
-
- case "-c", "-count": {
+ case "-c", "-count" -> {
if (argList.size() > i + 1) {
i++;
final int c = Integer.parseInt(argList.get(i));
@@ -55,8 +66,8 @@ public List invoke(List argList, Profile profile, Mode mod
out.err("Please specify a number.");
throw new IllegalArgumentException("Please specify a number.");
}
- break;
}
+ case "-a", "-append" -> append = true;
}
}
@@ -78,7 +89,7 @@ public List invoke(List argList, Profile profile, Mode mod
}
}
- var f = new Fetch(ap);
+ var f = new Fetcher(ap);
f.run();
@@ -120,7 +131,14 @@ public List invoke(List argList, Profile profile, Mode mod
System.out.print("\nDONE fetching " + mode + ". " + art.size() + " artworks found.\n");
System.out.print("\033[?25h");
- return art;
+ if (append && previous != null) {
+ out.info("Appending to previous " + previous.size() + " artworks, total " + (previous.size() + art.size()) + " artworks.");
+ LinkedList combined = new LinkedList<>(previous);
+ combined.addAll(art);
+ return combined;
+ } else {
+ return art;
+ }
}
public enum Mode {
@@ -141,7 +159,7 @@ public interface ArtProvider {
List fetch() throws IOException;
}
- private static class Fetch {
+ private static class Fetcher {
private final ArtProvider ap;
@Getter
private Exception exception;
@@ -152,7 +170,7 @@ private static class Fetch {
@Getter
private List result = null;
- public Fetch(ArtProvider ap) {
+ public Fetcher(ArtProvider ap) {
this.ap = ap;
}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Filter.java
similarity index 91%
rename from src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java
rename to src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Filter.java
index 77827c9..e885c45 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Filter.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Filter.java
@@ -1,15 +1,13 @@
-package xyz.zcraft.acgpicdownload.commands.pixiv;
+package xyz.zcraft.acgpicdownload.commands.pixiv.sub;
-import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.commands.pixiv.Profile;
+import xyz.zcraft.acgpicdownload.commands.pixiv.SubCommand;
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");
-
+public class Filter extends SubCommand {
private int bookmark = -1;
private int view = -1;
private int like = -1;
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Load.java
similarity index 64%
rename from src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java
rename to src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Load.java
index 762bce2..16a62c7 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Loader.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Load.java
@@ -1,23 +1,23 @@
-package xyz.zcraft.acgpicdownload.commands.pixiv;
+package xyz.zcraft.acgpicdownload.commands.pixiv.sub;
import com.alibaba.fastjson2.JSONArray;
-import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.commands.pixiv.Profile;
+import xyz.zcraft.acgpicdownload.commands.pixiv.SubCommand;
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");
+public class Load extends SubCommand {
private String fileName;
+ private boolean append = false;
- public List invoke(List argList) throws Exception {
+ public List invoke(List argList, Profile profile, List previous) throws Exception {
for (int i = 1; i < argList.size(); i++) {
if (!argList.get(i).startsWith("-")) break;
switch (argList.get(i).toLowerCase()) {
- case "-f", "-file": {
+ case "-f", "-file" -> {
if (argList.size() > i + 1) {
i++;
this.fileName = argList.get(i);
@@ -25,9 +25,9 @@ public List invoke(List argList) throws Exception {
out.err("Please specify file name");
throw new IllegalArgumentException("Please specify file name");
}
-
- break;
}
+
+ case "-a", "-append" -> append = true;
}
}
@@ -43,7 +43,13 @@ public List invoke(List argList) throws Exception {
final List list = JSONArray.parseArray(s, PixivArtwork.class);
out.info("Read " + list.size() + " artwork data from file: " + fileName);
- return list;
+ if (append && previous != null && !previous.isEmpty()) {
+ out.info("Appending to previous " + previous.size() + " artwork data, now total: " + (previous.size() + list.size()));
+ previous.addAll(list);
+ return previous;
+ } else {
+ return list;
+ }
} catch (Exception e) {
log.error("Error reading file", e);
out.err("Error reading file: " + fileName);
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Save.java
similarity index 84%
rename from src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java
rename to src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Save.java
index d0f27fd..052ed0b 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/sub/Save.java
@@ -1,8 +1,9 @@
-package xyz.zcraft.acgpicdownload.commands.pixiv;
+package xyz.zcraft.acgpicdownload.commands.pixiv.sub;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONWriter;
-import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.commands.pixiv.Profile;
+import xyz.zcraft.acgpicdownload.commands.pixiv.SubCommand;
import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
import java.nio.file.Files;
@@ -11,16 +12,14 @@
import java.util.function.Function;
import java.util.stream.Stream;
-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");
+public class Save extends SubCommand {
private String fileName;
private boolean format = false;
- public void invoke(List argList, List previous) throws Exception {
+ public List invoke(List argList, Profile profile, List previous) throws Exception {
if (previous == null || previous.isEmpty()) {
out.warn("No artwork data to save.");
- return;
+ return previous;
}
for (int i = 1; i < argList.size(); i++) {
@@ -66,5 +65,6 @@ public void invoke(List argList, List previous) throws Exc
out.err("Error writing file: " + fileName);
throw new Exception("Error writing file: " + fileName, e);
}
+ return previous;
}
}