A CLI tool for downloading from pixiv.net
Revision | b7fcfcf18ec9223b800711a585388d3f49c110cc (tree) |
---|---|
Zeit | 2023-10-29 18:41:39 |
Autor | mio <stigma@disr...> |
Commiter | mio |
Move configuration to separate module
Slowly going around and breaking down the main file.
@@ -24,6 +24,8 @@ import pixivd.types; | ||
24 | 24 | |
25 | 25 | import pixivd.client; |
26 | 26 | |
27 | +import configuration; | |
28 | + | |
27 | 29 | class ProgressMonitor |
28 | 30 | { |
29 | 31 | private size_t currentPage = 1; |
@@ -130,12 +132,6 @@ class ProgressMonitor | ||
130 | 132 | } |
131 | 133 | } |
132 | 134 | |
133 | -struct Config | |
134 | -{ | |
135 | - string baseFolder; | |
136 | - Client client; | |
137 | -} | |
138 | - | |
139 | 135 | enum ExitCode |
140 | 136 | { |
141 | 137 | success = 0, |
@@ -172,48 +168,6 @@ private bool convertToString(size_t value, out string converted) | ||
172 | 168 | } |
173 | 169 | |
174 | 170 | /** |
175 | - * Prompt for the PHPSESSID cookie. | |
176 | - * | |
177 | - * Returns: The entered input, with the leading and trailing whitespace | |
178 | - * stripped. | |
179 | - */ | |
180 | -string askForSessionID() | |
181 | -{ | |
182 | - import std.stdio : readln, writeln, write; | |
183 | - import std.string : strip; | |
184 | - | |
185 | - string ret = ""; | |
186 | - | |
187 | - writeln("========== NOTICE =========="); | |
188 | - writeln("No PHPSESSID value found."); | |
189 | - writeln("Please see the below instructions to find yours."); | |
190 | - writeln("https://codeberg.org/supercell/pixivd/src/branch/trunk/PHPSESSID"); | |
191 | - writeln("============================"); | |
192 | - | |
193 | - while ("" == ret) { | |
194 | - write("Please enter your PHPSESSID: "); | |
195 | - ret = readln().strip(); | |
196 | - } | |
197 | - | |
198 | - return ret; | |
199 | -} | |
200 | - | |
201 | -/** | |
202 | - * Store the *sessionid* in the file located at *path*. | |
203 | - * | |
204 | - * Params: | |
205 | - * sessionid = The PHPSESSID cookie value to store. | |
206 | - * path = The location of the file to write the value to. | |
207 | - */ | |
208 | -pragma(inline, true) | |
209 | -void storeSessionID(string sessionid, string path) | |
210 | -{ | |
211 | - import std.stdio : File; | |
212 | - | |
213 | - File(path, "w").writeln(sessionid); | |
214 | -} | |
215 | - | |
216 | -/** | |
217 | 171 | * Set the modification and access date/time for the provided *illust*. |
218 | 172 | * |
219 | 173 | * Params: |
@@ -311,7 +265,7 @@ void downloadIllust(ref Illustration illust, ref Config conf, | ||
311 | 265 | import std.path : buildPath; |
312 | 266 | import std.stdio : stderr; |
313 | 267 | |
314 | - const rawPath = buildPath(conf.baseFolder, | |
268 | + const rawPath = buildPath(conf.outputDirectory, | |
315 | 269 | illust.userId ~ "_" ~ illust.userName); |
316 | 270 | const subDirectory = makeSafe(rawPath); |
317 | 271 |
@@ -1144,85 +1098,6 @@ logLibGMVersion() | ||
1144 | 1098 | infof("GraphicsMagick Depth S: %s", MagickQuantumDepth); |
1145 | 1099 | } |
1146 | 1100 | |
1147 | -void | |
1148 | -resetSessionID() | |
1149 | -{ | |
1150 | - import std.file : exists, mkdirRecurse; | |
1151 | - import std.path : buildPath; | |
1152 | - | |
1153 | - import directories : ProjectDirectories, getProjectDirectories; | |
1154 | - | |
1155 | - const projectDirectories = getProjectDirectories(null, "YumeNeru", | |
1156 | - "pixiv_down"); | |
1157 | - if (false == exists(projectDirectories.dataDir)) | |
1158 | - { | |
1159 | - mkdirRecurse(projectDirectories.dataDir); | |
1160 | - } | |
1161 | - const sessionid = askForSessionID(); | |
1162 | - storeSessionID(sessionid, | |
1163 | - buildPath(projectDirectories.dataDir, ".phpsessid")); | |
1164 | -} | |
1165 | - | |
1166 | -Config | |
1167 | -loadConfig() | |
1168 | -{ | |
1169 | - import std.experimental.logger : infof; | |
1170 | - import std.file : exists, mkdirRecurse; | |
1171 | - import std.path : buildPath; | |
1172 | - import std.string : strip; | |
1173 | - import std.stdio : File; | |
1174 | - | |
1175 | - import configparser : ConfigParser; | |
1176 | - import directories : ProjectDirectories, UserDirectories, | |
1177 | - getProjectDirectories, getUserDirectories; | |
1178 | - | |
1179 | - Config config; | |
1180 | - | |
1181 | - ProjectDirectories dirs = getProjectDirectories(null, "YumeNeru Software", | |
1182 | - "pixiv_down"); | |
1183 | - UserDirectories userDirs = getUserDirectories(); | |
1184 | - infof("Configuration Directory = %s", dirs.configDir); | |
1185 | - | |
1186 | - if (exists(dirs.configDir)) { | |
1187 | - string configFilePath = buildPath(dirs.configDir, "settings.conf"); | |
1188 | - if (exists(configFilePath)) { | |
1189 | - scope parser = new ConfigParser(); | |
1190 | - parser.read(configFilePath); | |
1191 | - config.baseFolder = parser.get("output", "base_folder", | |
1192 | - userDirs.pictureDir); | |
1193 | - } else { | |
1194 | - config.baseFolder = userDirs.pictureDir; | |
1195 | - } | |
1196 | - } else { | |
1197 | - // Set default values | |
1198 | - config.baseFolder = userDirs.pictureDir; | |
1199 | - } | |
1200 | - infof("Output Directory = %s", config.baseFolder); | |
1201 | - infof("Local Data Directory = %s", dirs.dataDir); | |
1202 | - | |
1203 | - const idFilePath = buildPath(dirs.dataDir, ".phpsessid"); | |
1204 | - | |
1205 | - if (!exists(idFilePath)) | |
1206 | - { | |
1207 | - resetSessionID(); | |
1208 | - } | |
1209 | - | |
1210 | - const sessionid = File(idFilePath).readln().strip(); | |
1211 | - | |
1212 | - if (null is sessionid) | |
1213 | - { | |
1214 | - scope newID = askForSessionID(); | |
1215 | - storeSessionID(newID, idFilePath); | |
1216 | - config.client = new Client(newID); | |
1217 | - } | |
1218 | - else | |
1219 | - { | |
1220 | - config.client = new Client(sessionid); | |
1221 | - } | |
1222 | - | |
1223 | - return config; | |
1224 | -} | |
1225 | - | |
1226 | 1101 | /* |
1227 | 1102 | * -------------------------------------------------------------------------- |
1228 | 1103 | * Main |
@@ -1236,7 +1111,7 @@ int | ||
1236 | 1111 | main(string[] args) |
1237 | 1112 | { |
1238 | 1113 | import std.stdio : stderr, writeln, writefln; |
1239 | - import std.experimental.logger : stdThreadLocalLog; | |
1114 | + import std.experimental.logger : stdThreadLocalLog, infof; | |
1240 | 1115 | import logger; |
1241 | 1116 | |
1242 | 1117 | version(appimage) { |
@@ -1302,6 +1177,10 @@ version (GMagick_Dynamic) { | ||
1302 | 1177 | logLibGMVersion(); |
1303 | 1178 | |
1304 | 1179 | Config config = loadConfig(); |
1180 | + debug { pragma(msg, "TODO: Remove Config.client"); } | |
1181 | + config.client = new Client(config.sessionid); | |
1182 | + | |
1183 | + infof("Output Directory = %s", config.outputDirectory); | |
1305 | 1184 | |
1306 | 1185 | return (*func)(args, config); |
1307 | 1186 | } |
@@ -0,0 +1,166 @@ | ||
1 | +/* | |
2 | + * pixiv_down - CLI-based downloading tool for https://www.pixiv.net. | |
3 | + * Copyright (C) 2023 Mio | |
4 | + * | |
5 | + * This program is free software: you can redistribute it and/or modify | |
6 | + * it under the terms of the GNU General Public License as published by | |
7 | + * the Free Software Foundation, version 3 of the License. | |
8 | + * | |
9 | + * This program is distributed in the hope that it will be useful, | |
10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | + * GNU General Public License for more details. | |
13 | + * | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
16 | + */ | |
17 | +module configuration; | |
18 | + | |
19 | +private enum ProjectQualifier = null; | |
20 | +private enum ProjectOrg = "YumeNeru Software"; | |
21 | +private enum ProjectName = "pixiv_down"; | |
22 | +private enum PHPSessionIDFileName = ".phpsessid"; | |
23 | + | |
24 | +/// pixiv_down configuration. | |
25 | +/// | |
26 | +/// Use `configuration.loadConfig` to load the correct values. | |
27 | +struct Config | |
28 | +{ | |
29 | + /// The directory where content is downloaded to. | |
30 | + string outputDirectory; | |
31 | + /// The PHPSESSID of the current account. | |
32 | + string sessionid; | |
33 | + | |
34 | + import pixivd : Client; // TODO: Remove/Replace | |
35 | + Client client; | |
36 | +} | |
37 | + | |
38 | +/// Load the configuration for pixiv_down. | |
39 | +Config loadConfig() | |
40 | +{ | |
41 | + return Config(fetchOutputDirectory(), fetchSessionID()); | |
42 | +} | |
43 | + | |
44 | +/// Prompt to reset the PHPSESSID. | |
45 | +/// | |
46 | +/// This will store the value in the appropriate location so it | |
47 | +/// can be read in the future. | |
48 | +public void resetSessionID() @trusted /* @safe -> getProjectDirectories */ | |
49 | +{ | |
50 | + import std.path : buildPath; | |
51 | + import directories : getProjectDirectories; | |
52 | + | |
53 | + const projectDirs = getProjectDirectories(ProjectQualifier, ProjectOrg, ProjectName); | |
54 | + const id = promptForSessionID(); | |
55 | + | |
56 | + storeSessionID(id, buildPath(projectDirs.dataDir, PHPSessionIDFileName)); | |
57 | +} | |
58 | + | |
59 | +private string fetchOutputDirectory() /* @safe */ | |
60 | +{ | |
61 | + import std.file : exists; | |
62 | + import std.path : buildPath; | |
63 | + import std.string : empty; | |
64 | + | |
65 | + import configparser : ConfigParser; | |
66 | + import directories : getProjectDirectories, getUserDirectories; | |
67 | + | |
68 | + const projectDirs = getProjectDirectories(ProjectQualifier, ProjectOrg, ProjectName); | |
69 | + const userDirs = getUserDirectories(); | |
70 | + | |
71 | + if (exists(projectDirs.configDir)) | |
72 | + { | |
73 | + const configFile = buildPath(projectDirs.configDir, "settings.conf"); | |
74 | + if (exists(configFile)) { | |
75 | + scope parser = new ConfigParser(); | |
76 | + parser.read(configFile); | |
77 | + | |
78 | + // COMPAT FOR <0.2 (REMOVE @ 0.3) | |
79 | + const outputDirectory = parser.get("output", "directory", ""); | |
80 | + if (empty(outputDirectory)) | |
81 | + { | |
82 | + import std.stdio : stderr; | |
83 | + stderr.writeln("Warning: output.base_folder configuration option is being removed."); | |
84 | + stderr.writeln(" Please use output.directory instead."); | |
85 | + stderr.writeln("From:"); | |
86 | + stderr.writeln("\t[output]\n\tbase_folder = /my/path"); | |
87 | + stderr.writeln("To:"); | |
88 | + stderr.writeln("\t[output]\n\tdirectory = /my/path"); | |
89 | + | |
90 | + | |
91 | + const baseFolder = parser.get("output", "base_folder", userDirs.pictureDir); | |
92 | + //parser.set("output", "directory", baseFolder); | |
93 | + // TODO: Write the new config file when `.write` is implemented. | |
94 | + return baseFolder; | |
95 | + } | |
96 | + return outputDirectory; | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + return userDirs.pictureDir; | |
101 | +} | |
102 | + | |
103 | +private string promptForSessionID() @trusted | |
104 | +{ | |
105 | + import std.stdio : readln, stderr, write; | |
106 | + import std.string : empty, strip; | |
107 | + | |
108 | + import core.stdc.stdlib : exit; | |
109 | + | |
110 | + stderr.writeln("========== NOTICE =========="); | |
111 | + stderr.writeln("No PHPSESSID found.\n"); | |
112 | + stderr.writeln("Please see the below webpage for instructions to find your PHPSESSID"); | |
113 | + stderr.writeln("https://codeberg.org/supercell/pixivd/src/branch/trunk/PHPSESSID"); | |
114 | + stderr.writeln("============================"); | |
115 | + | |
116 | + write("\nPlease enter your PHPSESSID (leave blank to exit): "); | |
117 | + | |
118 | + const sessionid = readln.strip; | |
119 | + | |
120 | + if (empty(sessionid)) | |
121 | + { | |
122 | + exit(0); | |
123 | + } | |
124 | + | |
125 | + return sessionid; | |
126 | +} | |
127 | + | |
128 | +pragma(inline, true) | |
129 | +private void storeSessionID(const(char)[] sessionid, const(char)[] path) @safe | |
130 | +{ | |
131 | + import std.stdio : File; | |
132 | + | |
133 | + File(path, "w+").writeln(sessionid); | |
134 | +} | |
135 | + | |
136 | +private string fetchSessionID() /* @safe */ | |
137 | +{ | |
138 | + import std.file : exists, mkdirRecurse; | |
139 | + import std.path : buildPath; | |
140 | + import std.stdio : File; | |
141 | + import std.string : empty, strip; | |
142 | + | |
143 | + import directories : getProjectDirectories; | |
144 | + | |
145 | + const projectDirs = getProjectDirectories(ProjectQualifier, ProjectOrg, ProjectName); | |
146 | + const sessidPath = buildPath(projectDirs.dataDir, PHPSessionIDFileName); | |
147 | + | |
148 | + if (false == exists(sessidPath)) | |
149 | + { | |
150 | + mkdirRecurse(projectDirs.dataDir); | |
151 | + const newID = promptForSessionID(); | |
152 | + storeSessionID(newID, sessidPath); | |
153 | + return newID; | |
154 | + } | |
155 | + | |
156 | + const sessionid = File(sessidPath).readln.strip; | |
157 | + | |
158 | + if (empty(sessionid)) | |
159 | + { | |
160 | + const newID = promptForSessionID(); | |
161 | + storeSessionID(newID, sessidPath); | |
162 | + return newID; | |
163 | + } | |
164 | + | |
165 | + return sessionid; | |
166 | +} |