123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- * pixiv_down - CLI-based downloading tool for https://www.pixiv.net.
- * Copyright (C) 2024 Mio
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- module app.cmds.artwork;
- import pd.configuration: Config;
- /**
- * Download specified artworks.
- *
- * The expected format of *args* is: `["pixiv_down", "artwork", "id1", ...]`
- *
- * Params:
- * args = The arguments passed to pixiv_down.
- * config = pixiv_down configuration
- * Returns: 0 on success, non-zero on error
- */
- public int artworkHandle(string[] args, in Config config)
- {
- import std.algorithm.searching : all, find;
- import std.conv : ConvException, to;
- import std.getopt : getopt, GetOptOption = config;
- import std.stdio : stderr, stdout;
- import pd.pixiv;
- import pd.pixiv_downloader;
- import app.util : sleep;
- // When an exception occurs.
- string[] invalidArtworks;
- // The error message for the invalidArtworks
- // each index in the array matches the ID.
- string[] errorMessages;
- bool groupErrors = false;
- bool forceDownload = false;
- int returnCode = 0;
- /* artwork <id> */
- if (args.length < 2) {
- displayArtworkHelp();
- return 1;
- }
- auto helpInformation = getopt(args,
- GetOptOption.passThrough,
- "group-errors", &groupErrors,
- "force|f", &forceDownload,
- );
- if (helpInformation.helpWanted) {
- displayArtworkHelp();
- return 0;
- }
- string[] ids = find!(isValidID)(args);
- foreach(id; ids) {
- try {
- ArtworkInfo info = fetchArtworkInfo(id, config);
- downloadArtwork(info, config, forceDownload);
- } catch (PixivJSONException pje) {
- if (groupErrors) {
- invalidArtworks ~= id;
- errorMessages ~= pje.msg;
- } else {
- stderr.writefln("Error: Failed to fetch and download ID '%s'", id);
- stderr.writeln(pje.msg);
- }
- continue;
- }
- sleep(1, 5);
- }
- if (groupErrors && 0 < invalidArtworks.length) {
- stderr.writeln("Failed to download the following IDs:");
- foreach (index, id; invalidArtworks) {
- stderr.writefln(" %s - %s", id, errorMessages[index]);
- }
- }
- return returnCode;
- }
- void displayArtworkHelp()
- {
- import std.stdio : stderr;
- stderr.writefln(
- "pixiv_down artwork - Download specific artwork(s)\n" ~
- "\nUsage:\tpixiv_down artwork [options] <id> [<additional ids...>]\n" ~
- "\nYou can download one or more artworks via this command. Any\n" ~
- "artworks that fail to download are mentioned after attempting to\n" ~
- "download, you can change this to only print at the end by using the\n" ~
- "--group-errors option.\n" ~
- "\nOptions:\n" ~
- " -f, --force-download\tOverwrite existing downloads.\n" ~
- " --group-errors \tDisplay errors at the end instead.\n" ~
- "\nExamples:\n" ~
- "\n Download a single artwork:\n" ~
- " pixiv_down artwork id\n" ~
- "\n Download multiple artworks and display failed IDs at the end:\n" ~
- " pixiv_down artwork --group-errors id1 id2\n");
- }
- private:
- bool isValidID(const(char)[] id) {
- import std.algorithm.searching : all;
- import std.ascii : isDigit;
- return id.all!(isDigit);
- }
|