diff --git a/.gitignore b/.gitignore
index b8c349c..021dd4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,5 @@ build/
/accounts.json
/log/
/.idea/
+/src/test/
+/debug.cookie
diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
new file mode 100644
index 0000000..70f212e
--- /dev/null
+++ b/.idea/dbnavigator.xml
@@ -0,0 +1,414 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 877a01e..2a24573 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -16,6 +16,7 @@
+
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 58c094f..c2aa3c7 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -19,6 +19,7 @@
opens xyz.zcraft.acgpicdownload.util.source to com.alibaba.fastjson2;
opens xyz.zcraft.acgpicdownload.util.pixiv to javafx.base, javafx.controls, javafx.graphics, javafx.fxml, com.alibaba.fastjson2;
opens xyz.zcraft.acgpicdownload.util.source.argument to javafx.base, javafx.controls, javafx.graphics, javafx.fxml, com.alibaba.fastjson2;
+
exports xyz.zcraft.acgpicdownload;
exports xyz.zcraft.acgpicdownload.exceptions;
exports xyz.zcraft.acgpicdownload.gui;
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/Main.java b/src/main/java/xyz/zcraft/acgpicdownload/Main.java
index c2052e6..0327503 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/Main.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/Main.java
@@ -2,7 +2,6 @@
import lombok.Getter;
import xyz.zcraft.acgpicdownload.commands.Fetch;
-import xyz.zcraft.acgpicdownload.commands.Schedule;
import xyz.zcraft.acgpicdownload.commands.pixiv.Pixiv;
import xyz.zcraft.acgpicdownload.gui.GUI;
import xyz.zcraft.acgpicdownload.util.Logger;
@@ -74,16 +73,10 @@ public static void main(String[] args) {
argList.remove(0);
Fetch f = new Fetch();
f.enableConsoleProgressBar = true;
- f.main(argList, new Logger("Fetch", System.out));
- } else if (argList.get(0).equalsIgnoreCase("schedule")) {
- err.println("Command schedule will be deprecated soon. See project on GitHub for more information.");
- argList.remove(0);
- Schedule s = new Schedule();
- s.main(argList);
+ f.invoke(argList, new Logger("Fetch", System.out));
} else if (argList.get(0).equalsIgnoreCase("pixiv")) {
- argList.remove(0);
Pixiv p = new Pixiv();
- p.revoke(argList, new Logger("Pixiv", System.out));
+ p.invoke(argList, new Logger("Pixiv", System.out));
}
}
}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/Fetch.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/Fetch.java
index 13db7db..f306e09 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/Fetch.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/Fetch.java
@@ -191,7 +191,7 @@ private Source parseSource() {
return s;
}
- public void main(ArrayList args, Logger logger) {
+ public void invoke(ArrayList args, Logger logger) {
this.logger = logger;
if (!parseArguments(args)) {
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/Schedule.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/Schedule.java
index 2a3414e..6c0cb61 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/Schedule.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/Schedule.java
@@ -10,11 +10,12 @@
import static xyz.zcraft.acgpicdownload.util.source.SourceManager.isEmpty;
+@Deprecated
public class Schedule {
private final ArrayList events = new ArrayList<>();
Logger l;
- public void main(ArrayList args) {
+ public void invoke(ArrayList args) {
if (!parseEvent(args)) {
return;
}
@@ -91,7 +92,7 @@ public void main(ArrayList args) {
public void run() {
Fetch f = new Fetch();
Logger t = new Logger(String.valueOf(this.hashCode()), logger, System.out);
- f.main(e.getCommands(), t);
+ f.invoke(e.getCommands(), t);
t.info("[Event End]");
}
});
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Discovery.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java
similarity index 50%
rename from src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Discovery.java
rename to src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java
index 69057a1..25a3f3f 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Discovery.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Download.java
@@ -1,11 +1,16 @@
package xyz.zcraft.acgpicdownload.commands.pixiv;
-import lombok.Getter;
+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.*;
+import xyz.zcraft.acgpicdownload.util.pixiv.ArtworkCondition;
+import xyz.zcraft.acgpicdownload.util.pixiv.NamingRule;
+import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
+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;
@@ -14,97 +19,24 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
-public class Discovery {
- private final int threads = 5;
- private int mode = 0;
- private int count = 1;
+public class Download {
+ private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Download.class);
+ public int threads = 5;
- public void revoke(List argList, String cookie, String proxyHost, int proxyPort, Logger logger) {
- for (int i = 0; i < argList.size(); i++) {
- switch (argList.get(i).toLowerCase()) {
- case "-m", "-mode": {
- if (argList.size() > i + 1) {
- i++;
- if (!List.of(PixivFetchUtil.DISCOVERY_MODES).contains(argList.get(i))) {
- logger.err("Unknown mode " + argList.get(i));
- return;
- }
-
- mode = argList.indexOf(argList.get(i));
- } else {
- logger.err("Please specify at the mode");
- return;
- }
- break;
- }
-
- case "-c", "-count": {
- 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;
- }
+ private String fileName = null;
+ private String target = "downloads";
- count = c;
- } else {
- logger.err("Please specify a number.");
- return;
- }
- break;
- }
- }
- }
-
- logger.info("Ready to get discovery: mode=" + mode + ",count=" + count + ",proxy=" + proxyHost + ":" + proxyPort);
-
- var f = new Fetch(mode, count, cookie, proxyHost, proxyPort);
- f.run();
-
- System.out.print("\033[?25l");
- System.out.println("Fetching...");
- System.out.print("[= ]\033[2G");
- int d = 1, i = 2;
- while (!(f.isDone() || f.isError())) {
- if (i + d >= 18) d = -1;
- else if (i + d < 2) d = 1;
- i += d;
- System.out.print("\033[" + (i) + "G=");
- System.out.print("\033[" + (i - d) + "G ");
- try {
- Thread.sleep(50);
- } catch (InterruptedException ignored) {
- }
- }
- if (f.isError())
- System.out.println("\r\033[31m[ ERROR ]\033[0m");
- else
- System.out.println("\r\033[32m[ DONE ]\033[0m");
- List art = f.getResult();
-
- if (f.getException() != null) {
- logger.err("Error getting discovery: " + f.getException().getMessage());
- return;
- }
-
- if (art == null || art.isEmpty()) {
- logger.err("No artworks found!");
- return;
- }
-
- System.out.println("\033[32mGot " + count + " artworks\033[0m");
- System.out.println();
- System.out.println("\033[1mDownloading...\033[0m");
+ 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<>(count);
+ 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)));
+ art.forEach(e -> tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, cookie, proxyHost, proxyPort, target)));
boolean first = true;
while (true) {
@@ -129,7 +61,11 @@ public void revoke(List argList, String cookie, String proxyHost, int pr
for (int j = 0; j < 16 - v; j++) {
System.out.print(" ");
}
- System.out.print("] " + dl.getArtwork().getId());
+ System.out.print("] " +
+ dl.getArtwork().getId() + " \t" +
+ dl.getProgress() + "/" + dl.getTotal() +
+ (dl.getArtwork().getIllustType() == 2 ? " GIF" : "")
+ );
System.out.println();
}
}
@@ -137,20 +73,111 @@ public void revoke(List argList, String cookie, String proxyHost, int pr
if (completed.get() == art.size()) break;
try {
+ //noinspection BusyWait
Thread.sleep(500);
} catch (InterruptedException e) {
-// throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
}
- System.out.print("\n\nDONE fetching discovery.");
- System.out.print("\033[?25h");
tpe.shutdown();
}
+ public void invoke(List argList, String cookie,
+ String proxyHost, int proxyPort, Logger logger, 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;
+ }
+
+ break;
+ }
+
+ case "-t", "-threads": {
+ if (argList.size() > i + 1) {
+ i++;
+ try {
+ this.threads = Integer.parseInt(argList.get(i));
+ if (this.threads < 1) {
+ logger.err("Threads must be at least 1");
+ return;
+ }
+ } catch (NumberFormatException e) {
+ logger.err("Invalid number format: " + argList.get(i));
+ return;
+ }
+ } else {
+ logger.err("Please specify a number value");
+ return;
+ }
+
+ break;
+ }
+ }
+ }
+
+ 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!");
+ return;
+ }
+
+ logger.info(art.size() + " artworks to download!");
+
+ startDownload(cookie, proxyHost, proxyPort, art, threads, target);
+
+ logger.info("DONE Downloading");
+ }
+
private record DownloadTask(int threads, PixivArtwork e, ArrayList cur,
LinkedList err, ThreadPoolExecutor tpe,
AtomicInteger completed, String cookie, String proxyHost,
- int proxyPort) implements Runnable {
+ int proxyPort, String target) implements Runnable {
@Override
public void run() {
int I = -1;
@@ -167,14 +194,14 @@ public void run() {
}
if (dl == null) {
- tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, cookie, proxyHost, proxyPort));
+ tpe.submit(new DownloadTask(threads, e, cur, err, tpe, completed, cookie, proxyHost, proxyPort, target));
return;
}
try {
new DownloadUtil(1).downloadPixiv(
dl,
- Path.of("downloads").toFile(),
+ Path.of(target).toFile(),
cookie,
new NamingRule("{$id}{_p$p}", 0, "{$id}"),
false,
@@ -194,48 +221,4 @@ public void run() {
}
}
}
-
- private static class Fetch {
- private final String cookie;
- private final String proxyHost;
- private final int proxyPort;
- private final int mode;
- private final int count;
- @Getter
- private Exception exception;
- @Getter
- private volatile boolean isDone = false;
- @Getter
- private volatile boolean isError = false;
- @Getter
- private List result = null;
-
- public Fetch(int mode, int count, String cookie, String proxyHost, int proxyPort) {
- this.cookie = cookie;
- this.proxyHost = proxyHost;
- this.proxyPort = proxyPort;
- this.mode = mode;
- this.count = count;
- }
-
- public void run() {
- new Thread(() -> {
- try {
- setDone(PixivFetchUtil.getDiscovery(mode, count, cookie, proxyHost, proxyPort));
- } catch (IOException e) {
- setError(e);
- }
- }).start();
- }
-
- private void setError(Exception e) {
- isError = true;
- this.exception = e;
- }
-
- private void setDone(List result) {
- isDone = true;
- this.result = result;
- }
- }
}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java
new file mode 100644
index 0000000..c73eb9c
--- /dev/null
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Fetcher.java
@@ -0,0 +1,178 @@
+package xyz.zcraft.acgpicdownload.commands.pixiv;
+
+import lombok.Getter;
+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;
+
+public class Fetcher {
+ @SuppressWarnings("unused")
+ private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(Fetcher.class);
+
+ private ArtProvider ap;
+
+ public List invoke(List argList, String cookie, String proxyHost, int proxyPort, Logger logger, Mode mode) {
+ switch (mode) {
+ case Discovery -> {
+ int discMode = 0;
+ int count = 1;
+
+ for (int i = 1; i < argList.size(); i++) {
+ if (!argList.get(i).startsWith("-")) break;
+ switch (argList.get(i).toLowerCase()) {
+ case "-m", "-mode": {
+ 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;
+ }
+
+ discMode = argList.indexOf(argList.get(i));
+ } else {
+ logger.err("Please specify a mode");
+ return null;
+ }
+ break;
+ }
+
+ case "-c", "-count": {
+ 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;
+ }
+
+ count = c;
+ } else {
+ logger.err("Please specify a number.");
+ return null;
+ }
+ break;
+ }
+ }
+ }
+
+ logger.info("Ready to get discovery: mode=" + discMode + ",count=" + count +
+ (proxyHost != null ? ",proxy=" + proxyHost + ":" + proxyPort : ""));
+
+ int finalCount = count;
+ int finalDiscMode = discMode;
+ ap = () -> PixivFetchUtil.getDiscovery(finalDiscMode, finalCount, cookie, proxyHost, proxyPort);
+ }
+ case User -> {
+ // TODO
+ }
+ case Ranking -> {
+ // TODO
+ }
+ case Search -> {
+ // TODO
+ }
+ }
+
+ var f = new Fetch(ap);
+
+ f.run();
+
+ System.out.print("\033[?25l");
+ System.out.println("Fetching...");
+ System.out.print("[= ]\033[2G");
+ int d = 1, i = 2;
+ while (!(f.isDone() || f.isError())) {
+ if (i + d >= 18) d = -1;
+ else if (i + d < 2) d = 1;
+ i += d;
+ System.out.print("\033[" + (i) + "G=");
+ System.out.print("\033[" + (i - d) + "G ");
+ try {
+ //noinspection BusyWait
+ Thread.sleep(50);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ if (f.isError())
+ System.out.println("\r\033[31m[ ERROR ]\033[0m");
+ else
+ System.out.println("\r\033[32m[ DONE ]\033[0m");
+ List art = f.getResult();
+
+ if (f.getException() != null) {
+ logger.err("Error getting " + mode + ": " + f.getException().getMessage());
+ return null;
+ }
+
+ if (art == null || art.isEmpty()) {
+ logger.warn("No artworks found!");
+ return new LinkedList<>();
+ }
+
+ System.out.println("\033[32mGot " + art.size() + " artworks\033[0m");
+ System.out.println();
+
+ System.out.print("\nDONE fetching " + mode + ". " + art.size() + " artworks found.\n");
+ System.out.print("\033[?25h");
+
+ return art;
+ }
+
+ public enum Mode {
+ Discovery, User, Ranking, Search;
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case Discovery -> "discovery";
+ case User -> "user artworks";
+ case Ranking -> "ranking";
+ case Search -> "search";
+ };
+ }
+ }
+
+ public interface ArtProvider {
+ List fetch() throws IOException;
+ }
+
+ private static class Fetch {
+ private final ArtProvider ap;
+ @Getter
+ private Exception exception;
+ @Getter
+ private volatile boolean isDone = false;
+ @Getter
+ private volatile boolean isError = false;
+ @Getter
+ private List result = null;
+
+ public Fetch(ArtProvider ap) {
+ this.ap = ap;
+ }
+
+ public void run() {
+ new Thread(() -> {
+ try {
+ setDone(ap.fetch());
+ } catch (IOException e) {
+ setError(e);
+ }
+ }).start();
+ }
+
+ private void setError(Exception e) {
+ isError = true;
+ this.exception = e;
+ }
+
+ private void setDone(List result) {
+ isDone = true;
+ this.result = 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 68fb5b0..4db5643 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Pixiv.java
@@ -1,60 +1,104 @@
package xyz.zcraft.acgpicdownload.commands.pixiv;
import xyz.zcraft.acgpicdownload.util.Logger;
+import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
public class Pixiv {
+ private final List subCommands = List.of(
+ "discovery", "download", "ranking", "user", "disc", "dl", "rk", "save"
+ );
+ private final List fragments = new LinkedList<>(List.of(1));
private String cookie = null;
private String proxyHost = null;
private int proxyPort = -1;
+ private List previous;
- public void revoke(ArrayList argList, Logger logger) {
- for (int i = 0; i < argList.size(); i++) {
- switch (argList.get(i).toLowerCase()) {
- case "-c", "-cookie": {
- if (argList.size() > i + 1) {
- i++;
- try {
- cookie = Files.readString(Path.of(argList.get(i)));
- } catch (IOException e) {
- logger.err("Cannot read cookie file " + argList.get(i));
- return;
+ public void invoke(ArrayList argList, Logger logger) {
+ for (int i = 1; i < argList.size(); i++) {
+ if (subCommands.contains(argList.get(i).toLowerCase())) {
+ fragments.add(i);
+ }
+ }
+
+ fragments.add(argList.size());
+
+ 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;
}
- } else {
- logger.err("Please specify a cookie file");
- return;
- }
- break;
- }
- case "-p", "-proxy": {
- if (argList.size() > i + 1) {
- i++;
- try {
- final String[] split = argList.get(i).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(i));
+ 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;
}
- } else {
- logger.err("Please specify a proxy");
- return;
}
- break;
}
+ } 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 "discovery", "disc": {
- new Discovery().revoke(argList.subList(i + 1, argList.size()), cookie, proxyHost, proxyPort, logger);
- return;
+ 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;
+ }
+
+ case "ranking", "rk": {
+ previous = new Fetcher().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), cookie, proxyHost, proxyPort, logger, Fetcher.Mode.Ranking);
+ break;
+ }
+
+ case "user", "u": {
+ previous = new Fetcher().invoke(argList.subList(fragments.get(i), fragments.get(i + 1)), cookie, proxyHost, proxyPort, logger, Fetcher.Mode.User);
+ break;
+ }
}
}
}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java
new file mode 100644
index 0000000..5d4dbb7
--- /dev/null
+++ b/src/main/java/xyz/zcraft/acgpicdownload/commands/pixiv/Saver.java
@@ -0,0 +1,68 @@
+package xyz.zcraft.acgpicdownload.commands.pixiv;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONWriter;
+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;
+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 String fileName;
+ private boolean format = false;
+
+ public void invoke(List argList, Logger logger, List previous) {
+ if (previous == null || previous.isEmpty()) {
+ logger.warn("No artwork data to save.");
+ return;
+ }
+
+ for (int i = 1; i < argList.size(); i++) {
+ if (!argList.get(i).startsWith("-")) break;
+ switch (argList.get(i).toLowerCase()) {
+ case "-o", "-output": {
+ if (argList.size() > i + 1) {
+ i++;
+ this.fileName = argList.get(i);
+ } else {
+ logger.err("Please specify file name");
+ return;
+ }
+
+ break;
+ }
+
+ case "-f", "-format": {
+ format = true;
+ break;
+ }
+ }
+ }
+
+ if (fileName == null) {
+ logger.err("Please specify a file name to save.");
+ return;
+ }
+
+ logger.info("Saving " + previous.size() + " artwork data to file: " + fileName);
+
+ try {
+ Files.writeString(Path.of(fileName),
+ JSONArray.toJSONString(
+ previous.stream().flatMap(
+ (Function>) e -> Stream.of(e.getOrigJson())
+ ).toList()
+ , (format ? new JSONWriter.Feature[]{JSONWriter.Feature.PrettyFormat} : new JSONWriter.Feature[]{}))
+ );
+ logger.info("File written to " + fileName);
+ } catch (Exception e) {
+ log.error("Error writing file", e);
+ logger.err("Error writing file: " + fileName);
+ }
+ }
+}
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java b/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java
index ad59061..4001cb5 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/util/Logger.java
@@ -1,11 +1,14 @@
package xyz.zcraft.acgpicdownload.util;
+import lombok.Getter;
+
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Logger {
private final String name;
+ @Getter
private final Logger parentLogger;
private final PrintStream[] out;
@@ -29,17 +32,13 @@ public String getName() {
return name;
}
- public Logger getParentLogger() {
- return parentLogger;
- }
-
public String getOutputName() {
- return "[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "][" + getName() + "] ";
+ return "[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "][" + getName() + "]";
}
public void info(String message) {
for (PrintStream t : out) {
- t.println(getOutputName() + message);
+ t.println(getOutputName() + "[I] " + message);
t.flush();
}
}
@@ -54,7 +53,11 @@ public void printr(String str) {
}
public void err(String message) {
- System.err.println(getOutputName() + message);
+ System.err.println(getOutputName() + "\033[0;31m[E]\033[0m " + message);
+ }
+
+ public void warn(String message) {
+ System.err.println(getOutputName() + "\033[0;33m[E]\033[0m " + message);
}
public void printf(String format, String... arg) {
diff --git a/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivDownload.java b/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivDownload.java
index 2b18d00..bed457d 100644
--- a/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivDownload.java
+++ b/src/main/java/xyz/zcraft/acgpicdownload/util/pixiv/PixivDownload.java
@@ -10,7 +10,9 @@ public class PixivDownload {
private DownloadStatus status = DownloadStatus.CREATED;
private Exception exception;
private int progress = 0;
+ private int progressBytes = 0;
private int total = 0;
+ private int totalBytes = 0;
public PixivDownload(PixivArtwork artwork) {
this.artwork = artwork;
diff --git a/src/test/java/GifTest.java b/src/test/java/GifTest.java
deleted file mode 100644
index 56d4cba..0000000
--- a/src/test/java/GifTest.java
+++ /dev/null
@@ -1,16 +0,0 @@
-import xyz.zcraft.acgpicdownload.util.pixiv.GifData;
-import xyz.zcraft.acgpicdownload.util.pixiv.PixivArtwork;
-import xyz.zcraft.acgpicdownload.util.pixiv.PixivFetchUtil;
-
-import java.io.IOException;
-
-public class GifTest {
- private static final String cookieString = "PHPSESSID=53586815_etMGmfiftP72YvjcUPE3qRGwd8xHHAj2";
-
- public static void main(String[] args) throws IOException {
- final PixivArtwork pixivArtwork = new PixivArtwork();
- pixivArtwork.setId("91945977");
- GifData gifData = PixivFetchUtil.getGifData(pixivArtwork, cookieString, "127.0.0.1", 7890);
- System.out.println(gifData.getSrc());
- }
-}
diff --git a/src/test/java/PixivAccountTest.java b/src/test/java/PixivAccountTest.java
deleted file mode 100644
index 4e8faf9..0000000
--- a/src/test/java/PixivAccountTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-import com.alibaba.fastjson2.JSONObject;
-import org.jsoup.Connection;
-import org.jsoup.Jsoup;
-
-import java.util.HashMap;
-import java.util.Objects;
-
-import static xyz.zcraft.acgpicdownload.util.pixiv.PixivFetchUtil.parseCookie;
-
-public class PixivAccountTest {
- public static void main(String[] args) {
- String cookieString = "PHPSESSID=88458885_oPHKLxNYucl77CsueCnlimJbk7jFCnxS;";
- HashMap cookie = parseCookie(cookieString);
- Connection c = Jsoup.connect("https://www.pixiv.net")
- .ignoreContentType(true)
- .method(Connection.Method.GET)
- .cookies(cookie)
- .timeout(10 * 1000);
-
- c.proxy("127.0.0.1", 7890);
-
- try {
- String text = Objects.requireNonNull(c.get().getElementById("meta-global-data")).attr("content");
- final JSONObject jsonObject = JSONObject.parseObject(text);
- System.out.println(jsonObject.getString("token"));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/test/java/PixivBookmarkTest.java b/src/test/java/PixivBookmarkTest.java
deleted file mode 100644
index 0095a78..0000000
--- a/src/test/java/PixivBookmarkTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-import com.alibaba.fastjson2.JSONArray;
-import com.alibaba.fastjson2.JSONObject;
-import org.jsoup.Connection;
-import org.jsoup.Jsoup;
-
-import java.io.IOException;
-
-public class PixivBookmarkTest {
- public static void main(String[] args) throws IOException {
- JSONObject json = new JSONObject();
- json.put("illust_id", "104278312");
- json.put("restrict", 0);
- json.put("comment", "");
- json.put("tags", new JSONArray());
-
- System.out.println(json.toJSONString());
-
- final String response = Jsoup.connect("https://www.pixiv.net/ajax/illusts/bookmarks/add")
- .proxy("127.0.0.1", 7890)
- .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.69")
- .header("Cookie", "first_visit_datetime_pc=2023-01-17+20:57:49; p_ab_id=9; p_ab_id_2=3; p_ab_d_id=548119463; yuid_b=JUAnEEQ; privacy_policy_agreement=5; _ga=GA1.2.1769619120.1670332183; PHPSESSID=88458885_Ad022PSkkxj7xDaLeiJwS7LzPOyizsJv; device_token=f602092c8dd3ef28d19c163b5e115880; _ga_MZ1NL4PHH0=GS1.1.1673956724.1.1.1673956877.0.0.0; c_type=23; privacy_policy_notification=0; a_type=0; b_type=1; QSI_S_ZN_5hF4My7Ad6VNNAi=v:0:0; login_ever=yes; __cf_bm=q9Y6WtPU.i0hji5yXBtyVXsawJ2QU9qDDFfTkOt4cjI-1674913317-0-ATYCeZT0M3+Lgjh/q4oZo2HJsIDttHtt4ANl7TUFPnyyetZZVcFc8kqjuMUH8CY8RSeoOka/VMmO/51EDXtaGN8XIQGS17YG36f1jF1cEcFNptRSlniAvN6ZhQzkOPyOO4x3j10PVAyRmQt+yak5pitsJfP8nuyFMy36LDnQAvyIA3U/l7dUQRs+tGIUlDO4ciyhxfxq/Tu0vZDYRTFNWXk=; tag_view_ranking=-98s6o2-Rp~r_Jjn6Ua2V~jTSl_ciRq2~EZQqoW9r8g~2R7RYffVfj~SapL8yQw4Y~y8GNntYHsi~i83OPEGrYw~MhBZqc0gyc~Oe_3HJFeBA~O64_t9evHE~O2wfZxfonb~mYDe1eOQZ4~yL80PVO9Um~A7hSoqw-5Z~VTGlg0gWIi~cryvQ5p2Tx~Ged1jLxcdL~01ilCGA69_~SAyihQLaXc~Qq_PJ4rEpq~Ysy4PAF_ss~PwDMGzD6xn~qWFESUmfEs~Nj9Bt-JWdN~_IharlAfPe~jk9IzfjZ6n~n39RQWfHku~0CaTbfGZYk~ePN3h1AXKX")
- .header("Content-Type", "application/json;charset=UTF-8")
- .header("x-csrf-token", "755a7ccfb5e2770de6c6ddf5f9e1a0f6")
- .requestBody(json.toJSONString())
- .method(Connection.Method.POST)
- .ignoreHttpErrors(true)
- .ignoreContentType(true)
- .execute()
- .body();
- System.out.println("response = " + response);
- }
-}