@vacantthinker/firefox-addon-framework-easy 2026.613.2158 → 2026.614.1535
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/dist/browserNotification.d.ts +10 -4
- package/dist/browserNotification.d.ts.map +1 -1
- package/dist/browserNotification.js +18 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/serviceCommon.d.ts.map +1 -1
- package/dist/serviceCommon.js +4 -3
- package/dist/serviceOpContent.d.ts +13 -1
- package/dist/serviceOpContent.d.ts.map +1 -1
- package/dist/serviceOpContent.js +98 -1
- package/dist/serviceOpContentJsYTB.d.ts +38 -0
- package/dist/serviceOpContentJsYTB.d.ts.map +1 -0
- package/dist/serviceOpContentJsYTB.js +93 -0
- package/dist/serviceOpJavascript.d.ts.map +1 -1
- package/dist/serviceOpJavascript.js +51 -19
- package/dist/serviceOperationYTB.d.ts +9 -5
- package/dist/serviceOperationYTB.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/generate.d.ts +0 -13
- package/dist/generate.d.ts.map +0 -1
- package/dist/generate.js +0 -99
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
export interface NotificationTwoOptions {
|
|
2
|
+
message: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function browserNotificationCreateBasicMessageOnly(message: string): Promise<string>;
|
|
1
6
|
/**
|
|
2
|
-
* Creates a browser notification with basic type
|
|
3
|
-
*
|
|
4
|
-
* @param title The notification title (defaults to manifest name).
|
|
7
|
+
* Creates a browser notification with basic type,
|
|
8
|
+
* if title null use addon manifest name.
|
|
5
9
|
* @returns The notification identifier.
|
|
10
|
+
* @param notificationTwoOptions
|
|
6
11
|
*/
|
|
7
|
-
export declare function
|
|
12
|
+
export declare function browserNotificationCreateBasicMessage(notificationTwoOptions: NotificationTwoOptions): Promise<string>;
|
|
13
|
+
export declare function browserNotificationCreate(notificationOptions: browser.notifications.CreateNotificationOptions): Promise<string>;
|
|
8
14
|
//# sourceMappingURL=browserNotification.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserNotification.d.ts","sourceRoot":"","sources":["../src/browserNotification.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browserNotification.d.ts","sourceRoot":"","sources":["../src/browserNotification.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,yCAAyC,CAC7D,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED;;;;;GAKG;AACH,wBAAsB,qCAAqC,CACzD,sBAAsB,EAAE,sBAAsB,GAC7C,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED,wBAAsB,yBAAyB,CAC7C,mBAAmB,EAAE,OAAO,CAAC,aAAa,CAAC,yBAAyB,GACnE,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { browserRuntimeManifestName } from './browserRuntime';
|
|
2
|
+
export async function browserNotificationCreateBasicMessageOnly(message) {
|
|
3
|
+
return await browserNotificationCreateBasicMessage({ message });
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
|
-
* Creates a browser notification with basic type
|
|
4
|
-
*
|
|
5
|
-
* @param title The notification title (defaults to manifest name).
|
|
6
|
+
* Creates a browser notification with basic type,
|
|
7
|
+
* if title null use addon manifest name.
|
|
6
8
|
* @returns The notification identifier.
|
|
9
|
+
* @param notificationTwoOptions
|
|
7
10
|
*/
|
|
8
|
-
export async function
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
+
export async function browserNotificationCreateBasicMessage(notificationTwoOptions) {
|
|
12
|
+
const notificationOptions = {
|
|
13
|
+
message: "",
|
|
11
14
|
type: 'basic',
|
|
12
|
-
title:
|
|
13
|
-
message: content,
|
|
15
|
+
title: browserRuntimeManifestName()
|
|
14
16
|
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
const options = {
|
|
18
|
+
...notificationOptions, ...notificationTwoOptions
|
|
19
|
+
};
|
|
20
|
+
return await browserNotificationCreate(options);
|
|
21
|
+
}
|
|
22
|
+
export async function browserNotificationCreate(notificationOptions) {
|
|
23
|
+
return await browser.notifications.create(notificationOptions);
|
|
17
24
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ export * from './browserDownload';
|
|
|
3
3
|
export * from './browserNotification';
|
|
4
4
|
export * from './browserRuntime';
|
|
5
5
|
export * from './browserTab';
|
|
6
|
-
export * from './generate';
|
|
7
6
|
export * from './opStorage';
|
|
8
7
|
export * from './opTab';
|
|
9
8
|
export * from './serviceCommon';
|
|
10
9
|
export * from './serviceFetch';
|
|
11
10
|
export * from './serviceGet';
|
|
11
|
+
export * from './serviceOpContentJsYTB';
|
|
12
12
|
export * from './serviceOpContent';
|
|
13
13
|
export * from './serviceOperationYTB';
|
|
14
14
|
export * from './serviceOpJavascript';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@ export * from './browserDownload';
|
|
|
3
3
|
export * from './browserNotification';
|
|
4
4
|
export * from './browserRuntime';
|
|
5
5
|
export * from './browserTab';
|
|
6
|
-
export * from './generate';
|
|
7
6
|
export * from './opStorage';
|
|
8
7
|
export * from './opTab';
|
|
9
8
|
export * from './serviceCommon';
|
|
10
9
|
export * from './serviceFetch';
|
|
11
10
|
export * from './serviceGet';
|
|
11
|
+
export * from './serviceOpContentJsYTB';
|
|
12
12
|
export * from './serviceOpContent';
|
|
13
13
|
export * from './serviceOperationYTB';
|
|
14
14
|
export * from './serviceOpJavascript';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceCommon.d.ts","sourceRoot":"","sources":["../src/serviceCommon.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACf,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"serviceCommon.d.ts","sourceRoot":"","sources":["../src/serviceCommon.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACf,MAAM,mBAAmB,CAAC;AAS3B;;GAEG;AACH,wBAAsB,iBAAiB,kBAGtC;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBrF"}
|
package/dist/serviceCommon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { browserDownloadByDownlink } from './browserDownload';
|
|
2
|
-
import {
|
|
2
|
+
import { browserNotificationCreateBasicMessageOnly } from './browserNotification';
|
|
3
3
|
import { stoOpClear } from "./opStorage";
|
|
4
4
|
import { browserRuntimeReload } from "./browserRuntime";
|
|
5
5
|
/**
|
|
@@ -19,11 +19,12 @@ export async function serviceDownloadByDownlink(params) {
|
|
|
19
19
|
try {
|
|
20
20
|
// Attempt 1: Full download with provided parameters
|
|
21
21
|
await browserDownloadByDownlink(params);
|
|
22
|
-
await
|
|
22
|
+
await browserNotificationCreateBasicMessageOnly(`downloading! ${filename ??
|
|
23
|
+
'file'}`);
|
|
23
24
|
}
|
|
24
25
|
catch (error) {
|
|
25
26
|
// Notify about the failure
|
|
26
|
-
await
|
|
27
|
+
await browserNotificationCreateBasicMessageOnly(`reason=${error}`);
|
|
27
28
|
// Attempt 2: Fallback retry using only the downlink
|
|
28
29
|
await browserDownloadByDownlink({ downlink });
|
|
29
30
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
interface VideoInfo {
|
|
2
|
+
vid: string;
|
|
3
|
+
videoTitle: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Generates an executable script for Windows.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateMkvScriptForSystemWindows(videoInfo: VideoInfo): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generates a bash script for Fedora.
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateMkvScriptForSystemFedora(videoInfo: VideoInfo): string;
|
|
2
13
|
/**
|
|
3
14
|
* Copies text content to the system clipboard.
|
|
4
15
|
*/
|
|
@@ -21,4 +32,5 @@ export declare function serviceGenerateMkvToolNixScript(videoInfo: VideoInfo): P
|
|
|
21
32
|
* @returns A cleaned filename string.
|
|
22
33
|
*/
|
|
23
34
|
export declare function serviceRemoveIllegalWord(value: string): string;
|
|
35
|
+
export {};
|
|
24
36
|
//# sourceMappingURL=serviceOpContent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceOpContent.d.ts","sourceRoot":"","sources":["../src/serviceOpContent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serviceOpContent.d.ts","sourceRoot":"","sources":["../src/serviceOpContent.ts"],"names":[],"mappings":"AAEA,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAwED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAc9E;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAsB7E;AAYD;;GAEG;AACH,wBAAsB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAc,GAClB,IAAI,CAiBN;AAED;;;GAGG;AACH,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBrC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA+B9D"}
|
package/dist/serviceOpContent.js
CHANGED
|
@@ -1,5 +1,102 @@
|
|
|
1
1
|
import { browserRuntimePlatformInfo } from './browserRuntime';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Common Node.js script template with interactive error handling.
|
|
4
|
+
*/
|
|
5
|
+
function getMkvMergeNodeScript(videoInfo, mkvMergePath, openCommand) {
|
|
6
|
+
return `
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const { execSync } = require('child_process');
|
|
10
|
+
const readline = require('readline');
|
|
11
|
+
|
|
12
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
13
|
+
|
|
14
|
+
// Interactive helper to wait for user input before exiting
|
|
15
|
+
const waitAndExit = (msg, isError = true) => {
|
|
16
|
+
if (isError) console.error('\\n[ERROR]: ' + msg);
|
|
17
|
+
else console.log('\\n[INFO]: ' + msg);
|
|
18
|
+
|
|
19
|
+
rl.question('\\nPress Enter to exit...', () => {
|
|
20
|
+
rl.close();
|
|
21
|
+
process.exit(isError ? 1 : 0);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const { vid, videoTitle } = ${JSON.stringify(videoInfo)};
|
|
26
|
+
const pathDownload = __dirname;
|
|
27
|
+
const pathMKVOutput = path.join(pathDownload, \`\${videoTitle}.mkv\`);
|
|
28
|
+
const pathOutput = path.join(pathDownload, \`\${vid}.mkv\`);
|
|
29
|
+
const pathInputAudio = path.join(pathDownload, \`\${vid}.mp3\`);
|
|
30
|
+
const pathInputVideo = path.join(pathDownload, \`\${vid}.mp4\`);
|
|
31
|
+
|
|
32
|
+
if (fs.existsSync("${mkvMergePath}")) {
|
|
33
|
+
console.log('Merging: ' + videoTitle);
|
|
34
|
+
|
|
35
|
+
const cmd = [
|
|
36
|
+
'"${mkvMergePath}"',
|
|
37
|
+
'-o', '"' + pathOutput + '"',
|
|
38
|
+
'--no-video', '"' + pathInputAudio + '"',
|
|
39
|
+
'--no-audio', '"' + pathInputVideo + '"'
|
|
40
|
+
].join(' ');
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
44
|
+
|
|
45
|
+
// Cleanup temporary files
|
|
46
|
+
if (fs.existsSync(pathInputVideo)) fs.unlinkSync(pathInputVideo);
|
|
47
|
+
if (fs.existsSync(pathInputAudio)) fs.unlinkSync(pathInputAudio);
|
|
48
|
+
|
|
49
|
+
// Finalize
|
|
50
|
+
fs.renameSync(pathOutput, pathMKVOutput);
|
|
51
|
+
|
|
52
|
+
console.log('Merge complete.');
|
|
53
|
+
// Optional: open the file
|
|
54
|
+
if ("${openCommand}") {
|
|
55
|
+
execSync(\`\${"${openCommand}"} "\${pathMKVOutput}"\`);
|
|
56
|
+
}
|
|
57
|
+
waitAndExit('Process completed successfully.', false);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
waitAndExit('Processing failed: ' + err.message);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
waitAndExit('mkvmerge not found at: ${mkvMergePath}. Please check installation.');
|
|
63
|
+
}
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Generates an executable script for Windows.
|
|
68
|
+
*/
|
|
69
|
+
export function generateMkvScriptForSystemWindows(videoInfo) {
|
|
70
|
+
const nodeScript = getMkvMergeNodeScript(videoInfo, 'C:\\Program Files\\MKVToolNix\\mkvmerge.exe', '');
|
|
71
|
+
return `(function() {
|
|
72
|
+
const fs = require('fs');
|
|
73
|
+
${nodeScript}
|
|
74
|
+
|
|
75
|
+
// Cleanup script file after user presses enter
|
|
76
|
+
// (Wait for process exit handled inside getMkvMergeNodeScript)
|
|
77
|
+
})();`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Generates a bash script for Fedora.
|
|
81
|
+
*/
|
|
82
|
+
export function generateMkvScriptForSystemFedora(videoInfo) {
|
|
83
|
+
const nodeScript = getMkvMergeNodeScript(videoInfo, '/usr/bin/mkvmerge', 'xdg-open');
|
|
84
|
+
return `#!/usr/bin/env bash
|
|
85
|
+
|
|
86
|
+
# Ensure execution in a visible terminal window
|
|
87
|
+
if [ -z "$VTE_VERSION" ] && [ -z "$ALACRITTY_WINDOW_ID" ] && [ -z "$KITTY_WINDOW_ID" ] && [ "$1" != "--child" ]; then
|
|
88
|
+
gnome-terminal -- "$0" --child
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# Run Node.js logic
|
|
93
|
+
node << 'EOF'
|
|
94
|
+
${nodeScript}
|
|
95
|
+
EOF
|
|
96
|
+
|
|
97
|
+
rm -- "$0"
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
3
100
|
/**
|
|
4
101
|
* Maps file extensions to MIME types.
|
|
5
102
|
*/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captures an <img> element from the current document, draws it to a canvas
|
|
3
|
+
* matching its expected YouTube aspect ratio dimensions, and triggers a
|
|
4
|
+
* browser download.
|
|
5
|
+
* * @param filename - The name to save the downloaded file as.
|
|
6
|
+
* @param filename
|
|
7
|
+
* @param querySelector - Optional custom selector if you aren't targeting the
|
|
8
|
+
* first <img>.
|
|
9
|
+
*/
|
|
10
|
+
export declare function ctJsDownloadYoutubeImageViaCanvas(filename: string, querySelector?: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Delays execution for a random period to emulate human actions and bypass
|
|
13
|
+
* anti-bot detections.
|
|
14
|
+
* @param {number} min - Minimum duration in milliseconds.
|
|
15
|
+
* @param {number} max - Maximum duration in milliseconds.
|
|
16
|
+
* @returns {Promise<void>}
|
|
17
|
+
*/
|
|
18
|
+
export declare function ctJsRandomSleep(min: number, max: number): Promise<void>;
|
|
19
|
+
export declare function ctJsRandomSleep2001_2500(): Promise<void>;
|
|
20
|
+
export declare function ctJsRandomSleep1501_2000(): Promise<void>;
|
|
21
|
+
export declare function ctJsRandomSleep1001_1500(): Promise<void>;
|
|
22
|
+
export declare function ctJsRandomSleep501_1000(): Promise<void>;
|
|
23
|
+
export declare function ctJsRandomSleep501_800(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Safely isolates numerals from alphanumeric video quality markers (e.g.,
|
|
26
|
+
* "1080p" -> "1080").
|
|
27
|
+
* @param {string} text - Raw textual value containing targeting resolution
|
|
28
|
+
* details.
|
|
29
|
+
* @returns {string} Normalized string representation of numbers, or "unknown".
|
|
30
|
+
*/
|
|
31
|
+
export declare function ctJsExtractVideoQualityFromText(text: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Establishes a persistent baseline connection with the background script to
|
|
34
|
+
* maintain runtime context.
|
|
35
|
+
*/
|
|
36
|
+
export declare function ctJskeepAlive(tag?: string, enableLog?: boolean): void;
|
|
37
|
+
export declare function ctJsClsoeTab(): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=serviceOpContentJsYTB.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceOpContentJsYTB.d.ts","sourceRoot":"","sources":["../src/serviceOpContentJsYTB.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,GAAE,MAAc,GAAG,IAAI,CAmCvG;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE;AAED,wBAAsB,wBAAwB,kBAE7C;AAED,wBAAsB,wBAAwB,kBAE7C;AAED,wBAAsB,wBAAwB,kBAE7C;AAED,wBAAsB,uBAAuB,kBAE5C;AAED,wBAAsB,sBAAsB,kBAE3C;AAGD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAW,EAAE,SAAS,UAAQ,QAShE;AAED,wBAAsB,YAAY,kBAIjC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captures an <img> element from the current document, draws it to a canvas
|
|
3
|
+
* matching its expected YouTube aspect ratio dimensions, and triggers a
|
|
4
|
+
* browser download.
|
|
5
|
+
* * @param filename - The name to save the downloaded file as.
|
|
6
|
+
* @param filename
|
|
7
|
+
* @param querySelector - Optional custom selector if you aren't targeting the
|
|
8
|
+
* first <img>.
|
|
9
|
+
*/
|
|
10
|
+
export function ctJsDownloadYoutubeImageViaCanvas(filename, querySelector = 'img') {
|
|
11
|
+
const img = document.body.querySelector(querySelector);
|
|
12
|
+
if (!img) {
|
|
13
|
+
console.warn("downloadYoutubeImageViaCanvas: No image element found on the page.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
// Map YouTube naturalWidths to their expected canvas proportions (handling
|
|
17
|
+
// black bars)
|
|
18
|
+
const sizes = new Map();
|
|
19
|
+
sizes.set(1280, { w: 1280, h: 720 });
|
|
20
|
+
sizes.set(320, { w: 1280, h: 720 });
|
|
21
|
+
sizes.set(640, { w: 1280, h: 900 });
|
|
22
|
+
sizes.set(480, { w: 1280, h: 900 });
|
|
23
|
+
const { w, h } = sizes.get(img.naturalWidth) || {
|
|
24
|
+
w: img.naturalWidth,
|
|
25
|
+
h: img.naturalHeight
|
|
26
|
+
};
|
|
27
|
+
const canvas = document.createElement('canvas');
|
|
28
|
+
canvas.width = w;
|
|
29
|
+
canvas.height = h;
|
|
30
|
+
const ctx = canvas.getContext('2d');
|
|
31
|
+
if (!ctx)
|
|
32
|
+
return;
|
|
33
|
+
ctx.drawImage(img, 0, 0, w, h);
|
|
34
|
+
const canvasUrl = canvas.toDataURL('image/jpeg', 1.0);
|
|
35
|
+
const eleA = document.createElement('a');
|
|
36
|
+
eleA.href = canvasUrl;
|
|
37
|
+
eleA.download = filename;
|
|
38
|
+
eleA.click();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Delays execution for a random period to emulate human actions and bypass
|
|
42
|
+
* anti-bot detections.
|
|
43
|
+
* @param {number} min - Minimum duration in milliseconds.
|
|
44
|
+
* @param {number} max - Maximum duration in milliseconds.
|
|
45
|
+
* @returns {Promise<void>}
|
|
46
|
+
*/
|
|
47
|
+
export function ctJsRandomSleep(min, max) {
|
|
48
|
+
return new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (max - min + 1)) +
|
|
49
|
+
min));
|
|
50
|
+
}
|
|
51
|
+
export async function ctJsRandomSleep2001_2500() {
|
|
52
|
+
await ctJsRandomSleep(2001, 2500);
|
|
53
|
+
}
|
|
54
|
+
export async function ctJsRandomSleep1501_2000() {
|
|
55
|
+
await ctJsRandomSleep(1501, 2000);
|
|
56
|
+
}
|
|
57
|
+
export async function ctJsRandomSleep1001_1500() {
|
|
58
|
+
await ctJsRandomSleep(1001, 1500);
|
|
59
|
+
}
|
|
60
|
+
export async function ctJsRandomSleep501_1000() {
|
|
61
|
+
await ctJsRandomSleep(501, 1000);
|
|
62
|
+
}
|
|
63
|
+
export async function ctJsRandomSleep501_800() {
|
|
64
|
+
await ctJsRandomSleep(501, 800);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Safely isolates numerals from alphanumeric video quality markers (e.g.,
|
|
68
|
+
* "1080p" -> "1080").
|
|
69
|
+
* @param {string} text - Raw textual value containing targeting resolution
|
|
70
|
+
* details.
|
|
71
|
+
* @returns {string} Normalized string representation of numbers, or "unknown".
|
|
72
|
+
*/
|
|
73
|
+
export function ctJsExtractVideoQualityFromText(text) {
|
|
74
|
+
const num = parseInt(text, 10);
|
|
75
|
+
return Number.isNaN(num) ? 'unknown' : num.toString();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Establishes a persistent baseline connection with the background script to
|
|
79
|
+
* maintain runtime context.
|
|
80
|
+
*/
|
|
81
|
+
export function ctJskeepAlive(tag = "", enableLog = false) {
|
|
82
|
+
setInterval(async () => {
|
|
83
|
+
if (enableLog) {
|
|
84
|
+
console.log(tag, "br send message actMarco");
|
|
85
|
+
}
|
|
86
|
+
await browser.runtime.sendMessage({ act: 'actMarco' });
|
|
87
|
+
}, 1000);
|
|
88
|
+
}
|
|
89
|
+
export async function ctJsClsoeTab() {
|
|
90
|
+
await browser.runtime.sendMessage({
|
|
91
|
+
act: 'actRemoveCurrentTab',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceOpJavascript.d.ts","sourceRoot":"","sources":["../src/serviceOpJavascript.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serviceOpJavascript.d.ts","sourceRoot":"","sources":["../src/serviceOpJavascript.ts"],"names":[],"mappings":"AAaA,UAAU,UAAU;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,iBACR,SAAQ,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,CAAC,EAAE,WAAW,GAAG,KAAK,GAAG,iBAAiB,CAAC;CACxD;AAID;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,EACE,KAAK,EACL,QAAQ,EACR,IAAI,EACL,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAA;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+HhF;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtF;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCxF;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCzF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { serviceGetCurrentDateYYYYMMDDHHMMSS } from './serviceGet';
|
|
2
2
|
import { serviceCopyContentToClipboard, serviceRemoveIllegalWord, serviceSaveContentToLocal, } from './serviceOpContent';
|
|
3
|
-
import {
|
|
3
|
+
import { browserNotificationCreateBasicMessageOnly } from './browserNotification';
|
|
4
4
|
// --- Services ---
|
|
5
5
|
/**
|
|
6
6
|
* Captures a tab's screenshot and triggers a local download in the target tab.
|
|
@@ -9,7 +9,12 @@ export async function serviceTakeScreenshot({ tabId, filename, rect }) {
|
|
|
9
9
|
const dataURI = await browser.tabs.captureTab(tabId, { rect });
|
|
10
10
|
await browser.scripting.executeScript({
|
|
11
11
|
target: { tabId },
|
|
12
|
-
args: [
|
|
12
|
+
args: [
|
|
13
|
+
{
|
|
14
|
+
dataURI,
|
|
15
|
+
filename
|
|
16
|
+
}
|
|
17
|
+
],
|
|
13
18
|
func: (message) => {
|
|
14
19
|
const { dataURI, filename } = message;
|
|
15
20
|
const a = document.createElement('a');
|
|
@@ -45,7 +50,9 @@ export async function serviceElementPicker(message) {
|
|
|
45
50
|
function getUniqueSelector(el) {
|
|
46
51
|
const path = [];
|
|
47
52
|
let current = el;
|
|
48
|
-
while (current &&
|
|
53
|
+
while (current &&
|
|
54
|
+
current.nodeType ===
|
|
55
|
+
Node.ELEMENT_NODE) {
|
|
49
56
|
let selector = current.nodeName.toLowerCase();
|
|
50
57
|
if (current.id) {
|
|
51
58
|
selector += `#${current.id}`;
|
|
@@ -54,10 +61,14 @@ export async function serviceElementPicker(message) {
|
|
|
54
61
|
}
|
|
55
62
|
else {
|
|
56
63
|
let sib = current, nth = 1;
|
|
57
|
-
while ((sib = sib.previousElementSibling) &&
|
|
64
|
+
while ((sib = sib.previousElementSibling) &&
|
|
65
|
+
sib.nodeName.toLowerCase() ===
|
|
66
|
+
selector)
|
|
58
67
|
nth++;
|
|
59
|
-
if (nth !==
|
|
68
|
+
if (nth !==
|
|
69
|
+
1) {
|
|
60
70
|
selector += `:nth-of-type(${nth})`;
|
|
71
|
+
}
|
|
61
72
|
}
|
|
62
73
|
path.unshift(selector);
|
|
63
74
|
current = current.parentElement;
|
|
@@ -66,13 +77,18 @@ export async function serviceElementPicker(message) {
|
|
|
66
77
|
}
|
|
67
78
|
function handleMouseOver(e) {
|
|
68
79
|
const target = e.target;
|
|
69
|
-
if (target.id ===
|
|
80
|
+
if (target.id ===
|
|
81
|
+
overlayId ||
|
|
82
|
+
!overlay) {
|
|
70
83
|
return;
|
|
84
|
+
}
|
|
71
85
|
const rect = target.getBoundingClientRect();
|
|
72
86
|
Object.assign(overlay.style, {
|
|
73
87
|
display: 'block',
|
|
74
|
-
top: `${rect.top}px`,
|
|
75
|
-
|
|
88
|
+
top: `${rect.top}px`,
|
|
89
|
+
left: `${rect.left}px`,
|
|
90
|
+
width: `${rect.width}px`,
|
|
91
|
+
height: `${rect.height}px`,
|
|
76
92
|
});
|
|
77
93
|
document.body.style.setProperty('cursor', 'crosshair', 'important');
|
|
78
94
|
}
|
|
@@ -85,8 +101,10 @@ export async function serviceElementPicker(message) {
|
|
|
85
101
|
const rect = {
|
|
86
102
|
height: clientRect.height,
|
|
87
103
|
width: clientRect.width,
|
|
88
|
-
x: clientRect.left +
|
|
89
|
-
|
|
104
|
+
x: clientRect.left +
|
|
105
|
+
window.scrollX,
|
|
106
|
+
y: clientRect.top +
|
|
107
|
+
window.scrollY,
|
|
90
108
|
};
|
|
91
109
|
await browser.runtime.sendMessage({
|
|
92
110
|
...message,
|
|
@@ -114,11 +132,15 @@ export async function serviceGetFullPageRectData(message) {
|
|
|
114
132
|
args: [message],
|
|
115
133
|
func: (message) => {
|
|
116
134
|
const rect = {
|
|
117
|
-
x: 0,
|
|
135
|
+
x: 0,
|
|
136
|
+
y: 0,
|
|
118
137
|
width: document.documentElement.scrollWidth,
|
|
119
138
|
height: document.documentElement.scrollHeight,
|
|
120
139
|
};
|
|
121
|
-
browser.runtime.sendMessage({
|
|
140
|
+
browser.runtime.sendMessage({
|
|
141
|
+
...message,
|
|
142
|
+
rect
|
|
143
|
+
});
|
|
122
144
|
},
|
|
123
145
|
});
|
|
124
146
|
}
|
|
@@ -136,18 +158,22 @@ export async function serviceFindAllMagnetLink(message) {
|
|
|
136
158
|
attrElements.forEach(el => {
|
|
137
159
|
Array.from(el.attributes)
|
|
138
160
|
.forEach(attr => {
|
|
139
|
-
if (attr.value.includes('magnet:?xt='))
|
|
161
|
+
if (attr.value.includes('magnet:?xt=')) {
|
|
140
162
|
magnets.add(attr.value.trim());
|
|
163
|
+
}
|
|
141
164
|
});
|
|
142
165
|
});
|
|
143
166
|
// Type 2: Text content
|
|
144
167
|
document.querySelectorAll('div, span, td, p, a, button')
|
|
145
168
|
.forEach(el => {
|
|
146
|
-
if (el.children.length ===
|
|
147
|
-
|
|
169
|
+
if (el.children.length ===
|
|
170
|
+
0) {
|
|
171
|
+
const text = el.textContent?.trim() ||
|
|
172
|
+
'';
|
|
148
173
|
const match = text.match(/magnet:\?xt=[^\s"'<>]+/);
|
|
149
|
-
if (match)
|
|
174
|
+
if (match) {
|
|
150
175
|
magnets.add(match[0]);
|
|
176
|
+
}
|
|
151
177
|
}
|
|
152
178
|
});
|
|
153
179
|
await browser.runtime.sendMessage({
|
|
@@ -163,12 +189,18 @@ export async function serviceFindAllMagnetLink(message) {
|
|
|
163
189
|
export async function serviceDealWithMagnetLink(message) {
|
|
164
190
|
const { title, data, handleOption } = message;
|
|
165
191
|
const titleCleaned = serviceRemoveIllegalWord(title);
|
|
166
|
-
if (!Array.isArray(data) ||
|
|
167
|
-
|
|
192
|
+
if (!Array.isArray(data) ||
|
|
193
|
+
data.length ===
|
|
194
|
+
0) {
|
|
195
|
+
await browserNotificationCreateBasicMessageOnly('magnet link not found!');
|
|
168
196
|
return;
|
|
169
197
|
}
|
|
170
198
|
const content = `${data.join('\n')}\n`;
|
|
171
|
-
const filename = [
|
|
199
|
+
const filename = [
|
|
200
|
+
'magnet-link',
|
|
201
|
+
titleCleaned,
|
|
202
|
+
serviceGetCurrentDateYYYYMMDDHHMMSS()
|
|
203
|
+
].join(' ');
|
|
172
204
|
switch (handleOption) {
|
|
173
205
|
case 'clipboard':
|
|
174
206
|
await serviceCopyContentToClipboard(content);
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
interface VideoLinkInfoYTB {
|
|
2
2
|
videolink: string;
|
|
3
3
|
vid: string;
|
|
4
4
|
}
|
|
5
|
-
export interface
|
|
6
|
-
playlistVideolink: string;
|
|
5
|
+
export interface PlaylistLinkInfoYTB {
|
|
7
6
|
playlistId: string;
|
|
7
|
+
playlistVideolink: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PlaylistInfoYTB extends PlaylistLinkInfoYTB {
|
|
10
|
+
playlistTitle: string;
|
|
8
11
|
}
|
|
9
12
|
export type ImageQualityYTB = 'maxresdefault' | 'sddefault' | 'hqdefault' | 'mqdefault';
|
|
10
13
|
export declare function serviceGetImageURLYTB(vid: string, imageQuality: ImageQualityYTB): string;
|
|
@@ -17,9 +20,10 @@ export declare function serviceGetVideolinkByVid(vid: string): string;
|
|
|
17
20
|
* Extracts video ID and creates a clean YouTube URL.
|
|
18
21
|
* Supports: youtube.com/watch?v=, youtu.be/, and youtube.com/shorts/
|
|
19
22
|
*/
|
|
20
|
-
export declare function servicePureVideolinkYTB(videolinkOrigin: string):
|
|
23
|
+
export declare function servicePureVideolinkYTB(videolinkOrigin: string): VideoLinkInfoYTB | null;
|
|
21
24
|
/**
|
|
22
25
|
* Extracts playlist ID and creates a clean YouTube playlist URL.
|
|
23
26
|
*/
|
|
24
|
-
export declare function servicePurePlaylistVideolinkYTB(videolinkOrigin: string):
|
|
27
|
+
export declare function servicePurePlaylistVideolinkYTB(videolinkOrigin: string): PlaylistLinkInfoYTB | null;
|
|
28
|
+
export {};
|
|
25
29
|
//# sourceMappingURL=serviceOperationYTB.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceOperationYTB.d.ts","sourceRoot":"","sources":["../src/serviceOperationYTB.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"serviceOperationYTB.d.ts","sourceRoot":"","sources":["../src/serviceOperationYTB.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAgB,SAAQ,mBAAmB;IACxD,aAAa,EAAE,MAAM,CAAC;CACzB;AAGD,MAAM,MAAM,eAAe,GACrB,eAAe,GACf,WAAW,GACX,WAAW,GACX,WAAW,CAAA;AAEjB,wBAAgB,qBAAqB,CACjC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,eAAe,GAC9B,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAmCxF;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,eAAe,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAoBnG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vacantthinker/firefox-addon-framework-easy",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.0614.1535",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"install_package": "npm install",
|
|
17
|
-
"
|
|
17
|
+
"build_tsc": "tsc"
|
|
18
18
|
},
|
|
19
19
|
"author": "VacantThinker",
|
|
20
20
|
"license": "AGPL-3.0-only",
|
package/dist/generate.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface VideoInfo {
|
|
2
|
-
vid: string;
|
|
3
|
-
videoTitle: string;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Generates an executable script for Windows.
|
|
7
|
-
*/
|
|
8
|
-
export declare function generateMkvScriptForSystemWindows(videoInfo: VideoInfo): string;
|
|
9
|
-
/**
|
|
10
|
-
* Generates a bash script for Fedora.
|
|
11
|
-
*/
|
|
12
|
-
export declare function generateMkvScriptForSystemFedora(videoInfo: VideoInfo): string;
|
|
13
|
-
//# sourceMappingURL=generate.d.ts.map
|
package/dist/generate.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAyED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAc9E;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAsB7E"}
|
package/dist/generate.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Common Node.js script template with interactive error handling.
|
|
3
|
-
*/
|
|
4
|
-
function getMkvMergeNodeScript(videoInfo, mkvMergePath, openCommand) {
|
|
5
|
-
const { vid, videoTitle } = videoInfo;
|
|
6
|
-
return `
|
|
7
|
-
const path = require('path');
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const { execSync } = require('child_process');
|
|
10
|
-
const readline = require('readline');
|
|
11
|
-
|
|
12
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
13
|
-
|
|
14
|
-
// Interactive helper to wait for user input before exiting
|
|
15
|
-
const waitAndExit = (msg, isError = true) => {
|
|
16
|
-
if (isError) console.error('\\n[ERROR]: ' + msg);
|
|
17
|
-
else console.log('\\n[INFO]: ' + msg);
|
|
18
|
-
|
|
19
|
-
rl.question('\\nPress Enter to exit...', () => {
|
|
20
|
-
rl.close();
|
|
21
|
-
process.exit(isError ? 1 : 0);
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const { vid, videoTitle } = ${JSON.stringify(videoInfo)};
|
|
26
|
-
const pathDownload = __dirname;
|
|
27
|
-
const pathMKVOutput = path.join(pathDownload, \`\${videoTitle}.mkv\`);
|
|
28
|
-
const pathOutput = path.join(pathDownload, \`\${vid}.mkv\`);
|
|
29
|
-
const pathInputAudio = path.join(pathDownload, \`\${vid}.mp3\`);
|
|
30
|
-
const pathInputVideo = path.join(pathDownload, \`\${vid}.mp4\`);
|
|
31
|
-
|
|
32
|
-
if (fs.existsSync("${mkvMergePath}")) {
|
|
33
|
-
console.log('Merging: ' + videoTitle);
|
|
34
|
-
|
|
35
|
-
const cmd = [
|
|
36
|
-
'"${mkvMergePath}"',
|
|
37
|
-
'-o', '"' + pathOutput + '"',
|
|
38
|
-
'--no-video', '"' + pathInputAudio + '"',
|
|
39
|
-
'--no-audio', '"' + pathInputVideo + '"'
|
|
40
|
-
].join(' ');
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
execSync(cmd, { stdio: 'inherit' });
|
|
44
|
-
|
|
45
|
-
// Cleanup temporary files
|
|
46
|
-
if (fs.existsSync(pathInputVideo)) fs.unlinkSync(pathInputVideo);
|
|
47
|
-
if (fs.existsSync(pathInputAudio)) fs.unlinkSync(pathInputAudio);
|
|
48
|
-
|
|
49
|
-
// Finalize
|
|
50
|
-
fs.renameSync(pathOutput, pathMKVOutput);
|
|
51
|
-
|
|
52
|
-
console.log('Merge complete.');
|
|
53
|
-
// Optional: open the file
|
|
54
|
-
if ("${openCommand}") {
|
|
55
|
-
execSync(\`\${"${openCommand}"} "\${pathMKVOutput}"\`);
|
|
56
|
-
}
|
|
57
|
-
waitAndExit('Process completed successfully.', false);
|
|
58
|
-
} catch (err) {
|
|
59
|
-
waitAndExit('Processing failed: ' + err.message);
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
waitAndExit('mkvmerge not found at: ${mkvMergePath}. Please check installation.');
|
|
63
|
-
}
|
|
64
|
-
`;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Generates an executable script for Windows.
|
|
68
|
-
*/
|
|
69
|
-
export function generateMkvScriptForSystemWindows(videoInfo) {
|
|
70
|
-
const nodeScript = getMkvMergeNodeScript(videoInfo, 'C:\\Program Files\\MKVToolNix\\mkvmerge.exe', '');
|
|
71
|
-
return `(function() {
|
|
72
|
-
const fs = require('fs');
|
|
73
|
-
${nodeScript}
|
|
74
|
-
|
|
75
|
-
// Cleanup script file after user presses enter
|
|
76
|
-
// (Wait for process exit handled inside getMkvMergeNodeScript)
|
|
77
|
-
})();`;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Generates a bash script for Fedora.
|
|
81
|
-
*/
|
|
82
|
-
export function generateMkvScriptForSystemFedora(videoInfo) {
|
|
83
|
-
const nodeScript = getMkvMergeNodeScript(videoInfo, '/usr/bin/mkvmerge', 'xdg-open');
|
|
84
|
-
return `#!/usr/bin/env bash
|
|
85
|
-
|
|
86
|
-
# Ensure execution in a visible terminal window
|
|
87
|
-
if [ -z "$VTE_VERSION" ] && [ -z "$ALACRITTY_WINDOW_ID" ] && [ -z "$KITTY_WINDOW_ID" ] && [ "$1" != "--child" ]; then
|
|
88
|
-
gnome-terminal -- "$0" --child
|
|
89
|
-
exit 0
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
# Run Node.js logic
|
|
93
|
-
node << 'EOF'
|
|
94
|
-
${nodeScript}
|
|
95
|
-
EOF
|
|
96
|
-
|
|
97
|
-
rm -- "$0"
|
|
98
|
-
`;
|
|
99
|
-
}
|