wyzie-lib 2.3.0 → 2.5.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 +3 -3
- package/package.json +2 -2
- package/lib/main.amd.js +0 -146
- package/lib/main.cjs +0 -144
- package/lib/main.d.ts +0 -234
- package/lib/main.iife.js +0 -147
- package/lib/main.js +0 -144
- package/lib/main.umd.cjs +0 -148
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://sub.wyzie.
|
|
2
|
+
<a href="https://sub.wyzie.io/">
|
|
3
3
|
<img src="https://i.postimg.cc/L5ppKYC5/cclogo.png" height="120">
|
|
4
4
|
<h1 align="center">Wyzie Lib</h1>
|
|
5
5
|
</a>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
|
-
Wyzie Lib is a package made for easily implementing [Wyzie Subs](https
|
|
9
|
-
project without all the fuss. [Read the docs](https
|
|
8
|
+
Wyzie Lib is a package made for easily implementing [Wyzie Subs](https:
|
|
9
|
+
project without all the fuss. [Read the docs](https:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wyzie-lib",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"icon": "https://i.postimg.cc/L5ppKYC5/cclogo.png",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"repository": {
|
|
59
59
|
"type": "git",
|
|
60
|
-
"url": "git+https://github.com/
|
|
60
|
+
"url": "git+https://github.com/wyziedevs/wyzie-lib.git"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"dev": "vite",
|
package/lib/main.amd.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
define(["exports"], function(exports) {
|
|
2
|
-
"use strict";
|
|
3
|
-
const config = {
|
|
4
|
-
baseUrl: "https://sub.wyzie.ru"
|
|
5
|
-
};
|
|
6
|
-
function configure(options) {
|
|
7
|
-
if (options.baseUrl) {
|
|
8
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
async function constructUrl({
|
|
12
|
-
tmdb_id,
|
|
13
|
-
imdb_id,
|
|
14
|
-
season,
|
|
15
|
-
episode,
|
|
16
|
-
encoding,
|
|
17
|
-
language,
|
|
18
|
-
format,
|
|
19
|
-
source,
|
|
20
|
-
hi,
|
|
21
|
-
...extraParams
|
|
22
|
-
}) {
|
|
23
|
-
if (!tmdb_id && !imdb_id) {
|
|
24
|
-
throw new Error("Either tmdb_id or imdb_id must be provided.");
|
|
25
|
-
}
|
|
26
|
-
const hasSeason = season !== void 0;
|
|
27
|
-
const hasEpisode = episode !== void 0;
|
|
28
|
-
if (hasSeason && !hasEpisode || !hasSeason && hasEpisode) {
|
|
29
|
-
throw new Error("Season and episode must be provided together or omitted together.");
|
|
30
|
-
}
|
|
31
|
-
const url = new URL(`${config.baseUrl}/search`);
|
|
32
|
-
const queryParams = {
|
|
33
|
-
id: String(tmdb_id || imdb_id),
|
|
34
|
-
season,
|
|
35
|
-
episode,
|
|
36
|
-
encoding: Array.isArray(encoding) ? encoding.join(",") : encoding,
|
|
37
|
-
language: Array.isArray(language) ? language.join(",") : language,
|
|
38
|
-
format: Array.isArray(format) ? format.join(",") : format,
|
|
39
|
-
source: Array.isArray(source) ? source.join(",") : source,
|
|
40
|
-
hi
|
|
41
|
-
};
|
|
42
|
-
Object.entries(queryParams).forEach(([key, value]) => {
|
|
43
|
-
if (value !== void 0) {
|
|
44
|
-
url.searchParams.append(key, String(value));
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
Object.entries(extraParams).forEach(([key, value]) => {
|
|
48
|
-
if (value !== void 0) {
|
|
49
|
-
if (Array.isArray(value)) {
|
|
50
|
-
url.searchParams.append(key, value.join(","));
|
|
51
|
-
} else {
|
|
52
|
-
url.searchParams.append(key, String(value));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
return url;
|
|
57
|
-
}
|
|
58
|
-
async function fetchSubtitles(url) {
|
|
59
|
-
const response = await fetch(url.toString());
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
62
|
-
}
|
|
63
|
-
return response.json();
|
|
64
|
-
}
|
|
65
|
-
async function searchSubtitles(params) {
|
|
66
|
-
try {
|
|
67
|
-
const url = await constructUrl(params);
|
|
68
|
-
return await fetchSubtitles(url);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
throw new Error(`Error fetching subtitles: ${error}`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function parseToVTT(subtitleUrl) {
|
|
74
|
-
try {
|
|
75
|
-
const response = await fetch(subtitleUrl);
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
throw new Error(`Failed to fetch subtitle content: ${response.status}`);
|
|
78
|
-
}
|
|
79
|
-
const content = await response.text();
|
|
80
|
-
const normalizedContent = content.replace(/\r\n|\r/g, "\n").trim();
|
|
81
|
-
const blocks = normalizedContent.split(/\n\n+/);
|
|
82
|
-
const timestampRegex = /^\d{1,2}:\d{2}:\d{2}[,.]\d{3}\s*-->\s*\d{1,2}:\d{2}:\d{2}[,.]\d{3}$/;
|
|
83
|
-
const hasValidSRTFormat = blocks.some((block) => {
|
|
84
|
-
const lines = block.split("\n").map((line) => line.trim());
|
|
85
|
-
return lines.some((line) => timestampRegex.test(line));
|
|
86
|
-
});
|
|
87
|
-
if (!hasValidSRTFormat) {
|
|
88
|
-
throw new Error("Invalid subtitle format: not SRT");
|
|
89
|
-
}
|
|
90
|
-
const vttLines = ["WEBVTT", ""];
|
|
91
|
-
for (const block of blocks) {
|
|
92
|
-
const lines = block.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
93
|
-
if (lines.length < 2)
|
|
94
|
-
continue;
|
|
95
|
-
const timestampIndex = lines.findIndex((line) => timestampRegex.test(line));
|
|
96
|
-
if (timestampIndex === -1)
|
|
97
|
-
continue;
|
|
98
|
-
const textLines = lines.slice(timestampIndex + 1).filter((line) => !/^\d+$/.test(line));
|
|
99
|
-
if (textLines.length === 0)
|
|
100
|
-
continue;
|
|
101
|
-
let timestampLine = lines[timestampIndex];
|
|
102
|
-
timestampLine = timestampLine.replace(/[,.](?=\s*-->)/, "").replace(/[,.]$/, "").replace(/,(\d{3})/g, ".$1");
|
|
103
|
-
vttLines.push(`${timestampLine}
|
|
104
|
-
${textLines.join("\n")}
|
|
105
|
-
`);
|
|
106
|
-
}
|
|
107
|
-
return vttLines.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n\n";
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error("Error in parseToVTT:", error);
|
|
110
|
-
throw error;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function searchTmdb(query, language = "en-US") {
|
|
114
|
-
const url = new URL(`${config.baseUrl}/api/tmdb/search`);
|
|
115
|
-
url.searchParams.append("q", query);
|
|
116
|
-
url.searchParams.append("language", language);
|
|
117
|
-
const response = await fetch(url.toString());
|
|
118
|
-
if (!response.ok) {
|
|
119
|
-
throw new Error(`Failed to search TMDB: ${response.status}`);
|
|
120
|
-
}
|
|
121
|
-
return response.json();
|
|
122
|
-
}
|
|
123
|
-
async function getTvDetails(id) {
|
|
124
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}`;
|
|
125
|
-
const response = await fetch(url);
|
|
126
|
-
if (!response.ok) {
|
|
127
|
-
throw new Error(`Failed to fetch TV details: ${response.status}`);
|
|
128
|
-
}
|
|
129
|
-
return response.json();
|
|
130
|
-
}
|
|
131
|
-
async function getSeasonDetails(id, season) {
|
|
132
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}/${season}`;
|
|
133
|
-
const response = await fetch(url);
|
|
134
|
-
if (!response.ok) {
|
|
135
|
-
throw new Error(`Failed to fetch season details: ${response.status}`);
|
|
136
|
-
}
|
|
137
|
-
return response.json();
|
|
138
|
-
}
|
|
139
|
-
exports.configure = configure;
|
|
140
|
-
exports.getSeasonDetails = getSeasonDetails;
|
|
141
|
-
exports.getTvDetails = getTvDetails;
|
|
142
|
-
exports.parseToVTT = parseToVTT;
|
|
143
|
-
exports.searchSubtitles = searchSubtitles;
|
|
144
|
-
exports.searchTmdb = searchTmdb;
|
|
145
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
146
|
-
});
|
package/lib/main.cjs
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const config = {
|
|
4
|
-
baseUrl: "https://sub.wyzie.ru"
|
|
5
|
-
};
|
|
6
|
-
function configure(options) {
|
|
7
|
-
if (options.baseUrl) {
|
|
8
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
async function constructUrl({
|
|
12
|
-
tmdb_id,
|
|
13
|
-
imdb_id,
|
|
14
|
-
season,
|
|
15
|
-
episode,
|
|
16
|
-
encoding,
|
|
17
|
-
language,
|
|
18
|
-
format,
|
|
19
|
-
source,
|
|
20
|
-
hi,
|
|
21
|
-
...extraParams
|
|
22
|
-
}) {
|
|
23
|
-
if (!tmdb_id && !imdb_id) {
|
|
24
|
-
throw new Error("Either tmdb_id or imdb_id must be provided.");
|
|
25
|
-
}
|
|
26
|
-
const hasSeason = season !== void 0;
|
|
27
|
-
const hasEpisode = episode !== void 0;
|
|
28
|
-
if (hasSeason && !hasEpisode || !hasSeason && hasEpisode) {
|
|
29
|
-
throw new Error("Season and episode must be provided together or omitted together.");
|
|
30
|
-
}
|
|
31
|
-
const url = new URL(`${config.baseUrl}/search`);
|
|
32
|
-
const queryParams = {
|
|
33
|
-
id: String(tmdb_id || imdb_id),
|
|
34
|
-
season,
|
|
35
|
-
episode,
|
|
36
|
-
encoding: Array.isArray(encoding) ? encoding.join(",") : encoding,
|
|
37
|
-
language: Array.isArray(language) ? language.join(",") : language,
|
|
38
|
-
format: Array.isArray(format) ? format.join(",") : format,
|
|
39
|
-
source: Array.isArray(source) ? source.join(",") : source,
|
|
40
|
-
hi
|
|
41
|
-
};
|
|
42
|
-
Object.entries(queryParams).forEach(([key, value]) => {
|
|
43
|
-
if (value !== void 0) {
|
|
44
|
-
url.searchParams.append(key, String(value));
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
Object.entries(extraParams).forEach(([key, value]) => {
|
|
48
|
-
if (value !== void 0) {
|
|
49
|
-
if (Array.isArray(value)) {
|
|
50
|
-
url.searchParams.append(key, value.join(","));
|
|
51
|
-
} else {
|
|
52
|
-
url.searchParams.append(key, String(value));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
return url;
|
|
57
|
-
}
|
|
58
|
-
async function fetchSubtitles(url) {
|
|
59
|
-
const response = await fetch(url.toString());
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
62
|
-
}
|
|
63
|
-
return response.json();
|
|
64
|
-
}
|
|
65
|
-
async function searchSubtitles(params) {
|
|
66
|
-
try {
|
|
67
|
-
const url = await constructUrl(params);
|
|
68
|
-
return await fetchSubtitles(url);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
throw new Error(`Error fetching subtitles: ${error}`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function parseToVTT(subtitleUrl) {
|
|
74
|
-
try {
|
|
75
|
-
const response = await fetch(subtitleUrl);
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
throw new Error(`Failed to fetch subtitle content: ${response.status}`);
|
|
78
|
-
}
|
|
79
|
-
const content = await response.text();
|
|
80
|
-
const normalizedContent = content.replace(/\r\n|\r/g, "\n").trim();
|
|
81
|
-
const blocks = normalizedContent.split(/\n\n+/);
|
|
82
|
-
const timestampRegex = /^\d{1,2}:\d{2}:\d{2}[,.]\d{3}\s*-->\s*\d{1,2}:\d{2}:\d{2}[,.]\d{3}$/;
|
|
83
|
-
const hasValidSRTFormat = blocks.some((block) => {
|
|
84
|
-
const lines = block.split("\n").map((line) => line.trim());
|
|
85
|
-
return lines.some((line) => timestampRegex.test(line));
|
|
86
|
-
});
|
|
87
|
-
if (!hasValidSRTFormat) {
|
|
88
|
-
throw new Error("Invalid subtitle format: not SRT");
|
|
89
|
-
}
|
|
90
|
-
const vttLines = ["WEBVTT", ""];
|
|
91
|
-
for (const block of blocks) {
|
|
92
|
-
const lines = block.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
93
|
-
if (lines.length < 2)
|
|
94
|
-
continue;
|
|
95
|
-
const timestampIndex = lines.findIndex((line) => timestampRegex.test(line));
|
|
96
|
-
if (timestampIndex === -1)
|
|
97
|
-
continue;
|
|
98
|
-
const textLines = lines.slice(timestampIndex + 1).filter((line) => !/^\d+$/.test(line));
|
|
99
|
-
if (textLines.length === 0)
|
|
100
|
-
continue;
|
|
101
|
-
let timestampLine = lines[timestampIndex];
|
|
102
|
-
timestampLine = timestampLine.replace(/[,.](?=\s*-->)/, "").replace(/[,.]$/, "").replace(/,(\d{3})/g, ".$1");
|
|
103
|
-
vttLines.push(`${timestampLine}
|
|
104
|
-
${textLines.join("\n")}
|
|
105
|
-
`);
|
|
106
|
-
}
|
|
107
|
-
return vttLines.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n\n";
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error("Error in parseToVTT:", error);
|
|
110
|
-
throw error;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function searchTmdb(query, language = "en-US") {
|
|
114
|
-
const url = new URL(`${config.baseUrl}/api/tmdb/search`);
|
|
115
|
-
url.searchParams.append("q", query);
|
|
116
|
-
url.searchParams.append("language", language);
|
|
117
|
-
const response = await fetch(url.toString());
|
|
118
|
-
if (!response.ok) {
|
|
119
|
-
throw new Error(`Failed to search TMDB: ${response.status}`);
|
|
120
|
-
}
|
|
121
|
-
return response.json();
|
|
122
|
-
}
|
|
123
|
-
async function getTvDetails(id) {
|
|
124
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}`;
|
|
125
|
-
const response = await fetch(url);
|
|
126
|
-
if (!response.ok) {
|
|
127
|
-
throw new Error(`Failed to fetch TV details: ${response.status}`);
|
|
128
|
-
}
|
|
129
|
-
return response.json();
|
|
130
|
-
}
|
|
131
|
-
async function getSeasonDetails(id, season) {
|
|
132
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}/${season}`;
|
|
133
|
-
const response = await fetch(url);
|
|
134
|
-
if (!response.ok) {
|
|
135
|
-
throw new Error(`Failed to fetch season details: ${response.status}`);
|
|
136
|
-
}
|
|
137
|
-
return response.json();
|
|
138
|
-
}
|
|
139
|
-
exports.configure = configure;
|
|
140
|
-
exports.getSeasonDetails = getSeasonDetails;
|
|
141
|
-
exports.getTvDetails = getTvDetails;
|
|
142
|
-
exports.parseToVTT = parseToVTT;
|
|
143
|
-
exports.searchSubtitles = searchSubtitles;
|
|
144
|
-
exports.searchTmdb = searchTmdb;
|
package/lib/main.d.ts
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type for the configuration options for the library.
|
|
3
|
-
*/
|
|
4
|
-
export declare type ConfigurationOptions = {
|
|
5
|
-
/** The API's hostname (default: sub.wyzie.ru) */
|
|
6
|
-
baseUrl: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Configure the library settings.
|
|
11
|
-
*
|
|
12
|
-
* @param {ConfigurationOptions} options - Config options for the library.
|
|
13
|
-
* @throws {Error} Throws an error if the baseUrl is not provided.
|
|
14
|
-
*/
|
|
15
|
-
export declare function configure(options: ConfigurationOptions): void;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Details of a TV Episode.
|
|
19
|
-
*/
|
|
20
|
-
export declare type EpisodeDetails = {
|
|
21
|
-
air_date?: string;
|
|
22
|
-
episode_number: number;
|
|
23
|
-
id: number;
|
|
24
|
-
name: string;
|
|
25
|
-
overview?: string;
|
|
26
|
-
production_code?: string;
|
|
27
|
-
runtime?: number | null;
|
|
28
|
-
season_number: number;
|
|
29
|
-
show_id?: number;
|
|
30
|
-
still_path?: string | null;
|
|
31
|
-
vote_average?: number;
|
|
32
|
-
vote_count?: number;
|
|
33
|
-
[key: string]: any;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Fetches details for a specific season of a TV show from TMDB.
|
|
38
|
-
*
|
|
39
|
-
* @param {number} id - The TMDB ID of the TV show.
|
|
40
|
-
* @param {number} season - The season number.
|
|
41
|
-
* @returns {Promise<SeasonDetails>} A promise that resolves to the season details.
|
|
42
|
-
*/
|
|
43
|
-
export declare function getSeasonDetails(id: number, season: number): Promise<SeasonDetails>;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Fetches details for a TV show from TMDB.
|
|
47
|
-
*
|
|
48
|
-
* @param {number} id - The TMDB ID of the TV show.
|
|
49
|
-
* @returns {Promise<TvDetails>} A promise that resolves to the TV show details.
|
|
50
|
-
*/
|
|
51
|
-
export declare function getTvDetails(id: number): Promise<TvDetails>;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Parses subtitle content from a URL to VTT format.
|
|
55
|
-
*
|
|
56
|
-
* @param {string} subtitleUrl - The URL of the subtitle to parse.
|
|
57
|
-
* @returns {Promise<string>} A promise that resolves to the subtitle content in VTT format.
|
|
58
|
-
* @throws {Error} Throws an error if fetching or parsing the subtitle content fails.
|
|
59
|
-
*/
|
|
60
|
-
export declare function parseToVTT(subtitleUrl: string): Promise<string>;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Parameters used to construct the URL for subtitle search (requires an ID).
|
|
64
|
-
*/
|
|
65
|
-
export declare type QueryParams = {
|
|
66
|
-
/** Unique identifier (either TMDB or IMDB ID). */
|
|
67
|
-
id: string;
|
|
68
|
-
/** Season number if the content is a series. */
|
|
69
|
-
season?: number;
|
|
70
|
-
/** Episode number if the content is a series. */
|
|
71
|
-
episode?: number;
|
|
72
|
-
/** Encoding of the subtitle files. */
|
|
73
|
-
encoding?: string;
|
|
74
|
-
/** ISO 3166 code of the subtitle desired. */
|
|
75
|
-
language?: string;
|
|
76
|
-
/** Which subtitle file format you want */
|
|
77
|
-
format?: string;
|
|
78
|
-
/** Determines if you get a hearing impaired subtitles */
|
|
79
|
-
hi?: boolean;
|
|
80
|
-
/** The source where the subtitle will be scraped from. */
|
|
81
|
-
source?: string;
|
|
82
|
-
/** Filter by specific release group or name. */
|
|
83
|
-
release?: string;
|
|
84
|
-
/** Filter by filename. */
|
|
85
|
-
filename?: string;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Searches for subtitles based on the provided parameters.
|
|
90
|
-
*
|
|
91
|
-
* @param {SearchSubtitlesParams} params - The parameters for searching: SearchSubtitlesParams.
|
|
92
|
-
* @returns {Promise<SubtitleData[]>} A promise that resolves to an array of subtitle data.
|
|
93
|
-
* @throws {Error} Throws an error if fetching subtitles fails or something goes wrong.
|
|
94
|
-
*/
|
|
95
|
-
export declare function searchSubtitles(params: SearchSubtitlesParams): Promise<SubtitleData[]>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Parameters for searching subtitles.
|
|
99
|
-
* Either IMDB or TMDB ID is required and if episode is provided, season is also required.
|
|
100
|
-
*/
|
|
101
|
-
export declare type SearchSubtitlesParams = (
|
|
102
|
-
/** The TMDB ID of the media you want subtitles for (either TMDB or IMDB ID). */
|
|
103
|
-
{
|
|
104
|
-
tmdb_id: number;
|
|
105
|
-
imdb_id?: never;
|
|
106
|
-
}
|
|
107
|
-
/** The IMDB ID of the media you want subtitles for (either TMDB or IMDB ID). */
|
|
108
|
-
| {
|
|
109
|
-
imdb_id: string;
|
|
110
|
-
tmdb_id?: never;
|
|
111
|
-
}) & {
|
|
112
|
-
/** ISO 3166 code or codes of the subtitle desired. */
|
|
113
|
-
language?: string | string[];
|
|
114
|
-
/** The subtitle file's character encoding or encodings. */
|
|
115
|
-
encoding?: string | string[];
|
|
116
|
-
/** Which subtitle file format(s) you want. */
|
|
117
|
-
format?: string | string[];
|
|
118
|
-
/** Determines if you get hearing impaired subtitles. */
|
|
119
|
-
hi?: boolean;
|
|
120
|
-
/** The source where the subtitle will be scraped. Accepts a single value or a list. */
|
|
121
|
-
source?: string | string[];
|
|
122
|
-
/** Filter by specific release group or name. */
|
|
123
|
-
release?: string | string[];
|
|
124
|
-
/** Filter by filename. */
|
|
125
|
-
filename?: string | string[];
|
|
126
|
-
/** Additional parameters that can be used for filtering or other purposes. */
|
|
127
|
-
[key: string]: any;
|
|
128
|
-
} & (
|
|
129
|
-
/** The number of the desired season you want subtitles for. */
|
|
130
|
-
{
|
|
131
|
-
season: number;
|
|
132
|
-
episode: number;
|
|
133
|
-
}
|
|
134
|
-
/** The number of the desired episode you want subtitles for. */
|
|
135
|
-
| {
|
|
136
|
-
season?: never;
|
|
137
|
-
episode?: never;
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Searches TMDB for movies or TV shows.
|
|
142
|
-
*
|
|
143
|
-
* @param {string} query - The search query.
|
|
144
|
-
* @param {string} [language] - Optional language code (default: en-US).
|
|
145
|
-
* @returns {Promise<TmdbSearchResult[]>} A promise that resolves to an array of TMDB search results.
|
|
146
|
-
*/
|
|
147
|
-
export declare function searchTmdb(query: string, language?: string): Promise<TmdbSearchResult[]>;
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Details of a specific TV Season.
|
|
151
|
-
*/
|
|
152
|
-
export declare type SeasonDetails = {
|
|
153
|
-
episodes: EpisodeDetails[];
|
|
154
|
-
season_number: number;
|
|
155
|
-
id: string;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Summary of a TV season.
|
|
160
|
-
*/
|
|
161
|
-
export declare type SeasonSummary = {
|
|
162
|
-
air_date?: string;
|
|
163
|
-
episode_count?: number;
|
|
164
|
-
id: number;
|
|
165
|
-
name: string;
|
|
166
|
-
overview?: string;
|
|
167
|
-
poster_path?: string | null;
|
|
168
|
-
season_number: number;
|
|
169
|
-
vote_average?: number;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Data structure representing a single subtitle object.
|
|
174
|
-
*/
|
|
175
|
-
export declare type SubtitleData = {
|
|
176
|
-
/** Unique identifier (either TMDB or IMDB ID). */
|
|
177
|
-
id: string;
|
|
178
|
-
/** The subtitle file's URL. */
|
|
179
|
-
url: string;
|
|
180
|
-
/** The format of the subtitle file. */
|
|
181
|
-
format: string;
|
|
182
|
-
/** The subtitle file's character encoding. (UTF-8, ASCII, ETC) */
|
|
183
|
-
encoding: string;
|
|
184
|
-
/** Boolean indicating if the subtitle's is hearing impaired. */
|
|
185
|
-
isHearingImpaired: boolean;
|
|
186
|
-
/** URL to a PNG of the flag of the subtitle's language. */
|
|
187
|
-
flagUrl: string;
|
|
188
|
-
/** The name/title of the media. */
|
|
189
|
-
media: string;
|
|
190
|
-
/** The display language; Example: English. */
|
|
191
|
-
display: string;
|
|
192
|
-
/** ISO 3166 code; Example: en (2 alphabetic letters). */
|
|
193
|
-
language: string;
|
|
194
|
-
/** The subtitle's source (ex: subdl, subf2m, opensubtitles). */
|
|
195
|
-
source?: string | string[];
|
|
196
|
-
/** The release name of the subtitle. */
|
|
197
|
-
release?: string;
|
|
198
|
-
/** List of releases compatible with this subtitle. */
|
|
199
|
-
releases?: string[];
|
|
200
|
-
/** The original filename of the subtitle. */
|
|
201
|
-
fileName?: string;
|
|
202
|
-
/** The origin of the subtitle (e.g. DVD, WEB, BluRay). */
|
|
203
|
-
origin?: string;
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Result object from a TMDB search.
|
|
208
|
-
*/
|
|
209
|
-
export declare type TmdbSearchResult = {
|
|
210
|
-
id: number;
|
|
211
|
-
media_type: string;
|
|
212
|
-
title?: string;
|
|
213
|
-
name?: string;
|
|
214
|
-
original_title?: string;
|
|
215
|
-
original_name?: string;
|
|
216
|
-
overview?: string;
|
|
217
|
-
release_date?: string;
|
|
218
|
-
first_air_date?: string;
|
|
219
|
-
poster_path?: string | null;
|
|
220
|
-
backdrop_path?: string | null;
|
|
221
|
-
popularity?: number;
|
|
222
|
-
vote_average?: number;
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Details of a TV Show.
|
|
227
|
-
*/
|
|
228
|
-
export declare type TvDetails = {
|
|
229
|
-
seasons: SeasonSummary[];
|
|
230
|
-
name: string;
|
|
231
|
-
id: number;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
export { }
|
package/lib/main.iife.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
var main = function(exports) {
|
|
2
|
-
"use strict";
|
|
3
|
-
const config = {
|
|
4
|
-
baseUrl: "https://sub.wyzie.ru"
|
|
5
|
-
};
|
|
6
|
-
function configure(options) {
|
|
7
|
-
if (options.baseUrl) {
|
|
8
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
async function constructUrl({
|
|
12
|
-
tmdb_id,
|
|
13
|
-
imdb_id,
|
|
14
|
-
season,
|
|
15
|
-
episode,
|
|
16
|
-
encoding,
|
|
17
|
-
language,
|
|
18
|
-
format,
|
|
19
|
-
source,
|
|
20
|
-
hi,
|
|
21
|
-
...extraParams
|
|
22
|
-
}) {
|
|
23
|
-
if (!tmdb_id && !imdb_id) {
|
|
24
|
-
throw new Error("Either tmdb_id or imdb_id must be provided.");
|
|
25
|
-
}
|
|
26
|
-
const hasSeason = season !== void 0;
|
|
27
|
-
const hasEpisode = episode !== void 0;
|
|
28
|
-
if (hasSeason && !hasEpisode || !hasSeason && hasEpisode) {
|
|
29
|
-
throw new Error("Season and episode must be provided together or omitted together.");
|
|
30
|
-
}
|
|
31
|
-
const url = new URL(`${config.baseUrl}/search`);
|
|
32
|
-
const queryParams = {
|
|
33
|
-
id: String(tmdb_id || imdb_id),
|
|
34
|
-
season,
|
|
35
|
-
episode,
|
|
36
|
-
encoding: Array.isArray(encoding) ? encoding.join(",") : encoding,
|
|
37
|
-
language: Array.isArray(language) ? language.join(",") : language,
|
|
38
|
-
format: Array.isArray(format) ? format.join(",") : format,
|
|
39
|
-
source: Array.isArray(source) ? source.join(",") : source,
|
|
40
|
-
hi
|
|
41
|
-
};
|
|
42
|
-
Object.entries(queryParams).forEach(([key, value]) => {
|
|
43
|
-
if (value !== void 0) {
|
|
44
|
-
url.searchParams.append(key, String(value));
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
Object.entries(extraParams).forEach(([key, value]) => {
|
|
48
|
-
if (value !== void 0) {
|
|
49
|
-
if (Array.isArray(value)) {
|
|
50
|
-
url.searchParams.append(key, value.join(","));
|
|
51
|
-
} else {
|
|
52
|
-
url.searchParams.append(key, String(value));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
return url;
|
|
57
|
-
}
|
|
58
|
-
async function fetchSubtitles(url) {
|
|
59
|
-
const response = await fetch(url.toString());
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
62
|
-
}
|
|
63
|
-
return response.json();
|
|
64
|
-
}
|
|
65
|
-
async function searchSubtitles(params) {
|
|
66
|
-
try {
|
|
67
|
-
const url = await constructUrl(params);
|
|
68
|
-
return await fetchSubtitles(url);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
throw new Error(`Error fetching subtitles: ${error}`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function parseToVTT(subtitleUrl) {
|
|
74
|
-
try {
|
|
75
|
-
const response = await fetch(subtitleUrl);
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
throw new Error(`Failed to fetch subtitle content: ${response.status}`);
|
|
78
|
-
}
|
|
79
|
-
const content = await response.text();
|
|
80
|
-
const normalizedContent = content.replace(/\r\n|\r/g, "\n").trim();
|
|
81
|
-
const blocks = normalizedContent.split(/\n\n+/);
|
|
82
|
-
const timestampRegex = /^\d{1,2}:\d{2}:\d{2}[,.]\d{3}\s*-->\s*\d{1,2}:\d{2}:\d{2}[,.]\d{3}$/;
|
|
83
|
-
const hasValidSRTFormat = blocks.some((block) => {
|
|
84
|
-
const lines = block.split("\n").map((line) => line.trim());
|
|
85
|
-
return lines.some((line) => timestampRegex.test(line));
|
|
86
|
-
});
|
|
87
|
-
if (!hasValidSRTFormat) {
|
|
88
|
-
throw new Error("Invalid subtitle format: not SRT");
|
|
89
|
-
}
|
|
90
|
-
const vttLines = ["WEBVTT", ""];
|
|
91
|
-
for (const block of blocks) {
|
|
92
|
-
const lines = block.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
93
|
-
if (lines.length < 2)
|
|
94
|
-
continue;
|
|
95
|
-
const timestampIndex = lines.findIndex((line) => timestampRegex.test(line));
|
|
96
|
-
if (timestampIndex === -1)
|
|
97
|
-
continue;
|
|
98
|
-
const textLines = lines.slice(timestampIndex + 1).filter((line) => !/^\d+$/.test(line));
|
|
99
|
-
if (textLines.length === 0)
|
|
100
|
-
continue;
|
|
101
|
-
let timestampLine = lines[timestampIndex];
|
|
102
|
-
timestampLine = timestampLine.replace(/[,.](?=\s*-->)/, "").replace(/[,.]$/, "").replace(/,(\d{3})/g, ".$1");
|
|
103
|
-
vttLines.push(`${timestampLine}
|
|
104
|
-
${textLines.join("\n")}
|
|
105
|
-
`);
|
|
106
|
-
}
|
|
107
|
-
return vttLines.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n\n";
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error("Error in parseToVTT:", error);
|
|
110
|
-
throw error;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function searchTmdb(query, language = "en-US") {
|
|
114
|
-
const url = new URL(`${config.baseUrl}/api/tmdb/search`);
|
|
115
|
-
url.searchParams.append("q", query);
|
|
116
|
-
url.searchParams.append("language", language);
|
|
117
|
-
const response = await fetch(url.toString());
|
|
118
|
-
if (!response.ok) {
|
|
119
|
-
throw new Error(`Failed to search TMDB: ${response.status}`);
|
|
120
|
-
}
|
|
121
|
-
return response.json();
|
|
122
|
-
}
|
|
123
|
-
async function getTvDetails(id) {
|
|
124
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}`;
|
|
125
|
-
const response = await fetch(url);
|
|
126
|
-
if (!response.ok) {
|
|
127
|
-
throw new Error(`Failed to fetch TV details: ${response.status}`);
|
|
128
|
-
}
|
|
129
|
-
return response.json();
|
|
130
|
-
}
|
|
131
|
-
async function getSeasonDetails(id, season) {
|
|
132
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}/${season}`;
|
|
133
|
-
const response = await fetch(url);
|
|
134
|
-
if (!response.ok) {
|
|
135
|
-
throw new Error(`Failed to fetch season details: ${response.status}`);
|
|
136
|
-
}
|
|
137
|
-
return response.json();
|
|
138
|
-
}
|
|
139
|
-
exports.configure = configure;
|
|
140
|
-
exports.getSeasonDetails = getSeasonDetails;
|
|
141
|
-
exports.getTvDetails = getTvDetails;
|
|
142
|
-
exports.parseToVTT = parseToVTT;
|
|
143
|
-
exports.searchSubtitles = searchSubtitles;
|
|
144
|
-
exports.searchTmdb = searchTmdb;
|
|
145
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
146
|
-
return exports;
|
|
147
|
-
}({});
|
package/lib/main.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
const config = {
|
|
2
|
-
baseUrl: "https://sub.wyzie.ru"
|
|
3
|
-
};
|
|
4
|
-
function configure(options) {
|
|
5
|
-
if (options.baseUrl) {
|
|
6
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
async function constructUrl({
|
|
10
|
-
tmdb_id,
|
|
11
|
-
imdb_id,
|
|
12
|
-
season,
|
|
13
|
-
episode,
|
|
14
|
-
encoding,
|
|
15
|
-
language,
|
|
16
|
-
format,
|
|
17
|
-
source,
|
|
18
|
-
hi,
|
|
19
|
-
...extraParams
|
|
20
|
-
}) {
|
|
21
|
-
if (!tmdb_id && !imdb_id) {
|
|
22
|
-
throw new Error("Either tmdb_id or imdb_id must be provided.");
|
|
23
|
-
}
|
|
24
|
-
const hasSeason = season !== void 0;
|
|
25
|
-
const hasEpisode = episode !== void 0;
|
|
26
|
-
if (hasSeason && !hasEpisode || !hasSeason && hasEpisode) {
|
|
27
|
-
throw new Error("Season and episode must be provided together or omitted together.");
|
|
28
|
-
}
|
|
29
|
-
const url = new URL(`${config.baseUrl}/search`);
|
|
30
|
-
const queryParams = {
|
|
31
|
-
id: String(tmdb_id || imdb_id),
|
|
32
|
-
season,
|
|
33
|
-
episode,
|
|
34
|
-
encoding: Array.isArray(encoding) ? encoding.join(",") : encoding,
|
|
35
|
-
language: Array.isArray(language) ? language.join(",") : language,
|
|
36
|
-
format: Array.isArray(format) ? format.join(",") : format,
|
|
37
|
-
source: Array.isArray(source) ? source.join(",") : source,
|
|
38
|
-
hi
|
|
39
|
-
};
|
|
40
|
-
Object.entries(queryParams).forEach(([key, value]) => {
|
|
41
|
-
if (value !== void 0) {
|
|
42
|
-
url.searchParams.append(key, String(value));
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
Object.entries(extraParams).forEach(([key, value]) => {
|
|
46
|
-
if (value !== void 0) {
|
|
47
|
-
if (Array.isArray(value)) {
|
|
48
|
-
url.searchParams.append(key, value.join(","));
|
|
49
|
-
} else {
|
|
50
|
-
url.searchParams.append(key, String(value));
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
return url;
|
|
55
|
-
}
|
|
56
|
-
async function fetchSubtitles(url) {
|
|
57
|
-
const response = await fetch(url.toString());
|
|
58
|
-
if (!response.ok) {
|
|
59
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
60
|
-
}
|
|
61
|
-
return response.json();
|
|
62
|
-
}
|
|
63
|
-
async function searchSubtitles(params) {
|
|
64
|
-
try {
|
|
65
|
-
const url = await constructUrl(params);
|
|
66
|
-
return await fetchSubtitles(url);
|
|
67
|
-
} catch (error) {
|
|
68
|
-
throw new Error(`Error fetching subtitles: ${error}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
async function parseToVTT(subtitleUrl) {
|
|
72
|
-
try {
|
|
73
|
-
const response = await fetch(subtitleUrl);
|
|
74
|
-
if (!response.ok) {
|
|
75
|
-
throw new Error(`Failed to fetch subtitle content: ${response.status}`);
|
|
76
|
-
}
|
|
77
|
-
const content = await response.text();
|
|
78
|
-
const normalizedContent = content.replace(/\r\n|\r/g, "\n").trim();
|
|
79
|
-
const blocks = normalizedContent.split(/\n\n+/);
|
|
80
|
-
const timestampRegex = /^\d{1,2}:\d{2}:\d{2}[,.]\d{3}\s*-->\s*\d{1,2}:\d{2}:\d{2}[,.]\d{3}$/;
|
|
81
|
-
const hasValidSRTFormat = blocks.some((block) => {
|
|
82
|
-
const lines = block.split("\n").map((line) => line.trim());
|
|
83
|
-
return lines.some((line) => timestampRegex.test(line));
|
|
84
|
-
});
|
|
85
|
-
if (!hasValidSRTFormat) {
|
|
86
|
-
throw new Error("Invalid subtitle format: not SRT");
|
|
87
|
-
}
|
|
88
|
-
const vttLines = ["WEBVTT", ""];
|
|
89
|
-
for (const block of blocks) {
|
|
90
|
-
const lines = block.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
91
|
-
if (lines.length < 2)
|
|
92
|
-
continue;
|
|
93
|
-
const timestampIndex = lines.findIndex((line) => timestampRegex.test(line));
|
|
94
|
-
if (timestampIndex === -1)
|
|
95
|
-
continue;
|
|
96
|
-
const textLines = lines.slice(timestampIndex + 1).filter((line) => !/^\d+$/.test(line));
|
|
97
|
-
if (textLines.length === 0)
|
|
98
|
-
continue;
|
|
99
|
-
let timestampLine = lines[timestampIndex];
|
|
100
|
-
timestampLine = timestampLine.replace(/[,.](?=\s*-->)/, "").replace(/[,.]$/, "").replace(/,(\d{3})/g, ".$1");
|
|
101
|
-
vttLines.push(`${timestampLine}
|
|
102
|
-
${textLines.join("\n")}
|
|
103
|
-
`);
|
|
104
|
-
}
|
|
105
|
-
return vttLines.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n\n";
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error("Error in parseToVTT:", error);
|
|
108
|
-
throw error;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
async function searchTmdb(query, language = "en-US") {
|
|
112
|
-
const url = new URL(`${config.baseUrl}/api/tmdb/search`);
|
|
113
|
-
url.searchParams.append("q", query);
|
|
114
|
-
url.searchParams.append("language", language);
|
|
115
|
-
const response = await fetch(url.toString());
|
|
116
|
-
if (!response.ok) {
|
|
117
|
-
throw new Error(`Failed to search TMDB: ${response.status}`);
|
|
118
|
-
}
|
|
119
|
-
return response.json();
|
|
120
|
-
}
|
|
121
|
-
async function getTvDetails(id) {
|
|
122
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}`;
|
|
123
|
-
const response = await fetch(url);
|
|
124
|
-
if (!response.ok) {
|
|
125
|
-
throw new Error(`Failed to fetch TV details: ${response.status}`);
|
|
126
|
-
}
|
|
127
|
-
return response.json();
|
|
128
|
-
}
|
|
129
|
-
async function getSeasonDetails(id, season) {
|
|
130
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}/${season}`;
|
|
131
|
-
const response = await fetch(url);
|
|
132
|
-
if (!response.ok) {
|
|
133
|
-
throw new Error(`Failed to fetch season details: ${response.status}`);
|
|
134
|
-
}
|
|
135
|
-
return response.json();
|
|
136
|
-
}
|
|
137
|
-
export {
|
|
138
|
-
configure,
|
|
139
|
-
getSeasonDetails,
|
|
140
|
-
getTvDetails,
|
|
141
|
-
parseToVTT,
|
|
142
|
-
searchSubtitles,
|
|
143
|
-
searchTmdb
|
|
144
|
-
};
|
package/lib/main.umd.cjs
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.main = {}));
|
|
3
|
-
})(this, function(exports2) {
|
|
4
|
-
"use strict";
|
|
5
|
-
const config = {
|
|
6
|
-
baseUrl: "https://sub.wyzie.ru"
|
|
7
|
-
};
|
|
8
|
-
function configure(options) {
|
|
9
|
-
if (options.baseUrl) {
|
|
10
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
async function constructUrl({
|
|
14
|
-
tmdb_id,
|
|
15
|
-
imdb_id,
|
|
16
|
-
season,
|
|
17
|
-
episode,
|
|
18
|
-
encoding,
|
|
19
|
-
language,
|
|
20
|
-
format,
|
|
21
|
-
source,
|
|
22
|
-
hi,
|
|
23
|
-
...extraParams
|
|
24
|
-
}) {
|
|
25
|
-
if (!tmdb_id && !imdb_id) {
|
|
26
|
-
throw new Error("Either tmdb_id or imdb_id must be provided.");
|
|
27
|
-
}
|
|
28
|
-
const hasSeason = season !== void 0;
|
|
29
|
-
const hasEpisode = episode !== void 0;
|
|
30
|
-
if (hasSeason && !hasEpisode || !hasSeason && hasEpisode) {
|
|
31
|
-
throw new Error("Season and episode must be provided together or omitted together.");
|
|
32
|
-
}
|
|
33
|
-
const url = new URL(`${config.baseUrl}/search`);
|
|
34
|
-
const queryParams = {
|
|
35
|
-
id: String(tmdb_id || imdb_id),
|
|
36
|
-
season,
|
|
37
|
-
episode,
|
|
38
|
-
encoding: Array.isArray(encoding) ? encoding.join(",") : encoding,
|
|
39
|
-
language: Array.isArray(language) ? language.join(",") : language,
|
|
40
|
-
format: Array.isArray(format) ? format.join(",") : format,
|
|
41
|
-
source: Array.isArray(source) ? source.join(",") : source,
|
|
42
|
-
hi
|
|
43
|
-
};
|
|
44
|
-
Object.entries(queryParams).forEach(([key, value]) => {
|
|
45
|
-
if (value !== void 0) {
|
|
46
|
-
url.searchParams.append(key, String(value));
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
Object.entries(extraParams).forEach(([key, value]) => {
|
|
50
|
-
if (value !== void 0) {
|
|
51
|
-
if (Array.isArray(value)) {
|
|
52
|
-
url.searchParams.append(key, value.join(","));
|
|
53
|
-
} else {
|
|
54
|
-
url.searchParams.append(key, String(value));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
return url;
|
|
59
|
-
}
|
|
60
|
-
async function fetchSubtitles(url) {
|
|
61
|
-
const response = await fetch(url.toString());
|
|
62
|
-
if (!response.ok) {
|
|
63
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
64
|
-
}
|
|
65
|
-
return response.json();
|
|
66
|
-
}
|
|
67
|
-
async function searchSubtitles(params) {
|
|
68
|
-
try {
|
|
69
|
-
const url = await constructUrl(params);
|
|
70
|
-
return await fetchSubtitles(url);
|
|
71
|
-
} catch (error) {
|
|
72
|
-
throw new Error(`Error fetching subtitles: ${error}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
async function parseToVTT(subtitleUrl) {
|
|
76
|
-
try {
|
|
77
|
-
const response = await fetch(subtitleUrl);
|
|
78
|
-
if (!response.ok) {
|
|
79
|
-
throw new Error(`Failed to fetch subtitle content: ${response.status}`);
|
|
80
|
-
}
|
|
81
|
-
const content = await response.text();
|
|
82
|
-
const normalizedContent = content.replace(/\r\n|\r/g, "\n").trim();
|
|
83
|
-
const blocks = normalizedContent.split(/\n\n+/);
|
|
84
|
-
const timestampRegex = /^\d{1,2}:\d{2}:\d{2}[,.]\d{3}\s*-->\s*\d{1,2}:\d{2}:\d{2}[,.]\d{3}$/;
|
|
85
|
-
const hasValidSRTFormat = blocks.some((block) => {
|
|
86
|
-
const lines = block.split("\n").map((line) => line.trim());
|
|
87
|
-
return lines.some((line) => timestampRegex.test(line));
|
|
88
|
-
});
|
|
89
|
-
if (!hasValidSRTFormat) {
|
|
90
|
-
throw new Error("Invalid subtitle format: not SRT");
|
|
91
|
-
}
|
|
92
|
-
const vttLines = ["WEBVTT", ""];
|
|
93
|
-
for (const block of blocks) {
|
|
94
|
-
const lines = block.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
95
|
-
if (lines.length < 2)
|
|
96
|
-
continue;
|
|
97
|
-
const timestampIndex = lines.findIndex((line) => timestampRegex.test(line));
|
|
98
|
-
if (timestampIndex === -1)
|
|
99
|
-
continue;
|
|
100
|
-
const textLines = lines.slice(timestampIndex + 1).filter((line) => !/^\d+$/.test(line));
|
|
101
|
-
if (textLines.length === 0)
|
|
102
|
-
continue;
|
|
103
|
-
let timestampLine = lines[timestampIndex];
|
|
104
|
-
timestampLine = timestampLine.replace(/[,.](?=\s*-->)/, "").replace(/[,.]$/, "").replace(/,(\d{3})/g, ".$1");
|
|
105
|
-
vttLines.push(`${timestampLine}
|
|
106
|
-
${textLines.join("\n")}
|
|
107
|
-
`);
|
|
108
|
-
}
|
|
109
|
-
return vttLines.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n\n";
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error("Error in parseToVTT:", error);
|
|
112
|
-
throw error;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
async function searchTmdb(query, language = "en-US") {
|
|
116
|
-
const url = new URL(`${config.baseUrl}/api/tmdb/search`);
|
|
117
|
-
url.searchParams.append("q", query);
|
|
118
|
-
url.searchParams.append("language", language);
|
|
119
|
-
const response = await fetch(url.toString());
|
|
120
|
-
if (!response.ok) {
|
|
121
|
-
throw new Error(`Failed to search TMDB: ${response.status}`);
|
|
122
|
-
}
|
|
123
|
-
return response.json();
|
|
124
|
-
}
|
|
125
|
-
async function getTvDetails(id) {
|
|
126
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}`;
|
|
127
|
-
const response = await fetch(url);
|
|
128
|
-
if (!response.ok) {
|
|
129
|
-
throw new Error(`Failed to fetch TV details: ${response.status}`);
|
|
130
|
-
}
|
|
131
|
-
return response.json();
|
|
132
|
-
}
|
|
133
|
-
async function getSeasonDetails(id, season) {
|
|
134
|
-
const url = `${config.baseUrl}/api/tmdb/tv/${id}/${season}`;
|
|
135
|
-
const response = await fetch(url);
|
|
136
|
-
if (!response.ok) {
|
|
137
|
-
throw new Error(`Failed to fetch season details: ${response.status}`);
|
|
138
|
-
}
|
|
139
|
-
return response.json();
|
|
140
|
-
}
|
|
141
|
-
exports2.configure = configure;
|
|
142
|
-
exports2.getSeasonDetails = getSeasonDetails;
|
|
143
|
-
exports2.getTvDetails = getTvDetails;
|
|
144
|
-
exports2.parseToVTT = parseToVTT;
|
|
145
|
-
exports2.searchSubtitles = searchSubtitles;
|
|
146
|
-
exports2.searchTmdb = searchTmdb;
|
|
147
|
-
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
148
|
-
});
|