frostpv 1.0.6 → 1.0.7
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/index.js +88 -4
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4,7 +4,7 @@ const path = require("path");
|
|
|
4
4
|
const os = require("os");
|
|
5
5
|
const FormData = require("form-data");
|
|
6
6
|
const crypto = require("crypto");
|
|
7
|
-
const { igdl, ttdl, fbdown, mediafire, capcut, gdrive } = require("btch-downloader");
|
|
7
|
+
const { igdl, ttdl, fbdown, mediafire, capcut, gdrive, pinterest } = require("btch-downloader");
|
|
8
8
|
const { TwitterDL } = require("twitter-downloader");
|
|
9
9
|
const btch = require("btch-downloader");
|
|
10
10
|
const btchOld = require("btch-downloader-old");
|
|
@@ -67,6 +67,16 @@ const linkCant = [{
|
|
|
67
67
|
reason: "Use real link like 'https://www.tiktok.com'. (just click on your link and copy the link in the browser)"
|
|
68
68
|
}];
|
|
69
69
|
|
|
70
|
+
// Function to check if a link corresponds to a video platform
|
|
71
|
+
const isVideoLink = (link) => {
|
|
72
|
+
try {
|
|
73
|
+
const u = new URL(link);
|
|
74
|
+
const host = (u.hostname || '').toLowerCase();
|
|
75
|
+
if (host.endsWith('pintere21313213st.com')) return true;
|
|
76
|
+
} catch (_) {}
|
|
77
|
+
return videoPlatforms.some(platform => link.startsWith(platform));
|
|
78
|
+
};
|
|
79
|
+
|
|
70
80
|
// Function to check if a link is blacklisted
|
|
71
81
|
const blacklistLink = (link) => {
|
|
72
82
|
return linkCant.find(item => link.includes(item.link));
|
|
@@ -713,6 +723,32 @@ async function tryFallbackDownload(url, maxRetries = 3) {
|
|
|
713
723
|
}
|
|
714
724
|
break;
|
|
715
725
|
}
|
|
726
|
+
case "pinterest": {
|
|
727
|
+
try {
|
|
728
|
+
const data = await pinterest(url);
|
|
729
|
+
let mediaUrl = null;
|
|
730
|
+
const pickFrom = (obj) => {
|
|
731
|
+
if (!obj) return null;
|
|
732
|
+
if (typeof obj === 'string' && obj.startsWith('http')) return obj;
|
|
733
|
+
if (Array.isArray(obj)) {
|
|
734
|
+
for (const it of obj) {
|
|
735
|
+
const got = pickFrom(it);
|
|
736
|
+
if (got) return got;
|
|
737
|
+
}
|
|
738
|
+
} else if (typeof obj === 'object') {
|
|
739
|
+
const candidates = ['video', 'videoUrl', 'download', 'url', 'image', 'imageUrl', 'src', 'link'];
|
|
740
|
+
for (const k of candidates) {
|
|
741
|
+
const got = pickFrom(obj[k]);
|
|
742
|
+
if (got) return got;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
return null;
|
|
746
|
+
};
|
|
747
|
+
mediaUrl = pickFrom(data);
|
|
748
|
+
if (mediaUrl) return mediaUrl;
|
|
749
|
+
} catch (_) {}
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
716
752
|
|
|
717
753
|
default: {
|
|
718
754
|
// Generic fallback for unknown platforms
|
|
@@ -785,7 +821,7 @@ const MediaDownloader = async (url, options = {}) => {
|
|
|
785
821
|
if (url.includes("threads.com")) {
|
|
786
822
|
throw new Error("Threads links are not supported for download. Download videos from Instagram, X, TikTok, and Facebook");
|
|
787
823
|
}
|
|
788
|
-
|
|
824
|
+
// Pinterest now supported
|
|
789
825
|
|
|
790
826
|
const blacklisted = blacklistLink(url);
|
|
791
827
|
if (blacklisted) {
|
|
@@ -979,6 +1015,52 @@ async function downloadSmartVideo(url, config) {
|
|
|
979
1015
|
}
|
|
980
1016
|
break;
|
|
981
1017
|
}
|
|
1018
|
+
case "pinterest": {
|
|
1019
|
+
try {
|
|
1020
|
+
// Supports both pin links and search queries
|
|
1021
|
+
const data = await pinterest(url);
|
|
1022
|
+
// data may be array or object depending on query or pin
|
|
1023
|
+
// Try to find best url (image or video)
|
|
1024
|
+
let directUrl = null;
|
|
1025
|
+
const pickFrom = (obj) => {
|
|
1026
|
+
if (!obj) return null;
|
|
1027
|
+
if (typeof obj === 'string' && obj.startsWith('http')) return obj;
|
|
1028
|
+
if (Array.isArray(obj)) {
|
|
1029
|
+
for (const it of obj) {
|
|
1030
|
+
const got = pickFrom(it);
|
|
1031
|
+
if (got) return got;
|
|
1032
|
+
}
|
|
1033
|
+
} else if (typeof obj === 'object') {
|
|
1034
|
+
const candidates = ['video', 'videoUrl', 'download', 'url', 'image', 'imageUrl', 'src', 'link'];
|
|
1035
|
+
for (const k of candidates) {
|
|
1036
|
+
const got = pickFrom(obj[k]);
|
|
1037
|
+
if (got) return got;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
return null;
|
|
1041
|
+
};
|
|
1042
|
+
directUrl = pickFrom(data);
|
|
1043
|
+
if (!directUrl) throw new Error("No media URL found in Pinterest response");
|
|
1044
|
+
|
|
1045
|
+
// HEAD validate
|
|
1046
|
+
const head = await axios.head(directUrl, { timeout: 10000, maxRedirects: 5 }).catch(() => null);
|
|
1047
|
+
if (!head || (head.status < 200 || head.status >= 400)) {
|
|
1048
|
+
throw new Error("Pinterest media URL not accessible");
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// If it's an image, download with generic file helper; if video, continue normal flow
|
|
1052
|
+
const ct = (head.headers && head.headers['content-type']) || '';
|
|
1053
|
+
if (ct.startsWith('image/')) {
|
|
1054
|
+
const filePath = await downloadGenericFile(directUrl);
|
|
1055
|
+
return filePath;
|
|
1056
|
+
} else {
|
|
1057
|
+
videoUrl = directUrl;
|
|
1058
|
+
}
|
|
1059
|
+
} catch (error) {
|
|
1060
|
+
throw new Error(`Pinterest download failed: ${error.message}`);
|
|
1061
|
+
}
|
|
1062
|
+
break;
|
|
1063
|
+
}
|
|
982
1064
|
case "twitter": {
|
|
983
1065
|
try {
|
|
984
1066
|
// Validate and clean the Twitter URL
|
|
@@ -1378,8 +1460,10 @@ function getFileName(url) {
|
|
|
1378
1460
|
// Function to unshorten URLs
|
|
1379
1461
|
async function unshortenUrl(url) {
|
|
1380
1462
|
try {
|
|
1463
|
+
// Special handling for Facebook and Pinterest short-links
|
|
1381
1464
|
if (
|
|
1382
|
-
url.includes('facebook.com') || url.includes('fb.watch') || url.includes('fb.com')
|
|
1465
|
+
url.includes('facebook.com') || url.includes('fb.watch') || url.includes('fb.com') ||
|
|
1466
|
+
url.includes('pi1231231n.it') || url.includes('pint123123erest.com')
|
|
1383
1467
|
) {
|
|
1384
1468
|
const response = await axios.get(url, {
|
|
1385
1469
|
maxRedirects: 10,
|
|
@@ -1434,7 +1518,7 @@ const AudioDownloader = async (url, options = {}) => {
|
|
|
1434
1518
|
|
|
1435
1519
|
// Verificar se o link está na lista de plataformas suportadas
|
|
1436
1520
|
if (!isVideoLink(url)) {
|
|
1437
|
-
throw new Error("This URL is not from a supported platform. Supported platforms: Instagram, X(Twitter), TikTok, Facebook");
|
|
1521
|
+
throw new Error("This URL is not from a supported platform. Supported platforms: Instagram, X(Twitter), TikTok, Facebook, and YouTube");
|
|
1438
1522
|
}
|
|
1439
1523
|
|
|
1440
1524
|
await cleanupTempFiles(); // Clean up previous temp files
|