diff --git a/s.to/sToEngDub.json b/s.to/sToEngDub.json index c1f6543..b4a644d 100644 --- a/s.to/sToEngDub.json +++ b/s.to/sToEngDub.json @@ -5,7 +5,7 @@ "name": "Cufiy", "icon": "https://files.catbox.moe/ttj4fc.gif" }, - "version": "0.3.15", + "version": "0.3.16", "language": "English (DUB)", "streamType": "HLS", "quality": "720p", diff --git a/s.to/sToEngDub_v2.js b/s.to/sToEngDub_v2.js index af0169a..a8eeaa0 100644 --- a/s.to/sToEngDub_v2.js +++ b/s.to/sToEngDub_v2.js @@ -6,7 +6,8 @@ async function searchResults(keyword) { try { const encodedKeyword = encodeURIComponent(keyword); const searchApiUrl = `https://s.to/ajax/seriesSearch?keyword=${encodedKeyword}`; - const responseText = await fetch(searchApiUrl); + const response = await soraFetch(searchApiUrl); + const responseText = await response?.text() ?? response; const data = await JSON.parse(responseText); @@ -27,7 +28,7 @@ async function searchResults(keyword) { async function extractDetails(url) { try { const fetchUrl = `${url}`; - const response = await fetch(fetchUrl); + const response = await soraFetch(fetchUrl); const text = response.text ? await response.text() : response; const descriptionRegex = /
(.*?)<\/p>/s;
@@ -40,11 +41,15 @@ async function extractDetails(url) {
}
const descriptionMatch = descriptionRegex.exec(text) || [];
+ // sanitize description by removing HTML tags
+ let description = descriptionMatch[1] || '';
+ description = description.replace(/<[^>]+>/g, '').trim();
+
const airdateMatch = "Unknown"; // TODO: Implement airdate extraction
const transformedResults = [{
- description: descriptionMatch[1] || 'No description available',
+ description: description || 'No description available',
aliases: aliasesArray[0] || 'No aliases available',
airdate: airdateMatch
}];
@@ -64,16 +69,18 @@ async function extractEpisodes(url) {
try {
const baseUrl = 'https://s.to';
const fetchUrl = `${url}`;
- const response = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
const html = response.text ? await response.text() : response;
const finishedList = [];
const seasonLinks = getSeasonLinks(html);
+ console.log("Season Links: " + JSON.stringify(seasonLinks));
for (const seasonLink of seasonLinks) {
const seasonEpisodes = await fetchSeasonEpisodes(`${baseUrl}${seasonLink}`);
finishedList.push(...seasonEpisodes);
}
+ console.log("Finished Episode List: " + JSON.stringify(finishedList));
// Replace the field "number" with the current index of each item, starting from 1
finishedList.forEach((item, index) => {
@@ -94,7 +101,7 @@ async function extractStreamUrl(url) {
try {
const baseUrl = 'https://s.to';
const fetchUrl = `${url}`;
- const response = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
const text = response.text ? await response.text() : response;
const finishedList = [];
@@ -125,7 +132,7 @@ async function extractStreamUrl(url) {
const providerName = value;
// fetch the provider link and extract the stream URL
- const streamUrl = await fetch(providerLink);
+ const streamUrl = await soraFetch(providerLink);
console.log("Stream URL: " + streamUrl);
const winLocRegex = /window\.location\.href\s*=\s*['"]([^'"]+)['"]/;
const winLocMatch = await winLocRegex.exec(streamUrl);
@@ -195,9 +202,11 @@ function selectHoster(finishedList) {
// "https://speedfiles.net/82346fs": "speedfiles",
// };
+ console.log("Hoster List: " + JSON.stringify(finishedList));
+
// Define the preferred providers and languages
- const providerList = ["VOE", "SpeedFiles", "Vidmoly", "DoodStream", "Vidoza", "MP4Upload"];
- const languageList = ["Englisch", "mit Untertitel Englisch", "Deutsch", "mit Untertitel Deutsch"];
+ const providerList = ["VOE", "SpeedFiles", "Filemoon", "Vidmoly", "DoodStream", "Vidoza", "MP4Upload"];
+ const languageList = ["English", "mit Untertitel Deutsch", "mit Untertitel Englisch"];
@@ -263,10 +272,14 @@ async function fetchSeasonEpisodes(url) {
try {
const baseUrl = 'https://s.to';
const fetchUrl = `${url}`;
- const text = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
+ const text = await response?.text() ?? response;
// Updated regex to allow empty content
const regex = / (.*?)<\/p>/s;
@@ -40,11 +41,15 @@ async function extractDetails(url) {
}
const descriptionMatch = descriptionRegex.exec(text) || [];
+ // sanitize description by removing HTML tags
+ let description = descriptionMatch[1] || '';
+ description = description.replace(/<[^>]+>/g, '').trim();
+
const airdateMatch = "Unknown"; // TODO: Implement airdate extraction
const transformedResults = [{
- description: descriptionMatch[1] || 'No description available',
+ description: description || 'No description available',
aliases: aliasesArray[0] || 'No aliases available',
airdate: airdateMatch
}];
@@ -64,16 +69,18 @@ async function extractEpisodes(url) {
try {
const baseUrl = 'https://s.to';
const fetchUrl = `${url}`;
- const response = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
const html = response.text ? await response.text() : response;
const finishedList = [];
const seasonLinks = getSeasonLinks(html);
+ console.log("Season Links: " + JSON.stringify(seasonLinks));
for (const seasonLink of seasonLinks) {
const seasonEpisodes = await fetchSeasonEpisodes(`${baseUrl}${seasonLink}`);
finishedList.push(...seasonEpisodes);
}
+ console.log("Finished Episode List: " + JSON.stringify(finishedList));
// Replace the field "number" with the current index of each item, starting from 1
finishedList.forEach((item, index) => {
@@ -94,7 +101,7 @@ async function extractStreamUrl(url) {
try {
const baseUrl = 'https://s.to';
const fetchUrl = `${url}`;
- const response = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
const text = response.text ? await response.text() : response;
const finishedList = [];
@@ -125,7 +132,7 @@ async function extractStreamUrl(url) {
const providerName = value;
// fetch the provider link and extract the stream URL
- const streamUrl = await fetch(providerLink);
+ const streamUrl = await soraFetch(providerLink);
console.log("Stream URL: " + streamUrl);
const winLocRegex = /window\.location\.href\s*=\s*['"]([^'"]+)['"]/;
const winLocMatch = await winLocRegex.exec(streamUrl);
@@ -195,8 +202,10 @@ function selectHoster(finishedList) {
// "https://speedfiles.net/82346fs": "speedfiles",
// };
+ console.log("Hoster List: " + JSON.stringify(finishedList));
+
// Define the preferred providers and languages
- const providerList = ["VOE", "SpeedFiles", "Vidmoly", "DoodStream", "Vidoza", "MP4Upload"];
+ const providerList = ["VOE", "SpeedFiles", "Filemoon", "Vidmoly", "DoodStream", "Vidoza", "MP4Upload"];
const languageList = ["Deutsch", "mit Untertitel Deutsch", "mit Untertitel Englisch"];
@@ -263,10 +272,14 @@ async function fetchSeasonEpisodes(url) {
try {
const baseUrl = 'https://s.to';
const fetchUrl = `${url}`;
- const text = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
+ const text = await response?.text() ?? response;
// Updated regex to allow empty content
const regex = / Loaded from: \s*]*href="([^"]+)"[^>]*>.*?([^<]*)<\/strong>.*?([^<]+)<\/span>.*?<\/a>/g;
+const regex2 =
+ / ]*seasonEpisodeTitle[^>]*>\s*]*href=["']([^"']+)["'][^>]*>[\s\S]*?\s*([^<]*?)\s*<\/strong>[\s\S]*?(?:]*>\s*([^<]*?)\s*<\/span>)?[\s\S]*?<\/a>/gi;
+
const matches = [];
let match;
@@ -277,6 +290,16 @@ async function fetchSeasonEpisodes(url) {
matches.push({ number: holderNumber, href: `${baseUrl}${link}` });
}
+ // If no matches found with the first regex, try the second one
+ if (matches.length === 0) {
+ console.log("No matches found with first regex, trying second regex.");
+ while ((match = regex2.exec(text)) !== null) {
+ const [_, link] = match;
+ console.log("Match found with second regex: " + link);
+ matches.push({ number: holderNumber, href: `${baseUrl}${link}` });
+ }
+ }
+
return matches;
} catch (error) {
@@ -348,6 +371,7 @@ function base64Decode(str) {
}
+
// ⚠️ DO NOT EDIT BELOW THIS LINE ⚠️
// EDITING THIS FILE COULD BREAK THE UPDATER AND CAUSE ISSUES WITH THE EXTRACTOR
diff --git a/s.to/sToGerDub.json b/s.to/sToGerDub.json
index 8f99620..b33cb35 100644
--- a/s.to/sToGerDub.json
+++ b/s.to/sToGerDub.json
@@ -5,7 +5,7 @@
"name": "Hamzo & Cufiy",
"icon": "https://cdn.discordapp.com/avatars/623644371819954226/591ecab10b0b4535e859bb0b9bbe62e5?size=1024"
},
- "version": "0.3.15",
+ "version": "0.3.16",
"language": "German (DUB)",
"streamType": "HLS",
"quality": "720p",
diff --git a/s.to/sToGerDub_v2.js b/s.to/sToGerDub_v2.js
index 6b77b61..283f223 100644
--- a/s.to/sToGerDub_v2.js
+++ b/s.to/sToGerDub_v2.js
@@ -6,7 +6,8 @@ async function searchResults(keyword) {
try {
const encodedKeyword = encodeURIComponent(keyword);
const searchApiUrl = `https://s.to/ajax/seriesSearch?keyword=${encodedKeyword}`;
- const responseText = await fetch(searchApiUrl);
+ const response = await soraFetch(searchApiUrl);
+ const responseText = await response?.text() ?? response;
const data = await JSON.parse(responseText);
@@ -27,7 +28,7 @@ async function searchResults(keyword) {
async function extractDetails(url) {
try {
const fetchUrl = `${url}`;
- const response = await fetch(fetchUrl);
+ const response = await soraFetch(fetchUrl);
const text = response.text ? await response.text() : response;
const descriptionRegex = / \s*]*href="([^"]+)"[^>]*>.*?([^<]*)<\/strong>.*?([^<]+)<\/span>.*?<\/a>/g;
+const regex2 =
+ / ]*seasonEpisodeTitle[^>]*>\s*]*href=["']([^"']+)["'][^>]*>[\s\S]*?\s*([^<]*?)\s*<\/strong>[\s\S]*?(?:]*>\s*([^<]*?)\s*<\/span>)?[\s\S]*?<\/a>/gi;
+
const matches = [];
let match;
@@ -277,6 +290,16 @@ async function fetchSeasonEpisodes(url) {
matches.push({ number: holderNumber, href: `${baseUrl}${link}` });
}
+ // If no matches found with the first regex, try the second one
+ if (matches.length === 0) {
+ console.log("No matches found with first regex, trying second regex.");
+ while ((match = regex2.exec(text)) !== null) {
+ const [_, link] = match;
+ console.log("Match found with second regex: " + link);
+ matches.push({ number: holderNumber, href: `${baseUrl}${link}` });
+ }
+ }
+
return matches;
} catch (error) {
@@ -348,6 +371,7 @@ function base64Decode(str) {
}
+
// ⚠️ DO NOT EDIT BELOW THIS LINE ⚠️
// EDITING THIS FILE COULD BREAK THE UPDATER AND CAUSE ISSUES WITH THE EXTRACTOR
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..3216764
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,2 @@
+*.json
+.venv
\ No newline at end of file
diff --git a/test/debug_viewer.html b/test/debug_viewer.html
new file mode 100644
index 0000000..191a449
--- /dev/null
+++ b/test/debug_viewer.html
@@ -0,0 +1,1555 @@
+
+
+
+
+
+
+
+ Advanced Debug Log Viewer
+
+
+ No data loaded