twitter-snap 0.0.23 → 0.0.25
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 +36 -23
- package/bin/run.js +1 -1
- package/dist/commands/index.d.ts +14 -9
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +125 -49
- package/dist/commands/index.js.map +1 -1
- package/dist/core/core.d.ts +11 -10
- package/dist/core/core.d.ts.map +1 -1
- package/dist/core/core.js +57 -48
- package/dist/core/core.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/fonts.d.ts +4 -0
- package/dist/utils/fonts.d.ts.map +1 -1
- package/dist/utils/fonts.js +10 -26
- package/dist/utils/fonts.js.map +1 -1
- package/dist/utils/logger.d.ts +35 -13
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +165 -72
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/types.d.ts +1 -1
- package/dist/utils/types.d.ts.map +1 -1
- package/dist/utils/url.d.ts +5 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +32 -0
- package/dist/utils/url.js.map +1 -0
- package/oclif.manifest.json +108 -48
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@ npx twitter-snap 1518623997054918657
|
|
|
13
13
|
|
|
14
14
|

|
|
15
15
|
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
`npm -g i twitter-snap@latest`
|
|
19
|
+
|
|
16
20
|
## Arguments
|
|
17
21
|
|
|
18
22
|
```shell
|
|
@@ -20,44 +24,53 @@ $ bin/run --help
|
|
|
20
24
|
Create beautiful Tweet images fast
|
|
21
25
|
|
|
22
26
|
USAGE
|
|
23
|
-
$ twitter-snap ID [--api
|
|
24
|
-
|
|
25
|
-
tBookmarks] [--theme RenderBasic] [-o <value>] [--cleanup] [--max <value>] [--debug] [--sleep <value>] [--session_type <value>] [--cookies_file <value>] [--browser_profile <value>]
|
|
26
|
-
[--browser_headless]
|
|
27
|
+
$ twitter-snap ID [--api getTweetResultByRestId|getTweetDetail|getSearchTimeline|getHomeTimeline|getHomeLatestTimeline|getListLatestTweetsTimeline|getUserTweets|getUserTweetsAndReplies|getUserMedia|getLikes|getBookmarks] [--browserHeadless] [--browserProfile <value>] [--cookiesFile
|
|
28
|
+
<value>] [--debug] [--limit <value>] [--noCleanup] [-o <value>] [--sessionType <value>] [--simpleLog] [--sleep <value>] [--theme RenderBasic] [--ffmpegAdditonalOption <value>] [--ffmpegPath <value>] [--ffprobePath <value>]
|
|
27
29
|
|
|
28
30
|
ARGUMENTS
|
|
29
31
|
ID Twitter status id
|
|
30
32
|
|
|
31
33
|
FLAGS
|
|
32
|
-
-o, --output=<value>
|
|
33
|
-
--api=<option>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
--
|
|
40
|
-
--
|
|
41
|
-
--
|
|
42
|
-
--
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
|
|
34
|
+
-o, --output=<value> [default: {id}.{if-photo:png:mp4}] Output file name
|
|
35
|
+
--api=<option> [default: getTweetResultByRestId] API type
|
|
36
|
+
<options: getTweetResultByRestId|getTweetDetail|getSearchTimeline|getHomeTimeline|getHomeLatestTimeline|getListLatestTweetsTimeline|getUserTweets|getUserTweetsAndReplies|getUserMedia|getLikes|getBookmarks>
|
|
37
|
+
--browserHeadless Browser headless
|
|
38
|
+
--browserProfile=<value> [default: C:\Users\yuki/.cache/twitter-snap/profiles] Browser profile
|
|
39
|
+
--cookiesFile=<value> [default: cookies.json] Cookies file
|
|
40
|
+
--debug Debug
|
|
41
|
+
--ffmpegAdditonalOption=<value> FFmpeg additonal option
|
|
42
|
+
--ffmpegPath=<value> [default: ffmpeg] FFmpeg path
|
|
43
|
+
--ffprobePath=<value> [default: ffprobe] FFprobe path
|
|
44
|
+
--limit=<value> [default: 30] Limit count
|
|
45
|
+
--noCleanup Cleanup
|
|
46
|
+
--sessionType=<value> [default: guest] Session type
|
|
47
|
+
--simpleLog Simple log
|
|
48
|
+
--sleep=<value> Sleep (ms)
|
|
49
|
+
--theme=<option> [default: RenderBasic] Theme type
|
|
50
|
+
<options: RenderBasic>
|
|
46
51
|
|
|
47
52
|
DESCRIPTION
|
|
48
53
|
Create beautiful Tweet images fast
|
|
49
54
|
https://github.com/fa0311/twitter-snap
|
|
50
55
|
|
|
51
56
|
EXAMPLES
|
|
52
|
-
$ twitter-snap
|
|
57
|
+
$ twitter-snap 1349129669258448897
|
|
58
|
+
|
|
59
|
+
$ twitter-snap 1349129669258448897 --session-type browser
|
|
60
|
+
|
|
61
|
+
$ twitter-snap 1349129669258448897 --session-type file --cookies-file cookies.json
|
|
62
|
+
|
|
63
|
+
$ twitter-snap 44196397 --api getUserTweets --limit 10
|
|
64
|
+
|
|
65
|
+
$ twitter-snap 44196397 --api getUserTweets -o "data/{user-screen-name}/{id}.{if-photo:png:mp4}"
|
|
53
66
|
|
|
54
|
-
$ twitter-snap
|
|
67
|
+
$ twitter-snap https://twitter.com/elonmusk
|
|
55
68
|
|
|
56
|
-
$ twitter-snap
|
|
69
|
+
$ twitter-snap https://twitter.com/elonmusk/status/1349129669258448897
|
|
57
70
|
|
|
58
|
-
$ twitter-snap 44196397 --api getUserTweets
|
|
71
|
+
$ twitter-snap 44196397 --api getUserTweets -o "{user-screen-name}/{count}.png"
|
|
59
72
|
|
|
60
|
-
$ twitter-snap 44196397 --api getUserTweets
|
|
73
|
+
$ twitter-snap 44196397 --api getUserTweets -o "{time-tweet-yyyy}-{time-tweet-mm}-{time-tweet-dd}/{id}.png"
|
|
61
74
|
```
|
|
62
75
|
|
|
63
76
|
## Dependence
|
package/bin/run.js
CHANGED
package/dist/commands/index.d.ts
CHANGED
|
@@ -3,22 +3,27 @@ export default class Default extends Command {
|
|
|
3
3
|
static args: {
|
|
4
4
|
id: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
|
+
static browserProfile: string;
|
|
6
7
|
static description: string;
|
|
7
8
|
static examples: string[];
|
|
8
|
-
static browser_profile: string;
|
|
9
9
|
static flags: {
|
|
10
10
|
api: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<"getTweetDetail" | "getSearchTimeline" | "getHomeTimeline" | "getHomeLatestTimeline" | "getListLatestTweetsTimeline" | "getUserTweets" | "getUserTweetsAndReplies" | "getUserMedia" | "getLikes" | "getBookmarks" | "getTweetResultByRestId", import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
max: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
|
+
browserHeadless: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
12
|
+
browserProfile: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
|
+
cookiesFile: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
15
14
|
debug: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
15
|
+
ffmpegAdditonalOption: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
16
|
+
ffmpegPath: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
17
|
+
ffprobePath: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
18
|
+
limit: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
19
|
+
noCleanup: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
20
|
+
output: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
21
|
+
sessionType: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<"browser" | "file" | "guest", import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
22
|
+
simpleLog: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
16
23
|
sleep: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
17
|
-
|
|
18
|
-
cookies_file: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
19
|
-
browser_profile: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
20
|
-
browser_headless: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
24
|
+
theme: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<"RenderBasic", import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
21
25
|
};
|
|
26
|
+
main(): Promise<void>;
|
|
22
27
|
run(): Promise<void>;
|
|
23
28
|
}
|
|
24
29
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAQ,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,OAAO,EAAQ,MAAM,aAAa,CAAA;AAShD,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,MAAM,CAAC,IAAI;;MAEV;IAED,MAAM,CAAC,cAAc,SAAiD;IACtE,MAAM,CAAC,WAAW,SAA8F;IAEhH,MAAM,CAAC,QAAQ,WAUd;IAED,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;MAwEX;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6ErB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAO3B"}
|
package/dist/commands/index.js
CHANGED
|
@@ -1,44 +1,43 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { Args, Command, Flags } from '@oclif/core';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
import { themeList } from 'twitter-snap-core';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { FFmpegInfrastructure, themeList } from 'twitter-snap-core';
|
|
5
5
|
import { twitterSnapCookies, twitterSnapGuest, twitterSnapPuppeteer } from '../core/core.js';
|
|
6
|
-
import { Logger } from '../utils/logger.js';
|
|
6
|
+
import { Logger, LoggerSimple } from '../utils/logger.js';
|
|
7
|
+
import { twitterUrlConvert } from '../utils/url.js';
|
|
7
8
|
import { getTweetList } from './../utils/types.js';
|
|
8
|
-
const apiFlag = Flags.custom({
|
|
9
|
-
description: 'API type',
|
|
10
|
-
options: ['getTweetResultByRestId', ...getTweetList],
|
|
11
|
-
default: 'getTweetResultByRestId',
|
|
12
|
-
});
|
|
13
|
-
const themeNameFlag = Flags.custom({
|
|
14
|
-
description: 'Theme type',
|
|
15
|
-
options: Object.keys(themeList),
|
|
16
|
-
default: 'RenderBasic',
|
|
17
|
-
});
|
|
18
|
-
const sessionType = Flags.custom({
|
|
19
|
-
description: 'Session type',
|
|
20
|
-
default: 'guest',
|
|
21
|
-
});
|
|
22
9
|
class Default extends Command {
|
|
23
|
-
async
|
|
10
|
+
async main() {
|
|
24
11
|
const { args, flags } = await this.parse(_a);
|
|
25
|
-
const logger = new Logger();
|
|
12
|
+
const logger = flags.simpleLog ? new LoggerSimple(this.log.bind(this)) : new Logger();
|
|
26
13
|
console.log = flags.debug ? logger.log.bind(logger) : (_) => { };
|
|
27
|
-
console.debug = flags.debug ? logger.
|
|
14
|
+
console.debug = flags.debug ? logger.log.bind(logger) : (_) => { };
|
|
28
15
|
console.warn = logger.warn.bind(logger);
|
|
29
16
|
console.error = logger.error.bind(logger);
|
|
30
17
|
const getClient = (() => {
|
|
31
|
-
switch (flags.
|
|
18
|
+
switch (flags.sessionType) {
|
|
32
19
|
case 'guest':
|
|
33
20
|
return twitterSnapGuest();
|
|
34
21
|
case 'browser':
|
|
35
|
-
return twitterSnapPuppeteer(flags.
|
|
22
|
+
return twitterSnapPuppeteer(flags.browserHeadless, flags.browserProfile);
|
|
36
23
|
case 'file':
|
|
37
|
-
return twitterSnapCookies(flags.
|
|
24
|
+
return twitterSnapCookies(flags.cookiesFile);
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
const [client, api] = await logger.guard({ text: 'Loading client' }, getClient);
|
|
28
|
+
const [id, type] = await (async () => {
|
|
29
|
+
if (args.id.startsWith('http')) {
|
|
30
|
+
const convert = twitterUrlConvert({ url: args.id });
|
|
31
|
+
if (typeof convert === 'function') {
|
|
32
|
+
return await logger.guard({ text: 'Get user id' }, convert(api));
|
|
33
|
+
}
|
|
34
|
+
else if (typeof convert === 'object') {
|
|
35
|
+
return convert;
|
|
36
|
+
}
|
|
38
37
|
}
|
|
38
|
+
return [args.id, flags.api];
|
|
39
39
|
})();
|
|
40
|
-
const
|
|
41
|
-
const logHandler = async ({ type, user, id }) => {
|
|
40
|
+
const logHandler = async ({ id, type, user }) => {
|
|
42
41
|
switch (type) {
|
|
43
42
|
case 'start':
|
|
44
43
|
return logger.update(`Rendering tweet ${user}/${id}`);
|
|
@@ -49,54 +48,131 @@ class Default extends Command {
|
|
|
49
48
|
}
|
|
50
49
|
};
|
|
51
50
|
const sleep = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
52
|
-
const render = client({ id
|
|
51
|
+
const render = client({ id, limit: flags.limit, type }, async (render) => {
|
|
53
52
|
try {
|
|
54
53
|
const finalize = await render({
|
|
54
|
+
handler: logHandler,
|
|
55
|
+
output: flags.output,
|
|
55
56
|
themeName: flags.theme,
|
|
56
57
|
themeParam: {
|
|
58
|
+
ffmpeg: new FFmpegInfrastructure({
|
|
59
|
+
ffmpegPath: flags.ffmpegPath,
|
|
60
|
+
ffprobePath: flags.ffprobePath,
|
|
61
|
+
}),
|
|
62
|
+
ffmpegAdditonalOption: flags.ffmpegAdditonalOption?.split(' ') ?? [],
|
|
57
63
|
width: 600,
|
|
58
64
|
},
|
|
59
|
-
output: flags.output,
|
|
60
|
-
handler: logHandler,
|
|
61
65
|
});
|
|
62
66
|
await finalize({
|
|
63
|
-
cleanup:
|
|
67
|
+
cleanup: !flags.noCleanup,
|
|
64
68
|
});
|
|
65
69
|
logger.succeed();
|
|
66
70
|
}
|
|
67
|
-
catch (
|
|
68
|
-
logger.
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger.catchFail(error);
|
|
69
73
|
}
|
|
70
74
|
await sleep(flags.sleep);
|
|
71
75
|
});
|
|
72
|
-
await logger.guardProgress({ text: 'Rendering tweet'
|
|
76
|
+
await logger.guardProgress({ max: flags.limit, text: 'Rendering tweet' }, render);
|
|
77
|
+
}
|
|
78
|
+
async run() {
|
|
79
|
+
try {
|
|
80
|
+
await this.main();
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error(error);
|
|
84
|
+
}
|
|
73
85
|
}
|
|
74
86
|
}
|
|
75
87
|
_a = Default;
|
|
76
88
|
Default.args = {
|
|
77
89
|
id: Args.string({ description: 'Twitter status id', required: true }),
|
|
78
90
|
};
|
|
91
|
+
Default.browserProfile = `${os.homedir()}/.cache/twitter-snap/profiles`;
|
|
79
92
|
Default.description = ['Create beautiful Tweet images fast', 'https://github.com/fa0311/twitter-snap'].join('\n');
|
|
80
93
|
Default.examples = [
|
|
81
|
-
'twitter-snap
|
|
82
|
-
'twitter-snap
|
|
83
|
-
'twitter-snap
|
|
84
|
-
'twitter-snap 44196397 --api getUserTweets --
|
|
85
|
-
'twitter-snap 44196397 --api getUserTweets
|
|
94
|
+
'twitter-snap 1349129669258448897',
|
|
95
|
+
'twitter-snap 1349129669258448897 --session-type browser',
|
|
96
|
+
'twitter-snap 1349129669258448897 --session-type file --cookies-file cookies.json',
|
|
97
|
+
'twitter-snap 44196397 --api getUserTweets --limit 10',
|
|
98
|
+
'twitter-snap 44196397 --api getUserTweets -o "data/{user-screen-name}/{id}.{if-photo:png:mp4}"',
|
|
99
|
+
'twitter-snap https://twitter.com/elonmusk',
|
|
100
|
+
'twitter-snap https://twitter.com/elonmusk/status/1349129669258448897',
|
|
101
|
+
'twitter-snap 44196397 --api getUserTweets -o "{user-screen-name}/{count}.png"',
|
|
102
|
+
'twitter-snap 44196397 --api getUserTweets -o "{time-tweet-yyyy}-{time-tweet-mm}-{time-tweet-dd}/{id}.png"',
|
|
86
103
|
];
|
|
87
|
-
Default.browser_profile = `${os.homedir()}/.cache/twitter-snap/profiles`;
|
|
88
104
|
Default.flags = {
|
|
89
|
-
api:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
api: Flags.custom({
|
|
106
|
+
default: 'getTweetResultByRestId',
|
|
107
|
+
description: 'API type',
|
|
108
|
+
options: ['getTweetResultByRestId', ...getTweetList],
|
|
109
|
+
})(),
|
|
110
|
+
browserHeadless: Flags.boolean({
|
|
111
|
+
aliases: ['browser-headless'],
|
|
112
|
+
default: false,
|
|
113
|
+
description: 'Browser headless',
|
|
114
|
+
}),
|
|
115
|
+
browserProfile: Flags.string({
|
|
116
|
+
aliases: ['browser-profile'],
|
|
117
|
+
default: _a.browserProfile,
|
|
118
|
+
description: 'Browser profile',
|
|
119
|
+
}),
|
|
120
|
+
cookiesFile: Flags.file({
|
|
121
|
+
aliases: ['cookies-file'],
|
|
122
|
+
default: 'cookies.json',
|
|
123
|
+
description: 'Cookies file',
|
|
124
|
+
}),
|
|
125
|
+
debug: Flags.boolean({
|
|
126
|
+
default: false,
|
|
127
|
+
description: 'Debug',
|
|
128
|
+
}),
|
|
129
|
+
ffmpegAdditonalOption: Flags.string({
|
|
130
|
+
aliases: ['ffmpeg-additonal-option'],
|
|
131
|
+
description: 'FFmpeg additonal option',
|
|
132
|
+
}),
|
|
133
|
+
ffmpegPath: Flags.string({
|
|
134
|
+
aliases: ['ffmpeg-path'],
|
|
135
|
+
default: 'ffmpeg',
|
|
136
|
+
description: 'FFmpeg path',
|
|
137
|
+
}),
|
|
138
|
+
ffprobePath: Flags.string({
|
|
139
|
+
aliases: ['ffprobe-path'],
|
|
140
|
+
default: 'ffprobe',
|
|
141
|
+
description: 'FFprobe path',
|
|
142
|
+
}),
|
|
143
|
+
limit: Flags.integer({
|
|
144
|
+
default: 30,
|
|
145
|
+
description: 'Limit count',
|
|
146
|
+
}),
|
|
147
|
+
noCleanup: Flags.boolean({
|
|
148
|
+
aliases: ['no-cleanup'],
|
|
149
|
+
default: false,
|
|
150
|
+
description: 'Cleanup',
|
|
151
|
+
}),
|
|
152
|
+
output: Flags.string({
|
|
153
|
+
char: 'o',
|
|
154
|
+
default: '{id}.{if-photo:png:mp4}',
|
|
155
|
+
description: 'Output file name',
|
|
156
|
+
}),
|
|
157
|
+
sessionType: Flags.custom({
|
|
158
|
+
aliases: ['session-type'],
|
|
159
|
+
default: 'guest',
|
|
160
|
+
description: 'Session type',
|
|
161
|
+
})(),
|
|
162
|
+
simpleLog: Flags.boolean({
|
|
163
|
+
aliases: ['simple-log'],
|
|
164
|
+
default: false,
|
|
165
|
+
description: 'Simple log',
|
|
166
|
+
}),
|
|
167
|
+
sleep: Flags.integer({
|
|
168
|
+
default: 0,
|
|
169
|
+
description: 'Sleep (ms)',
|
|
170
|
+
}),
|
|
171
|
+
theme: Flags.custom({
|
|
172
|
+
default: 'RenderBasic',
|
|
173
|
+
description: 'Theme type',
|
|
174
|
+
options: Object.keys(themeList),
|
|
175
|
+
})(),
|
|
100
176
|
};
|
|
101
177
|
export default Default;
|
|
102
178
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"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"}
|
package/dist/core/core.d.ts
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import { TweetApiUtilsData } from 'twitter-openapi-typescript';
|
|
1
|
+
import { TweetApiUtilsData, TwitterOpenApiClient } from 'twitter-openapi-typescript';
|
|
2
2
|
import { ThemeNameType } from 'twitter-snap-core';
|
|
3
3
|
import { GetTweetApi, ThemeParamType } from '../utils/types.js';
|
|
4
|
-
export declare const twitterSnapGuest: () => Promise<({ id,
|
|
5
|
-
export declare const twitterSnapPuppeteer: (headless?: boolean, userDataDir?: string) => Promise<({ id,
|
|
6
|
-
export declare const twitterSnapCookies: (path: string) => Promise<({ id,
|
|
4
|
+
export declare const twitterSnapGuest: () => Promise<readonly [({ id, limit, type }: tweetApiSnapParam, handler: handlerType) => Promise<void>, TwitterOpenApiClient]>;
|
|
5
|
+
export declare const twitterSnapPuppeteer: (headless?: boolean, userDataDir?: string) => Promise<readonly [({ id, limit, type }: tweetApiSnapParam, handler: handlerType) => Promise<void>, TwitterOpenApiClient]>;
|
|
6
|
+
export declare const twitterSnapCookies: (path: string) => Promise<readonly [({ id, limit, type }: tweetApiSnapParam, handler: handlerType) => Promise<void>, TwitterOpenApiClient]>;
|
|
7
7
|
type tweetApiSnapParam = {
|
|
8
8
|
id: string;
|
|
9
|
+
limit: number;
|
|
9
10
|
type?: 'getTweetResultByRestId' | keyof GetTweetApi;
|
|
10
|
-
max: number;
|
|
11
11
|
};
|
|
12
|
-
type
|
|
12
|
+
type handlerType = (e: ReturnType<typeof twitterRender>) => Promise<void>;
|
|
13
|
+
type HandlerTypeLiteral = 'image' | 'start' | 'video';
|
|
13
14
|
export type HandlerType = {
|
|
15
|
+
id: string;
|
|
14
16
|
type: HandlerTypeLiteral;
|
|
15
17
|
user: string;
|
|
16
|
-
id: string;
|
|
17
18
|
};
|
|
18
19
|
type twitterRenderParam = {
|
|
20
|
+
handler?: (e: HandlerType) => void;
|
|
21
|
+
output: string;
|
|
19
22
|
themeName: ThemeNameType;
|
|
20
23
|
themeParam: ThemeParamType;
|
|
21
|
-
output: string;
|
|
22
|
-
handler?: (e: HandlerType) => void;
|
|
23
24
|
};
|
|
24
|
-
declare const twitterRender: (data: TweetApiUtilsData) => ({
|
|
25
|
+
declare const twitterRender: (data: TweetApiUtilsData, count: number) => ({ handler, output, themeName, themeParam }: twitterRenderParam) => Promise<({ cleanup }: FinalizeParam) => Promise<void>>;
|
|
25
26
|
type FinalizeParam = {
|
|
26
27
|
cleanup: boolean;
|
|
27
28
|
};
|
package/dist/core/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/core/core.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,iBAAiB,EAAkB,oBAAoB,EAAC,MAAM,4BAA4B,CAAA;AAClG,OAAO,EAAC,aAAa,EAAY,MAAM,mBAAmB,CAAA;AAE1D,OAAO,EAAC,WAAW,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAA;AAE3E,eAAO,MAAM,gBAAgB,gDA6CM,iBAAiB,WAAW,WAAW,0CAzCzE,CAAA;AAED,eAAO,MAAM,oBAAoB,cAAqB,OAAO,gBAAgB,MAAM,6CAuChD,iBAAiB,WAAW,WAAW,0CAnBzE,CAAA;AAED,eAAO,MAAM,kBAAkB,SAAgB,MAAM,6CAiBlB,iBAAiB,WAAW,WAAW,0CAXzE,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,wBAAwB,GAAG,MAAM,WAAW,CAAA;CACpD,CAAA;AAED,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAyCzE,KAAK,kBAAkB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AACrD,MAAM,MAAM,WAAW,GAAG;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAA;AAE9E,KAAK,kBAAkB,GAAG;IACxB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,aAAa,CAAA;IACxB,UAAU,EAAE,cAAc,CAAA;CAC3B,CAAA;AAED,QAAA,MAAM,aAAa,SAAU,iBAAiB,SAAS,MAAM,kDAMH,kBAAkB,2BAqExD,aAAa,mBAPhC,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA"}
|
package/dist/core/core.js
CHANGED
|
@@ -1,62 +1,61 @@
|
|
|
1
1
|
import { ImageResponse } from '@vercel/og';
|
|
2
|
-
import { promises as fs } from 'fs';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import { launch } from 'puppeteer';
|
|
3
4
|
import { TwitterOpenApi } from 'twitter-openapi-typescript';
|
|
4
|
-
import puppeteer from 'puppeteer';
|
|
5
5
|
import { themeList } from 'twitter-snap-core';
|
|
6
6
|
import { getTweetList } from '../utils/types.js';
|
|
7
7
|
export const twitterSnapGuest = async () => {
|
|
8
8
|
const twitter = new TwitterOpenApi();
|
|
9
9
|
const api = await twitter.getGuestClient();
|
|
10
|
-
return tweetApiSnap(api);
|
|
10
|
+
return [tweetApiSnap(api), api];
|
|
11
11
|
};
|
|
12
12
|
export const twitterSnapPuppeteer = async (headless, userDataDir) => {
|
|
13
|
-
const browser = await
|
|
14
|
-
headless
|
|
13
|
+
const browser = await launch({
|
|
14
|
+
headless,
|
|
15
15
|
timeout: 0,
|
|
16
|
-
userDataDir
|
|
16
|
+
userDataDir,
|
|
17
17
|
});
|
|
18
18
|
const [page] = await browser.pages();
|
|
19
19
|
await page.goto('https://twitter.com/login');
|
|
20
20
|
page.setDefaultNavigationTimeout(0);
|
|
21
21
|
page.setDefaultTimeout(0);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
22
|
+
const pattern = 'https://twitter.com/i/api/graphql/[a-zA-Z0-9_-]+/HomeTimeline?.*';
|
|
23
|
+
await page.waitForResponse((res) => new RegExp(pattern).test(res.url()));
|
|
25
24
|
const cookies = await page.cookies();
|
|
26
25
|
await browser.close();
|
|
27
26
|
const twitter = new TwitterOpenApi();
|
|
28
|
-
const api = await twitter.getClientFromCookies(cookies.
|
|
29
|
-
return tweetApiSnap(api);
|
|
27
|
+
const api = await twitter.getClientFromCookies(Object.fromEntries(cookies.map((e) => [e.name, e.value])));
|
|
28
|
+
return [tweetApiSnap(api), api];
|
|
30
29
|
};
|
|
31
30
|
export const twitterSnapCookies = async (path) => {
|
|
32
|
-
const data = await fs.readFile(path, '
|
|
31
|
+
const data = await fs.readFile(path, 'utf8');
|
|
33
32
|
const cookies = JSON.parse(data);
|
|
34
33
|
const twitter = new TwitterOpenApi();
|
|
35
|
-
const api = await twitter.getClientFromCookies(cookies.
|
|
36
|
-
return tweetApiSnap(api);
|
|
34
|
+
const api = await twitter.getClientFromCookies(Object.fromEntries(cookies.map((e) => [e.name, e.value])));
|
|
35
|
+
return [tweetApiSnap(api), api];
|
|
37
36
|
};
|
|
38
37
|
const tweetApiSnap = (client) => {
|
|
39
|
-
return async ({ id,
|
|
40
|
-
const key = getTweetList.find((k) => k
|
|
38
|
+
return async ({ id, limit, type }, handler) => {
|
|
39
|
+
const key = getTweetList.find((k) => k === type);
|
|
41
40
|
if (key) {
|
|
42
41
|
const that = client.getTweetApi();
|
|
43
42
|
const api = that[key].bind(that);
|
|
44
43
|
let count = 0;
|
|
45
44
|
const cursor = [];
|
|
46
|
-
while (count <
|
|
45
|
+
while (count < limit) {
|
|
47
46
|
const res = await api({
|
|
47
|
+
cursor: cursor.length > 0 ? cursor.pop() : undefined,
|
|
48
48
|
focalTweetId: id,
|
|
49
|
-
rawQuery: id,
|
|
50
49
|
listId: id,
|
|
50
|
+
rawQuery: id,
|
|
51
51
|
userId: id,
|
|
52
|
-
cursor: cursor.length ? cursor.pop() : undefined,
|
|
53
52
|
});
|
|
54
53
|
for (const e of res.data.data) {
|
|
55
54
|
if (e.promotedMetadata)
|
|
56
55
|
continue;
|
|
57
|
-
if (count >=
|
|
56
|
+
if (count >= limit)
|
|
58
57
|
return;
|
|
59
|
-
await handler(twitterRender(e));
|
|
58
|
+
await handler(twitterRender(e, count));
|
|
60
59
|
count++;
|
|
61
60
|
}
|
|
62
61
|
if (res.data.cursor.bottom) {
|
|
@@ -72,37 +71,51 @@ const tweetApiSnap = (client) => {
|
|
|
72
71
|
tweetId: id,
|
|
73
72
|
});
|
|
74
73
|
if (res.data)
|
|
75
|
-
await handler(twitterRender(res.data));
|
|
74
|
+
await handler(twitterRender(res.data, 0));
|
|
76
75
|
}
|
|
77
76
|
};
|
|
78
77
|
};
|
|
79
|
-
const twitterRender = (data) => {
|
|
78
|
+
const twitterRender = (data, count) => {
|
|
79
|
+
const legacy = data.tweet.legacy;
|
|
80
80
|
const extEntities = data.tweet.legacy?.extendedEntities;
|
|
81
81
|
const extMedia = extEntities?.media ?? [];
|
|
82
|
-
const isVideoData =
|
|
83
|
-
return async ({
|
|
84
|
-
handler && handler({ type: 'start', user: data.user.legacy.screenName
|
|
85
|
-
const
|
|
86
|
-
const
|
|
82
|
+
const isVideoData = extMedia.some((e) => e.type !== 'photo');
|
|
83
|
+
return async ({ handler, output, themeName, themeParam }) => {
|
|
84
|
+
handler && handler({ id: data.tweet.restId, type: 'start', user: data.user.legacy.screenName });
|
|
85
|
+
const Theme = Object.entries(themeList).find(([k, _]) => k === themeName)[1];
|
|
86
|
+
const replaceData = [
|
|
87
87
|
['{id}', data.tweet.restId],
|
|
88
88
|
['{user-screen-name}', data.user.legacy.screenName],
|
|
89
89
|
['{if-photo:(?<true>.+?):(?<false>.+?)}', isVideoData ? '$2' : '$1'],
|
|
90
|
+
['{count}', count.toString()],
|
|
91
|
+
['{time-now-yyyy}', new Date().getFullYear().toString().padStart(4, '0')],
|
|
92
|
+
['{time-now-mm}', (new Date().getMonth() + 1).toString().padStart(2, '0')],
|
|
93
|
+
['{time-now-dd}', new Date().getDate().toString().padStart(2, '0')],
|
|
94
|
+
['{time-now-hh}', new Date().getHours().toString().padStart(2, '0')],
|
|
95
|
+
['{time-now-mi}', new Date().getMinutes().toString().padStart(2, '0')],
|
|
96
|
+
['{time-now-ss}', new Date().getSeconds().toString().padStart(2, '0')],
|
|
97
|
+
['{time-tweet-yyyy}', new Date(legacy.createdAt).getFullYear().toString().padStart(4, '0')],
|
|
98
|
+
['{time-tweet-mm}', (new Date(legacy.createdAt).getMonth() + 1).toString().padStart(2, '0')],
|
|
99
|
+
['{time-tweet-dd}', new Date(legacy.createdAt).getDate().toString().padStart(2, '0')],
|
|
100
|
+
['{time-tweet-hh}', new Date(legacy.createdAt).getHours().toString().padStart(2, '0')],
|
|
101
|
+
['{time-tweet-mi}', new Date(legacy.createdAt).getMinutes().toString().padStart(2, '0')],
|
|
102
|
+
['{time-tweet-ss}', new Date(legacy.createdAt).getSeconds().toString().padStart(2, '0')],
|
|
90
103
|
];
|
|
91
|
-
const repOutput =
|
|
92
|
-
const video = repOutput.split('.').pop()
|
|
93
|
-
const pngOutput = video ? repOutput.
|
|
94
|
-
const render = new
|
|
104
|
+
const repOutput = replaceData.reduce((acc, [k, v]) => acc.replaceAll(new RegExp(k, 'g'), v), output);
|
|
105
|
+
const video = repOutput.split('.').pop() !== 'png';
|
|
106
|
+
const pngOutput = video ? repOutput.split('.').slice(0, -1).join('.') + '.png' : repOutput;
|
|
107
|
+
const render = new Theme({
|
|
95
108
|
...themeParam,
|
|
96
|
-
video
|
|
109
|
+
video,
|
|
97
110
|
});
|
|
98
|
-
handler && handler({ type: 'image', user: data.user.legacy.screenName
|
|
111
|
+
handler && handler({ id: data.tweet.restId, type: 'image', user: data.user.legacy.screenName });
|
|
99
112
|
const element = render.imageRender({
|
|
100
|
-
data
|
|
113
|
+
data,
|
|
101
114
|
});
|
|
102
115
|
const img = new ImageResponse(element, {
|
|
103
|
-
width: themeParam.width,
|
|
104
|
-
height: undefined,
|
|
105
116
|
emoji: 'twemoji',
|
|
117
|
+
height: undefined,
|
|
118
|
+
width: themeParam.width,
|
|
106
119
|
});
|
|
107
120
|
const png = Buffer.from(await img.arrayBuffer());
|
|
108
121
|
if (pngOutput.split('/').length > 1) {
|
|
@@ -110,24 +123,20 @@ const twitterRender = (data) => {
|
|
|
110
123
|
}
|
|
111
124
|
await fs.writeFile(pngOutput, png);
|
|
112
125
|
if (video) {
|
|
113
|
-
handler && handler({ type: 'video', user: data.user.legacy.screenName
|
|
126
|
+
handler && handler({ id: data.tweet.restId, type: 'video', user: data.user.legacy.screenName });
|
|
114
127
|
const res = await render.videoRender({
|
|
115
|
-
data
|
|
128
|
+
data,
|
|
116
129
|
image: pngOutput,
|
|
117
130
|
output: repOutput,
|
|
118
131
|
});
|
|
119
132
|
return finalize(res.temp);
|
|
120
133
|
}
|
|
121
|
-
|
|
122
|
-
return finalize([]);
|
|
123
|
-
}
|
|
134
|
+
return finalize([]);
|
|
124
135
|
};
|
|
125
136
|
};
|
|
126
|
-
const finalize = async (temp) => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
};
|
|
137
|
+
const finalize = async (temp) => async ({ cleanup }) => {
|
|
138
|
+
if (cleanup) {
|
|
139
|
+
await Promise.all(temp.map((e) => fs.rm(e)));
|
|
140
|
+
}
|
|
132
141
|
};
|
|
133
142
|
//# sourceMappingURL=core.js.map
|