diff --git a/package.json b/package.json index 34c61d6..fd8d37d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "5.4.7", + "version": "5.5", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", diff --git a/src/modules/processing/match.js b/src/modules/processing/match.js index f6e18a2..3328a32 100644 --- a/src/modules/processing/match.js +++ b/src/modules/processing/match.js @@ -16,6 +16,7 @@ import tumblr from "./services/tumblr.js"; import vimeo from "./services/vimeo.js"; import soundcloud from "./services/soundcloud.js"; import instagram from "./services/instagram.js"; +import vine from "./services/vine.js"; export default async function (host, patternMatch, url, lang, obj) { try { @@ -104,7 +105,10 @@ export default async function (host, patternMatch, url, lang, obj) { }); break; case "instagram": - r = await instagram({ id: patternMatch["id"] ? patternMatch["id"] : false }); + r = await instagram({ id: patternMatch["id"] }); + break; + case "vine": + r = await vine({ id: patternMatch["id"] }); break; default: return apiJSON(0, { t: errorUnsupported(lang) }); diff --git a/src/modules/processing/matchActionDecider.js b/src/modules/processing/matchActionDecider.js index b2329a1..ba10af2 100644 --- a/src/modules/processing/matchActionDecider.js +++ b/src/modules/processing/matchActionDecider.js @@ -52,6 +52,7 @@ export default function(r, host, ip, audioFormat, isAudioOnly, lang, isAudioMute params = { type: "bridge" }; break; + case "vine": case "instagram": case "tumblr": case "twitter": diff --git a/src/modules/processing/services/tumblr.js b/src/modules/processing/services/tumblr.js index 45291f0..95ba7f4 100644 --- a/src/modules/processing/services/tumblr.js +++ b/src/modules/processing/services/tumblr.js @@ -10,5 +10,5 @@ export default async function(obj) { if (!html) return { error: 'ErrorCouldntFetch' }; if (!html.includes('property="og:video" content="https://va.media.tumblr.com/')) return { error: 'ErrorEmptyDownload' }; - return { urls: `https://va.media.tumblr.com/${html.split('property="og:video" content="https://va.media.tumblr.com/')[1].split('"')[0]}`, audioFilename: `tumblr_${obj.id}_audio` } + return { urls: `https://va.media.tumblr.com/${html.split('property="og:video" content="https://va.media.tumblr.com/')[1].split('"')[0]}`, filename: `tumblr_${obj.id}.mp4`, audioFilename: `tumblr_${obj.id}_audio` } } diff --git a/src/modules/processing/services/vine.js b/src/modules/processing/services/vine.js new file mode 100644 index 0000000..21596d4 --- /dev/null +++ b/src/modules/processing/services/vine.js @@ -0,0 +1,8 @@ +export default async function(obj) { + let post = await fetch(`https://archive.vine.co/posts/${obj.id}.json`).then((r) => { return r.json() }).catch(() => { return false }); + if (!post) return { error: 'ErrorEmptyDownload' }; + + if (post.videoUrl) return { urls: post.videoUrl.replace("http://", "https://"), filename: `vine_${obj.id}.mp4`, audioFilename: `vine_${obj.id}_audio` }; + + return { error: 'ErrorEmptyDownload' } +} diff --git a/src/modules/processing/servicesConfig.json b/src/modules/processing/servicesConfig.json index d99e1b7..2bb7f8f 100644 --- a/src/modules/processing/servicesConfig.json +++ b/src/modules/processing/servicesConfig.json @@ -56,6 +56,12 @@ "alias": "instagram reels & video posts", "patterns": ["reels/:id", "reel/:id", "p/:id"], "enabled": true + }, + "vine": { + "alias": "vine archive", + "tld": "co", + "patterns": ["v/:id"], + "enabled": true } } } diff --git a/src/modules/processing/servicesPatternTesters.js b/src/modules/processing/servicesPatternTesters.js index bb64377..8f70613 100644 --- a/src/modules/processing/servicesPatternTesters.js +++ b/src/modules/processing/servicesPatternTesters.js @@ -26,5 +26,7 @@ export const testers = { "soundcloud": (patternMatch) => ((patternMatch["author"] && patternMatch["song"] && (patternMatch["author"].length + patternMatch["song"].length) <= 96) || (patternMatch["shortLink"] && patternMatch["shortLink"].length <= 32)), - "instagram": (patternMatch) => (patternMatch["id"] && patternMatch["id"].length <= 12) + "instagram": (patternMatch) => (patternMatch["id"] && patternMatch["id"].length <= 12), + + "vine": (patternMatch) => (patternMatch["id"] && patternMatch["id"].length <= 12) } diff --git a/src/test/tests.json b/src/test/tests.json index 5e94cb7..158a0ea 100644 --- a/src/test/tests.json +++ b/src/test/tests.json @@ -814,6 +814,16 @@ "code": 200, "status": "stream" } + }, { + "name": "reel (isAudioMuted)", + "url": "https://www.instagram.com/reel/CoEBV3eM4QR/", + "params": { + "isAudioMuted": true + }, + "expected": { + "code": 200, + "status": "stream" + } }, { "name": "inexistent reel", "url": "https://www.instagram.com/reel/XXXXXXXXXX/", @@ -830,5 +840,34 @@ "code": 400, "status": "error" } + }], + "vine": [{ + "name": "regular vine link (9+10=21)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": {}, + "expected": { + "code": 200, + "status": "redirect" + } + }, { + "name": "regular vine link (isAudioOnly)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": { + "isAudioOnly": true + }, + "expected": { + "code": 200, + "status": "stream" + } + }, { + "name": "regular vine link (isAudioMuted)", + "url": "https://vine.co/v/huwVJIEJW50", + "params": { + "isAudioMuted": true + }, + "expected": { + "code": 200, + "status": "stream" + } }] } \ No newline at end of file