pixivflow 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/README_EN.md +4 -0
- package/dist/commands/TagsCommand.d.ts +25 -0
- package/dist/commands/TagsCommand.d.ts.map +1 -0
- package/dist/commands/TagsCommand.js +176 -0
- package/dist/commands/TagsCommand.js.map +1 -0
- package/dist/commands/TopicCommand.d.ts +19 -0
- package/dist/commands/TopicCommand.d.ts.map +1 -0
- package/dist/commands/TopicCommand.js +113 -0
- package/dist/commands/TopicCommand.js.map +1 -0
- package/dist/commands/index.d.ts +3 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +7 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/config/types.d.ts +45 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +40 -3
- package/dist/config/validation.js.map +1 -1
- package/dist/download/DownloadManager.d.ts.map +1 -1
- package/dist/download/DownloadManager.js +5 -2
- package/dist/download/DownloadManager.js.map +1 -1
- package/dist/download/handlers/IllustrationTargetHandler.d.ts +5 -1
- package/dist/download/handlers/IllustrationTargetHandler.d.ts.map +1 -1
- package/dist/download/handlers/IllustrationTargetHandler.js +26 -1
- package/dist/download/handlers/IllustrationTargetHandler.js.map +1 -1
- package/dist/download/handlers/NovelTargetHandler.d.ts +4 -1
- package/dist/download/handlers/NovelTargetHandler.d.ts.map +1 -1
- package/dist/download/handlers/NovelTargetHandler.js +23 -1
- package/dist/download/handlers/NovelTargetHandler.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/pixiv/PixivClient.d.ts +10 -1
- package/dist/pixiv/PixivClient.d.ts.map +1 -1
- package/dist/pixiv/PixivClient.js +25 -0
- package/dist/pixiv/PixivClient.js.map +1 -1
- package/dist/pixiv/client/SearchService.d.ts +2 -1
- package/dist/pixiv/client/SearchService.d.ts.map +1 -1
- package/dist/pixiv/client/SearchService.js +10 -0
- package/dist/pixiv/client/SearchService.js.map +1 -1
- package/dist/pixiv/types.d.ts +15 -0
- package/dist/pixiv/types.d.ts.map +1 -1
- package/dist/storage/Database.d.ts +2 -0
- package/dist/storage/Database.d.ts.map +1 -1
- package/dist/storage/Database.js +4 -0
- package/dist/storage/Database.js.map +1 -1
- package/dist/tags/TagDiscoveryService.d.ts +22 -0
- package/dist/tags/TagDiscoveryService.d.ts.map +1 -0
- package/dist/tags/TagDiscoveryService.js +137 -0
- package/dist/tags/TagDiscoveryService.js.map +1 -0
- package/dist/tags/TagDiscoveryStore.d.ts +21 -0
- package/dist/tags/TagDiscoveryStore.d.ts.map +1 -0
- package/dist/tags/TagDiscoveryStore.js +67 -0
- package/dist/tags/TagDiscoveryStore.js.map +1 -0
- package/dist/tags/TagPlanApplier.d.ts +22 -0
- package/dist/tags/TagPlanApplier.d.ts.map +1 -0
- package/dist/tags/TagPlanApplier.js +86 -0
- package/dist/tags/TagPlanApplier.js.map +1 -0
- package/dist/tags/types.d.ts +36 -0
- package/dist/tags/types.d.ts.map +1 -0
- package/dist/tags/types.js +3 -0
- package/dist/tags/types.js.map +1 -0
- package/dist/topic/TopicCache.d.ts +23 -0
- package/dist/topic/TopicCache.d.ts.map +1 -0
- package/dist/topic/TopicCache.js +78 -0
- package/dist/topic/TopicCache.js.map +1 -0
- package/dist/topic/TopicPipeline.d.ts +49 -0
- package/dist/topic/TopicPipeline.d.ts.map +1 -0
- package/dist/topic/TopicPipeline.js +224 -0
- package/dist/topic/TopicPipeline.js.map +1 -0
- package/dist/topic/TopicResolver.d.ts +31 -0
- package/dist/topic/TopicResolver.d.ts.map +1 -0
- package/dist/topic/TopicResolver.js +162 -0
- package/dist/topic/TopicResolver.js.map +1 -0
- package/dist/topic/TopicTagScorer.d.ts +13 -0
- package/dist/topic/TopicTagScorer.d.ts.map +1 -0
- package/dist/topic/TopicTagScorer.js +109 -0
- package/dist/topic/TopicTagScorer.js.map +1 -0
- package/dist/topic/createTopicPipeline.d.ts +12 -0
- package/dist/topic/createTopicPipeline.d.ts.map +1 -0
- package/dist/topic/createTopicPipeline.js +31 -0
- package/dist/topic/createTopicPipeline.js.map +1 -0
- package/dist/topic/types.d.ts +93 -0
- package/dist/topic/types.d.ts.map +1 -0
- package/dist/topic/types.js +8 -0
- package/dist/topic/types.js.map +1 -0
- package/dist/webui/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -160,6 +160,12 @@ outbox 清单保留在 SQLite 数据库同级的 `delivery-outbox/`;下一次
|
|
|
160
160
|
| `pixivflow config` | 配置管理(查看 / 编辑 / 备份 / 恢复) |
|
|
161
161
|
| `pixivflow status` | 下载统计与最近记录 |
|
|
162
162
|
| `pixivflow health` | 健康检查:配置、目录可写性、连通性 |
|
|
163
|
+
| `pixivflow tags discover <词>` | 发现相关 Tag(Pixiv 联想 + 作品标签共现),只列候选不改配置 |
|
|
164
|
+
| `pixivflow tags apply <清单> --target <id> --select <tag1,tag2>` | 人工确认后把所选 Tag 原子写入配置并触发热重载 |
|
|
165
|
+
| `pixivflow topic resolve <主题>` | 查看自动推导出的相关 Tag 空间(`--type illustration\|novel`、`--refresh`) |
|
|
166
|
+
| `pixivflow topic test <主题> --date YESTERDAY` | dry-run 预览某天的候选与 Top N,不下载 |
|
|
167
|
+
|
|
168
|
+
`tags discover` 会调用 Pixiv 标签联想接口,并抽样最近插画 / 小说统计共同出现的标签,结果缓存 7 天;它**不会**改动任何下载计划。确认候选后用 `tags apply` 显式选择,应用前会整份校验配置、自动备份并原子替换,运行中的 scheduler 经配置热重载生效。
|
|
163
169
|
|
|
164
170
|
其他用法见 [CLI_MIGRATION_SUMMARY.md](docs/CLI_MIGRATION_SUMMARY.md)。
|
|
165
171
|
|
package/README_EN.md
CHANGED
|
@@ -141,6 +141,10 @@ Interactive configuration wizard: `pixivflow setup`.
|
|
|
141
141
|
| `pixivflow config` | Manage config (view / edit / backup / restore) |
|
|
142
142
|
| `pixivflow status` | Download stats and recent records |
|
|
143
143
|
| `pixivflow health` | Health check: config, directories, connectivity |
|
|
144
|
+
| `pixivflow tags discover <seed>` | Discover related tags (Pixiv autocomplete + tag co-occurrence); lists candidates only |
|
|
145
|
+
| `pixivflow tags apply <manifest> --target <id> --select <tag1,tag2>` | Atomically write chosen tags into config after manual confirmation, then hot-reload |
|
|
146
|
+
|
|
147
|
+
`tags discover` calls the Pixiv autocomplete endpoint and samples recent illustrations/novels to count co-occurring tags, caching results for 7 days; it **never** changes active plans. After reviewing candidates, run `tags apply` to explicitly select tags: it validates the whole config, writes a backup and atomically replaces the file so a running scheduler hot-reloads it.
|
|
144
148
|
|
|
145
149
|
More commands in [CLI_MIGRATION_SUMMARY.md](docs/CLI_MIGRATION_SUMMARY.md).
|
|
146
150
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseCommand } from './Command';
|
|
2
|
+
import { CommandCategory } from './metadata';
|
|
3
|
+
import type { CommandArgs, CommandContext, CommandResult } from './types';
|
|
4
|
+
export declare class TagsCommand extends BaseCommand {
|
|
5
|
+
readonly name = "tags";
|
|
6
|
+
readonly description = "Discover related Pixiv tags, then explicitly apply selected tags";
|
|
7
|
+
readonly aliases: string[];
|
|
8
|
+
readonly metadata: {
|
|
9
|
+
category: CommandCategory;
|
|
10
|
+
requiresAuth: boolean;
|
|
11
|
+
longRunning: boolean;
|
|
12
|
+
};
|
|
13
|
+
execute(context: CommandContext, args: CommandArgs): Promise<CommandResult>;
|
|
14
|
+
private discover;
|
|
15
|
+
private apply;
|
|
16
|
+
private createStore;
|
|
17
|
+
private parseContentTypes;
|
|
18
|
+
private printManifest;
|
|
19
|
+
private integerOption;
|
|
20
|
+
private numberOption;
|
|
21
|
+
private stringOption;
|
|
22
|
+
private booleanOption;
|
|
23
|
+
getUsage(): string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=TagsCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagsCommand.d.ts","sourceRoot":"","sources":["../../src/commands/TagsCommand.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAS1E,qBAAa,WAAY,SAAQ,WAAW;IAC1C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,sEAAsE;IAC1F,QAAQ,CAAC,OAAO,WAAW;IAC3B,QAAQ,CAAC,QAAQ;;;;MAIf;IAEI,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;YAenE,QAAQ;YAgDR,KAAK;IAkCnB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IAIrB,QAAQ,IAAI,MAAM;CAgBnB"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TagsCommand = void 0;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const Command_1 = require("./Command");
|
|
6
|
+
const metadata_1 = require("./metadata");
|
|
7
|
+
const Database_1 = require("../storage/Database");
|
|
8
|
+
const AuthClient_1 = require("../pixiv/AuthClient");
|
|
9
|
+
const PixivClient_1 = require("../pixiv/PixivClient");
|
|
10
|
+
const TagDiscoveryService_1 = require("../tags/TagDiscoveryService");
|
|
11
|
+
const TagDiscoveryStore_1 = require("../tags/TagDiscoveryStore");
|
|
12
|
+
const TagPlanApplier_1 = require("../tags/TagPlanApplier");
|
|
13
|
+
class TagsCommand extends Command_1.BaseCommand {
|
|
14
|
+
name = 'tags';
|
|
15
|
+
description = 'Discover related Pixiv tags, then explicitly apply selected tags';
|
|
16
|
+
aliases = ['tag'];
|
|
17
|
+
metadata = {
|
|
18
|
+
category: metadata_1.CommandCategory.CONFIGURATION,
|
|
19
|
+
requiresAuth: true,
|
|
20
|
+
longRunning: false,
|
|
21
|
+
};
|
|
22
|
+
async execute(context, args) {
|
|
23
|
+
const subcommand = args.positional[0];
|
|
24
|
+
try {
|
|
25
|
+
if (subcommand === 'discover')
|
|
26
|
+
return await this.discover(context, args);
|
|
27
|
+
if (subcommand === 'apply')
|
|
28
|
+
return await this.apply(context, args);
|
|
29
|
+
console.error(`\nUnknown tags subcommand: ${subcommand ? `'${subcommand}'` : '(none)'}`);
|
|
30
|
+
console.error(`\nUsage:\n${this.getUsage()}\n`);
|
|
31
|
+
return this.failure(this.getUsage());
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
console.error(`\n✗ ${message}\n`);
|
|
36
|
+
return this.failure(message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async discover(context, args) {
|
|
40
|
+
const seed = args.positional.slice(1).join(' ').trim();
|
|
41
|
+
if (!seed) {
|
|
42
|
+
console.error('\nUsage: pixivflow tags discover <seed> [options]\n');
|
|
43
|
+
return this.failure('Missing seed tag for discovery');
|
|
44
|
+
}
|
|
45
|
+
const contentTypes = this.parseContentTypes(args.options.type);
|
|
46
|
+
const sampleSize = this.integerOption(args.options.sample, 60, 'sample');
|
|
47
|
+
const limit = this.integerOption(args.options.limit, 20, 'limit');
|
|
48
|
+
const cacheDays = this.numberOption(args.options['cache-days'], 7, 'cache-days');
|
|
49
|
+
const ttlMs = Math.round(cacheDays * 24 * 60 * 60_000);
|
|
50
|
+
const cacheKey = { seed, contentTypes, sampleSize, limit };
|
|
51
|
+
const store = this.createStore(context);
|
|
52
|
+
if (!this.booleanOption(args.options.refresh)) {
|
|
53
|
+
const cached = await store.loadFresh(cacheKey);
|
|
54
|
+
if (cached) {
|
|
55
|
+
this.printManifest(cached.manifest, cached.path, true, this.booleanOption(args.options.json));
|
|
56
|
+
return this.success('Fresh tag discovery cache reused', cached);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const database = new Database_1.Database(context.config.storage.databasePath);
|
|
60
|
+
try {
|
|
61
|
+
database.migrate();
|
|
62
|
+
const auth = new AuthClient_1.PixivAuth(context.config.pixiv, context.config.network, database, context.configPath);
|
|
63
|
+
const client = new PixivClient_1.PixivClient(auth, context.config);
|
|
64
|
+
const service = new TagDiscoveryService_1.TagDiscoveryService(client);
|
|
65
|
+
const manifest = await service.discover(seed, {
|
|
66
|
+
contentTypes,
|
|
67
|
+
sampleSize,
|
|
68
|
+
limit,
|
|
69
|
+
ttlMs,
|
|
70
|
+
});
|
|
71
|
+
const path = await store.save(cacheKey, manifest);
|
|
72
|
+
this.printManifest(manifest, path, false, this.booleanOption(args.options.json));
|
|
73
|
+
return this.success('Tag discovery completed', { manifest, path, cached: false });
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
database.close();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async apply(context, args) {
|
|
80
|
+
const manifestPath = args.positional[1];
|
|
81
|
+
const targetId = this.stringOption(args.options.target);
|
|
82
|
+
const selected = this.stringOption(args.options.select)
|
|
83
|
+
?.split(',')
|
|
84
|
+
.map((value) => value.trim())
|
|
85
|
+
.filter(Boolean) ?? [];
|
|
86
|
+
const mode = this.stringOption(args.options.mode) ?? 'append';
|
|
87
|
+
if (!manifestPath || !targetId || selected.length === 0) {
|
|
88
|
+
console.error('\nUsage: pixivflow tags apply <manifest.json> --target <id> --select <tag1,tag2> [--mode append|replace]\n');
|
|
89
|
+
return this.failure('apply requires a manifest path, --target and --select');
|
|
90
|
+
}
|
|
91
|
+
if (mode !== 'append' && mode !== 'replace') {
|
|
92
|
+
console.error('\n--mode must be append or replace\n');
|
|
93
|
+
return this.failure('--mode must be append or replace');
|
|
94
|
+
}
|
|
95
|
+
const store = this.createStore(context);
|
|
96
|
+
const manifest = await store.read((0, node_path_1.resolve)(manifestPath));
|
|
97
|
+
const result = await new TagPlanApplier_1.TagPlanApplier().apply(context.configPath, manifest, {
|
|
98
|
+
targetId,
|
|
99
|
+
selectedTags: selected,
|
|
100
|
+
mode,
|
|
101
|
+
});
|
|
102
|
+
console.log(`\n✓ Target ${result.targetId} updated atomically`);
|
|
103
|
+
console.log(` Previous: ${result.previousTag ?? '(empty)'}`);
|
|
104
|
+
console.log(` Current: ${result.tag}`);
|
|
105
|
+
console.log(` Backup: ${result.backupPath}`);
|
|
106
|
+
console.log(' Scheduler: the config watcher will hot-reload this validated snapshot\n');
|
|
107
|
+
return this.success('Selected tags applied and ready for hot reload', result);
|
|
108
|
+
}
|
|
109
|
+
createStore(context) {
|
|
110
|
+
const databasePath = (0, node_path_1.resolve)(context.config.storage.databasePath);
|
|
111
|
+
return new TagDiscoveryStore_1.TagDiscoveryStore((0, node_path_1.resolve)((0, node_path_1.dirname)(databasePath), 'tag-discovery'));
|
|
112
|
+
}
|
|
113
|
+
parseContentTypes(value) {
|
|
114
|
+
const type = this.stringOption(value) ?? 'all';
|
|
115
|
+
if (type === 'all')
|
|
116
|
+
return ['illustration', 'novel'];
|
|
117
|
+
if (type === 'illustration' || type === 'novel')
|
|
118
|
+
return [type];
|
|
119
|
+
throw new Error('--type must be all, illustration or novel');
|
|
120
|
+
}
|
|
121
|
+
printManifest(manifest, path, cached, json) {
|
|
122
|
+
if (json) {
|
|
123
|
+
console.log(JSON.stringify({ cached, path, ...manifest }, null, 2));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
console.log(`\nTag suggestions for: ${manifest.seed}${cached ? ' (cache)' : ''}`);
|
|
127
|
+
console.log(`Sampled: ${manifest.sampledWorks.illustration} illustrations, ${manifest.sampledWorks.novel} novels`);
|
|
128
|
+
console.log('');
|
|
129
|
+
manifest.candidates.forEach((candidate, index) => {
|
|
130
|
+
const translation = candidate.translatedName ? ` / ${candidate.translatedName}` : '';
|
|
131
|
+
const occurrences = candidate.occurrences.illustration + candidate.occurrences.novel;
|
|
132
|
+
console.log(`${String(index + 1).padStart(2)}. ${candidate.name}${translation} score=${candidate.score.toFixed(4)} works=${occurrences} source=${candidate.sources.join('+')}`);
|
|
133
|
+
});
|
|
134
|
+
console.log(`\nManifest: ${path}`);
|
|
135
|
+
console.log(`Apply selected candidates only:`);
|
|
136
|
+
console.log(` pixivflow tags apply "${path}" --target <target-id> --select "tag1,tag2"\n`);
|
|
137
|
+
}
|
|
138
|
+
integerOption(value, fallback, name) {
|
|
139
|
+
const number = this.numberOption(value, fallback, name);
|
|
140
|
+
if (!Number.isInteger(number))
|
|
141
|
+
throw new Error(`--${name} must be an integer`);
|
|
142
|
+
return number;
|
|
143
|
+
}
|
|
144
|
+
numberOption(value, fallback, name) {
|
|
145
|
+
if (value === undefined)
|
|
146
|
+
return fallback;
|
|
147
|
+
const number = Number(value);
|
|
148
|
+
if (!Number.isFinite(number))
|
|
149
|
+
throw new Error(`--${name} must be a number`);
|
|
150
|
+
return number;
|
|
151
|
+
}
|
|
152
|
+
stringOption(value) {
|
|
153
|
+
return typeof value === 'string' ? value.trim() : undefined;
|
|
154
|
+
}
|
|
155
|
+
booleanOption(value) {
|
|
156
|
+
return value === true || (typeof value === 'string' && ['true', '1', 'yes'].includes(value.toLowerCase()));
|
|
157
|
+
}
|
|
158
|
+
getUsage() {
|
|
159
|
+
return `tags discover <seed> [options]
|
|
160
|
+
--type all|illustration|novel Content to sample (default: all)
|
|
161
|
+
--sample <1-200> Maximum works sampled per type (default: 60)
|
|
162
|
+
--limit <1-100> Candidate count (default: 20)
|
|
163
|
+
--cache-days <days> Cache lifetime (default: 7)
|
|
164
|
+
--refresh Ignore a fresh cache
|
|
165
|
+
--json Machine-readable output
|
|
166
|
+
|
|
167
|
+
tags apply <manifest.json> --target <id> --select <tag1,tag2> [options]
|
|
168
|
+
--mode append|replace Keep the current seed or replace it (default: append)
|
|
169
|
+
|
|
170
|
+
Discovery never changes active plans. Apply accepts only names from the saved
|
|
171
|
+
manifest, validates the complete config, writes a backup, then atomically
|
|
172
|
+
replaces the config so a running scheduler can hot-reload it.`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.TagsCommand = TagsCommand;
|
|
176
|
+
//# sourceMappingURL=TagsCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagsCommand.js","sourceRoot":"","sources":["../../src/commands/TagsCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseCommand } from './Command';
|
|
2
|
+
import { CommandCategory } from './metadata';
|
|
3
|
+
import type { CommandArgs, CommandContext, CommandResult } from './types';
|
|
4
|
+
export declare class TopicCommand extends BaseCommand {
|
|
5
|
+
readonly name = "topic";
|
|
6
|
+
readonly description = "Resolve a semantic topic into related tags (resolve) or dry-run a day selection (test)";
|
|
7
|
+
readonly aliases: string[];
|
|
8
|
+
readonly metadata: {
|
|
9
|
+
category: CommandCategory;
|
|
10
|
+
requiresAuth: boolean;
|
|
11
|
+
longRunning: boolean;
|
|
12
|
+
};
|
|
13
|
+
execute(context: CommandContext, args: CommandArgs): Promise<CommandResult>;
|
|
14
|
+
private withClient;
|
|
15
|
+
private resolve;
|
|
16
|
+
private test;
|
|
17
|
+
getUsage(): string;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=TopicCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TopicCommand.d.ts","sourceRoot":"","sources":["../../src/commands/TopicCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAU1E,qBAAa,YAAa,SAAQ,WAAW;IAC3C,QAAQ,CAAC,IAAI,WAAW;IACxB,QAAQ,CAAC,WAAW,4FAA4F;IAChH,QAAQ,CAAC,OAAO,WAAc;IAC9B,QAAQ,CAAC,QAAQ;;;;MAIf;IAEI,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;YAgBnE,UAAU;YAYV,OAAO;YAyBP,IAAI;IA6BlB,QAAQ,IAAI,MAAM;CASnB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TopicCommand = void 0;
|
|
4
|
+
const Command_1 = require("./Command");
|
|
5
|
+
const metadata_1 = require("./metadata");
|
|
6
|
+
const Database_1 = require("../storage/Database");
|
|
7
|
+
const AuthClient_1 = require("../pixiv/AuthClient");
|
|
8
|
+
const PixivClient_1 = require("../pixiv/PixivClient");
|
|
9
|
+
const createTopicPipeline_1 = require("../topic/createTopicPipeline");
|
|
10
|
+
const TopicResolver_1 = require("../topic/TopicResolver");
|
|
11
|
+
const TopicCache_1 = require("../topic/TopicCache");
|
|
12
|
+
const pixiv_date_utils_1 = require("../utils/pixiv-date-utils");
|
|
13
|
+
class TopicCommand extends Command_1.BaseCommand {
|
|
14
|
+
name = 'topic';
|
|
15
|
+
description = 'Resolve a semantic topic into related tags (resolve) or dry-run a day selection (test)';
|
|
16
|
+
aliases = ['topics'];
|
|
17
|
+
metadata = {
|
|
18
|
+
category: metadata_1.CommandCategory.DOWNLOAD,
|
|
19
|
+
requiresAuth: true,
|
|
20
|
+
longRunning: false,
|
|
21
|
+
};
|
|
22
|
+
async execute(context, args) {
|
|
23
|
+
const subcommand = args.positional[0];
|
|
24
|
+
const topic = args.positional.slice(1).join(' ').trim();
|
|
25
|
+
try {
|
|
26
|
+
if (subcommand === 'resolve')
|
|
27
|
+
return await this.resolve(context, args, topic);
|
|
28
|
+
if (subcommand === 'test')
|
|
29
|
+
return await this.test(context, args, topic);
|
|
30
|
+
console.error(`\nUnknown topic subcommand: ${subcommand ? `'${subcommand}'` : '(none)'}`);
|
|
31
|
+
console.error(`\nUsage:\n${this.getUsage()}\n`);
|
|
32
|
+
return this.failure(this.getUsage());
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
console.error(`\n✗ ${message}\n`);
|
|
37
|
+
return this.failure(message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async withClient(context, fn) {
|
|
41
|
+
const database = new Database_1.Database(context.config.storage.databasePath);
|
|
42
|
+
try {
|
|
43
|
+
database.migrate();
|
|
44
|
+
const auth = new AuthClient_1.PixivAuth(context.config.pixiv, context.config.network, database, context.configPath);
|
|
45
|
+
const client = new PixivClient_1.PixivClient(auth, context.config);
|
|
46
|
+
return await fn({ client, database });
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
database.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async resolve(context, _args, topic) {
|
|
53
|
+
if (!topic) {
|
|
54
|
+
console.error('\nUsage: pixivflow topic resolve <topic> [--type illustration|novel|all] [--refresh]\n');
|
|
55
|
+
return this.failure('Missing topic for resolve');
|
|
56
|
+
}
|
|
57
|
+
const type = (String(_args.options.type ?? 'all'));
|
|
58
|
+
const refresh = Boolean(_args.options.refresh);
|
|
59
|
+
const types = type === 'all' ? ['illustration', 'novel'] : [type];
|
|
60
|
+
return this.withClient(context, async ({ client, database }) => {
|
|
61
|
+
const cache = TopicCache_1.TopicCache.forDatabase(database.getDatabasePath());
|
|
62
|
+
for (const contentType of types) {
|
|
63
|
+
const resolver = new TopicResolver_1.TopicResolver(client, cache, context.config.download?.requestDelay ?? 500);
|
|
64
|
+
const { space, fromCache, degraded } = await resolver.resolve(topic, contentType, { refresh });
|
|
65
|
+
console.log(`\nTopic: ${topic} (${contentType}) ${fromCache ? (degraded ? '· stale cache' : '· cache') : '· fresh'}`);
|
|
66
|
+
console.log('Tag'.padEnd(28) + 'Score'.padStart(7) + 'Occ'.padStart(6) + 'Spec'.padStart(7));
|
|
67
|
+
for (const tag of space.tags) {
|
|
68
|
+
const name = (tag.name + (tag.translatedName ? ` / ${tag.translatedName}` : '')).slice(0, 27);
|
|
69
|
+
console.log(name.padEnd(28) + tag.score.toFixed(2).padStart(7) + String(tag.occurrences).padStart(6) + tag.specificity.toFixed(2).padStart(7));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return this.success('Topic resolved', { topic });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async test(context, args, topic) {
|
|
76
|
+
if (!topic) {
|
|
77
|
+
console.error('\nUsage: pixivflow topic test <topic> [--type illustration|novel|all] [--date YESTERDAY|YYYY-MM-DD] [--limit N] [--refresh]\n');
|
|
78
|
+
return this.failure('Missing topic for test');
|
|
79
|
+
}
|
|
80
|
+
const type = (String(args.options.type ?? 'all'));
|
|
81
|
+
const types = type === 'all' ? ['illustration', 'novel'] : [type];
|
|
82
|
+
const dateRaw = String(args.options.date ?? 'YESTERDAY');
|
|
83
|
+
const day = dateRaw === 'TODAY' ? (0, pixiv_date_utils_1.getTodayDate)() : !dateRaw || dateRaw === 'YESTERDAY' ? (0, pixiv_date_utils_1.getYesterdayDate)() : dateRaw;
|
|
84
|
+
const limit = Number(args.options.limit ?? 5);
|
|
85
|
+
const refresh = Boolean(args.options.refresh);
|
|
86
|
+
return this.withClient(context, async ({ client, database }) => {
|
|
87
|
+
const factory = (0, createTopicPipeline_1.createTopicPipelineFactory)(client, database.getDatabasePath(), context.config.download?.requestDelay ?? 500);
|
|
88
|
+
for (const contentType of types) {
|
|
89
|
+
const target = { type: contentType, mode: 'topic', topic, limit, topicDiscovery: { refresh } };
|
|
90
|
+
const pipeline = factory();
|
|
91
|
+
const { works, selection } = await pipeline.selectWorks(target, contentType, day, limit, { refresh }, {});
|
|
92
|
+
console.log(`\n=== ${contentType} topic "${topic}" day ${day} ===`);
|
|
93
|
+
console.log(`resolvedTags=${selection.resolvedTagCount} raw=${selection.rawCount} deduped=${selection.dedupedCount} accepted=${selection.acceptedCount} selected=${works.length}`);
|
|
94
|
+
selection.selected.forEach((c, i) => {
|
|
95
|
+
console.log(` #${i + 1} id=${c.id} pop=${c.popularity.toFixed(1)} meta=${c.metadataScore.toFixed(2)} ${c.title}`);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
console.log('\n(dry-run: nothing downloaded)');
|
|
99
|
+
return this.success('Topic dry-run completed', { topic, day });
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
getUsage() {
|
|
103
|
+
return [
|
|
104
|
+
'topic resolve <topic> [--type all|illustration|novel] [--refresh]',
|
|
105
|
+
' Show the Pixiv-derived related tag space for a topic (cached).',
|
|
106
|
+
'',
|
|
107
|
+
'topic test <topic> [--type all|illustration|novel] [--date YESTERDAY|YYYY-MM-DD] [--limit N] [--refresh]',
|
|
108
|
+
' Dry-run a daily selection: resolved tags, candidate counts, Top N (no downloads).',
|
|
109
|
+
].join('\n');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.TopicCommand = TopicCommand;
|
|
113
|
+
//# sourceMappingURL=TopicCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TopicCommand.js","sourceRoot":"","sources":["../../src/commands/TopicCommand.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ import { MonitorCommand } from './MonitorCommand';
|
|
|
22
22
|
import { SetupCommand } from './SetupCommand';
|
|
23
23
|
import { DirsCommand } from './DirsCommand';
|
|
24
24
|
import { VersionCommand } from './VersionCommand';
|
|
25
|
+
import { TagsCommand } from './TagsCommand';
|
|
26
|
+
import { TopicCommand } from './TopicCommand';
|
|
25
27
|
/**
|
|
26
28
|
* Create and register all commands
|
|
27
29
|
*/
|
|
@@ -29,5 +31,5 @@ export declare function registerAllCommands(registry: CommandRegistry): void;
|
|
|
29
31
|
/**
|
|
30
32
|
* Export all command classes
|
|
31
33
|
*/
|
|
32
|
-
export { HelpCommand, LoginCommand, LoginHeadlessCommand, RefreshCommand, DownloadCommand, RandomDownloadCommand, SchedulerCommand, MigrateConfigCommand, NormalizeCommand, WebUICommand, HealthCommand, StatusCommand, LogsCommand, ConfigCommand, BackupCommand, MaintainCommand, MonitorCommand, SetupCommand, DirsCommand, VersionCommand, };
|
|
34
|
+
export { HelpCommand, LoginCommand, LoginHeadlessCommand, RefreshCommand, DownloadCommand, RandomDownloadCommand, SchedulerCommand, MigrateConfigCommand, NormalizeCommand, WebUICommand, HealthCommand, StatusCommand, LogsCommand, ConfigCommand, BackupCommand, MaintainCommand, MonitorCommand, SetupCommand, DirsCommand, VersionCommand, TagsCommand, TopicCommand, };
|
|
33
35
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAuBnE;AAED;;GAEG;AACH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EACb,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,YAAY,GACb,CAAC"}
|
package/dist/commands/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Command exports and registration
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.VersionCommand = exports.DirsCommand = exports.SetupCommand = exports.MonitorCommand = exports.MaintainCommand = exports.BackupCommand = exports.ConfigCommand = exports.LogsCommand = exports.StatusCommand = exports.HealthCommand = exports.WebUICommand = exports.NormalizeCommand = exports.MigrateConfigCommand = exports.SchedulerCommand = exports.RandomDownloadCommand = exports.DownloadCommand = exports.RefreshCommand = exports.LoginHeadlessCommand = exports.LoginCommand = exports.HelpCommand = void 0;
|
|
6
|
+
exports.TopicCommand = exports.TagsCommand = exports.VersionCommand = exports.DirsCommand = exports.SetupCommand = exports.MonitorCommand = exports.MaintainCommand = exports.BackupCommand = exports.ConfigCommand = exports.LogsCommand = exports.StatusCommand = exports.HealthCommand = exports.WebUICommand = exports.NormalizeCommand = exports.MigrateConfigCommand = exports.SchedulerCommand = exports.RandomDownloadCommand = exports.DownloadCommand = exports.RefreshCommand = exports.LoginHeadlessCommand = exports.LoginCommand = exports.HelpCommand = void 0;
|
|
7
7
|
exports.registerAllCommands = registerAllCommands;
|
|
8
8
|
const HelpCommand_1 = require("./HelpCommand");
|
|
9
9
|
Object.defineProperty(exports, "HelpCommand", { enumerable: true, get: function () { return HelpCommand_1.HelpCommand; } });
|
|
@@ -45,6 +45,10 @@ const DirsCommand_1 = require("./DirsCommand");
|
|
|
45
45
|
Object.defineProperty(exports, "DirsCommand", { enumerable: true, get: function () { return DirsCommand_1.DirsCommand; } });
|
|
46
46
|
const VersionCommand_1 = require("./VersionCommand");
|
|
47
47
|
Object.defineProperty(exports, "VersionCommand", { enumerable: true, get: function () { return VersionCommand_1.VersionCommand; } });
|
|
48
|
+
const TagsCommand_1 = require("./TagsCommand");
|
|
49
|
+
Object.defineProperty(exports, "TagsCommand", { enumerable: true, get: function () { return TagsCommand_1.TagsCommand; } });
|
|
50
|
+
const TopicCommand_1 = require("./TopicCommand");
|
|
51
|
+
Object.defineProperty(exports, "TopicCommand", { enumerable: true, get: function () { return TopicCommand_1.TopicCommand; } });
|
|
48
52
|
/**
|
|
49
53
|
* Create and register all commands
|
|
50
54
|
*/
|
|
@@ -69,5 +73,7 @@ function registerAllCommands(registry) {
|
|
|
69
73
|
registry.register(new SetupCommand_1.SetupCommand());
|
|
70
74
|
registry.register(new DirsCommand_1.DirsCommand());
|
|
71
75
|
registry.register(new VersionCommand_1.VersionCommand());
|
|
76
|
+
registry.register(new TagsCommand_1.TagsCommand());
|
|
77
|
+
registry.register(new TopicCommand_1.TopicCommand());
|
|
72
78
|
}
|
|
73
79
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA6BH,kDAuBC;AAjDD,+CAA4C;AAuD1C,4FAvDO,yBAAW,OAuDP;AAtDb,iDAA8C;AAuD5C,6FAvDO,2BAAY,OAuDP;AAtDd,iEAA8D;AAuD5D,qGAvDO,2CAAoB,OAuDP;AAtDtB,qDAAkD;AAuDhD,+FAvDO,+BAAc,OAuDP;AAtDhB,uDAAoD;AAuDlD,gGAvDO,iCAAe,OAuDP;AAtDjB,mEAAgE;AAuD9D,sGAvDO,6CAAqB,OAuDP;AAtDvB,yDAAsD;AAuDpD,iGAvDO,mCAAgB,OAuDP;AAtDlB,iEAA8D;AAuD5D,qGAvDO,2CAAoB,OAuDP;AAtDtB,yDAAsD;AAuDpD,iGAvDO,mCAAgB,OAuDP;AAtDlB,iDAA8C;AAuD5C,6FAvDO,2BAAY,OAuDP;AAtDd,mDAAgD;AAuD9C,8FAvDO,6BAAa,OAuDP;AAtDf,mDAAgD;AAuD9C,8FAvDO,6BAAa,OAuDP;AAtDf,+CAA4C;AAuD1C,4FAvDO,yBAAW,OAuDP;AAtDb,mDAAgD;AAuD9C,8FAvDO,6BAAa,OAuDP;AAtDf,mDAAgD;AAuD9C,8FAvDO,6BAAa,OAuDP;AAtDf,uDAAoD;AAuDlD,gGAvDO,iCAAe,OAuDP;AAtDjB,qDAAkD;AAuDhD,+FAvDO,+BAAc,OAuDP;AAtDhB,iDAA8C;AAuD5C,6FAvDO,2BAAY,OAuDP;AAtDd,+CAA4C;AAuD1C,4FAvDO,yBAAW,OAuDP;AAtDb,qDAAkD;AAuDhD,+FAvDO,+BAAc,OAuDP;AAtDhB,+CAA4C;AAuD1C,4FAvDO,yBAAW,OAuDP;AAtDb,iDAA8C;AAuD5C,6FAvDO,2BAAY,OAuDP;AArDd;;GAEG;AACH,SAAgB,mBAAmB,CAAC,QAAyB;IAC3D,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAW,EAAE,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,IAAI,2BAAY,EAAE,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,2CAAoB,EAAE,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,IAAI,+BAAc,EAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,IAAI,iCAAe,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6CAAqB,EAAE,CAAC,CAAC;IAC/C,QAAQ,CAAC,QAAQ,CAAC,IAAI,mCAAgB,EAAE,CAAC,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,IAAI,2CAAoB,EAAE,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,CAAC,IAAI,mCAAgB,EAAE,CAAC,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,IAAI,2BAAY,EAAE,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAW,EAAE,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,6BAAa,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,iCAAe,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,IAAI,+BAAc,EAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,IAAI,2BAAY,EAAE,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAW,EAAE,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,IAAI,+BAAc,EAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAW,EAAE,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,IAAI,2BAAY,EAAE,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type TargetType = 'illustration' | 'novel';
|
|
5
5
|
export type DeliveryFieldValue = string | number | boolean | string[];
|
|
6
|
+
/** Discovery tuning for mode='topic'. Every value has a safe default. */
|
|
7
|
+
export interface TopicDiscoveryConfig {
|
|
8
|
+
/** Max related tags used to build the search space (default 12). */
|
|
9
|
+
maxTags?: number;
|
|
10
|
+
/** Recent works sampled per type to compute co-occurrence (default 100). */
|
|
11
|
+
sampleWorks?: number;
|
|
12
|
+
/** Cache lifetime in days for the resolved tag space (default 7). */
|
|
13
|
+
cacheDays?: number;
|
|
14
|
+
/** Minimum relatedness score for a tag to enter the space (default 0.18). */
|
|
15
|
+
minScore?: number;
|
|
16
|
+
/** Ignore a fresh cache and re-discover now (default false). */
|
|
17
|
+
refresh?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Candidate collection tuning for mode='topic'. */
|
|
20
|
+
export interface CandidateCollectionConfig {
|
|
21
|
+
/** Max works fetched per related tag for the target day (default 40). */
|
|
22
|
+
maxPerTag?: number;
|
|
23
|
+
/** Hard cap on the merged, deduplicated candidate pool (default 250). */
|
|
24
|
+
maxCandidates?: number;
|
|
25
|
+
/** Minimum metadata-topic score to survive filtering (default 0.35). */
|
|
26
|
+
minMetadataScore?: number;
|
|
27
|
+
}
|
|
6
28
|
export interface TargetDeliveryConfig {
|
|
7
29
|
/** 顶层 delivery.targets 中定义的交付目标名称 */
|
|
8
30
|
target: string;
|
|
@@ -43,13 +65,34 @@ export interface TargetConfig {
|
|
|
43
65
|
sort?: 'date_desc' | 'date_asc' | 'popular_desc';
|
|
44
66
|
restrict?: 'public' | 'private';
|
|
45
67
|
/**
|
|
46
|
-
* Download mode: 'search' (default) or '
|
|
68
|
+
* Download mode: 'search' (default), 'ranking' or 'topic'
|
|
47
69
|
* - 'search': Search by tag
|
|
48
70
|
* - 'ranking': Use the Pixiv ranking API when filterTag is absent. With
|
|
49
71
|
* filterTag, search works published on rankingDate and rank them locally
|
|
50
72
|
* by popularity.
|
|
73
|
+
* - 'topic': Semantic-topic download. Instead of requiring the user to know
|
|
74
|
+
* every related Pixiv tag, PixivFlow derives a dynamic search space from
|
|
75
|
+
* the topic itself (Pixiv autocomplete + tag co-occurrence on recent
|
|
76
|
+
* works), searches the target day across those tags, filters by lightweight
|
|
77
|
+
* metadata scoring and ranks by local popularity, then downloads Top N.
|
|
78
|
+
* No LLM/VLM/embeddings — only Pixiv tag/metadata signals.
|
|
79
|
+
*/
|
|
80
|
+
mode?: 'search' | 'ranking' | 'topic';
|
|
81
|
+
/**
|
|
82
|
+
* Semantic topic for mode='topic'. Distinct from `tag`: a tag is an exact
|
|
83
|
+
* Pixiv tag to match, while a topic is expanded at runtime into related
|
|
84
|
+
* tags. Only the seed topic needs to be supplied.
|
|
85
|
+
*/
|
|
86
|
+
topic?: string;
|
|
87
|
+
/**
|
|
88
|
+
* One-day publication window for mode='topic' (YYYY-MM-DD, 'YESTERDAY' or
|
|
89
|
+
* 'TODAY'). Resolved at run time. Falls back to rankingDate/startDate, then
|
|
90
|
+
* YESTERDAY for the daily scheduler use case.
|
|
51
91
|
*/
|
|
52
|
-
|
|
92
|
+
date?: string;
|
|
93
|
+
/** Tunable discovery/collection knobs for mode='topic' (all optional). */
|
|
94
|
+
topicDiscovery?: TopicDiscoveryConfig;
|
|
95
|
+
candidateCollection?: CandidateCollectionConfig;
|
|
53
96
|
/**
|
|
54
97
|
* Ranking mode (only used when mode='ranking')
|
|
55
98
|
* - 'day': Daily ranking
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,OAAO,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC;AAEtE,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,YAAY,CAAC,EAAE,wBAAwB,GAAG,sBAAsB,GAAG,mBAAmB,CAAC;IACvF;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,cAAc,CAAC;IACjD,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/config/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,MAAM,EAAE,MAAM,EAAE;aAChB,QAAQ,EAAE,MAAM,EAAE;gBAFlC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,GAAE,MAAM,EAAO;CAK1C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/config/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,MAAM,EAAE,MAAM,EAAE;aAChB,QAAQ,EAAE,MAAM,EAAE;gBAFlC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,GAAE,MAAM,EAAO;CAK1C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAkT/G;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAkB/G"}
|
|
@@ -93,9 +93,46 @@ function validateConfig(config, location, databasePath) {
|
|
|
93
93
|
}
|
|
94
94
|
targetIds.add(target.id);
|
|
95
95
|
}
|
|
96
|
-
//
|
|
97
|
-
if (target.mode
|
|
98
|
-
errors.push(`targets[${index}].
|
|
96
|
+
// mode must be a known value
|
|
97
|
+
if (target.mode && !['search', 'ranking', 'topic'].includes(target.mode)) {
|
|
98
|
+
errors.push(`targets[${index}].mode: Invalid value "${target.mode}", must be search, ranking or topic`);
|
|
99
|
+
}
|
|
100
|
+
// mode='topic' requires a topic seed instead of an exact tag
|
|
101
|
+
if (target.mode === 'topic' && (!target.topic || target.topic.trim() === '')) {
|
|
102
|
+
errors.push(`targets[${index}].topic: Required field is missing or empty (mode='topic' derives tags from the topic)`);
|
|
103
|
+
}
|
|
104
|
+
// Tag is required for search mode, optional for ranking/topic/series/single/user modes
|
|
105
|
+
if (target.mode !== 'ranking' && target.mode !== 'topic' && !target.seriesId && !target.novelId && !target.illustId && !target.userId && (!target.tag || target.tag.trim() === '')) {
|
|
106
|
+
errors.push(`targets[${index}].tag: Required field is missing or empty (required for search mode, optional for ranking/topic/series/single/user mode)`);
|
|
107
|
+
}
|
|
108
|
+
const td = target.topicDiscovery;
|
|
109
|
+
if (td) {
|
|
110
|
+
const bound = (field, min, max) => {
|
|
111
|
+
const value = td[field];
|
|
112
|
+
if (value !== undefined && (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max)) {
|
|
113
|
+
errors.push(`targets[${index}].topicDiscovery.${field}: Must be an integer between ${min} and ${max} (got ${value})`);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
bound('maxTags', 1, 40);
|
|
117
|
+
bound('sampleWorks', 10, 200);
|
|
118
|
+
bound('cacheDays', 1, 90);
|
|
119
|
+
if (typeof td.minScore === 'number' && (td.minScore < 0 || td.minScore > 1)) {
|
|
120
|
+
errors.push(`targets[${index}].topicDiscovery.minScore: Must be between 0 and 1 (got ${td.minScore})`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const cc = target.candidateCollection;
|
|
124
|
+
if (cc) {
|
|
125
|
+
const bound = (field, min, max) => {
|
|
126
|
+
const value = cc[field];
|
|
127
|
+
if (value !== undefined && (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max)) {
|
|
128
|
+
errors.push(`targets[${index}].candidateCollection.${field}: Must be an integer between ${min} and ${max} (got ${value})`);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
bound('maxPerTag', 5, 100);
|
|
132
|
+
bound('maxCandidates', 20, 500);
|
|
133
|
+
if (typeof cc.minMetadataScore === 'number' && (cc.minMetadataScore < 0 || cc.minMetadataScore > 3)) {
|
|
134
|
+
errors.push(`targets[${index}].candidateCollection.minMetadataScore: Must be between 0 and 3 (got ${cc.minMetadataScore})`);
|
|
135
|
+
}
|
|
99
136
|
}
|
|
100
137
|
if (target.type && !['illustration', 'novel'].includes(target.type)) {
|
|
101
138
|
errors.push(`targets[${index}].type: Must be "illustration" or "novel"`);
|