From a1c5a4da7204f75e7e37eadfb2b454ef1320e89e Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:01:04 +0600 Subject: [PATCH 01/25] tiktok: update domain & force device info --- src/modules/processing/services/tiktok.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index 1818daf2..daea8c4b 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -4,8 +4,8 @@ const userAgent = genericUserAgent.split(' Chrome/1')[0], config = { tiktok: { short: "https://vt.tiktok.com/", - api: "https://api22-normal-c-useast2a.tiktokv.com/aweme/v1/feed/?aweme_id={postId}&version_code=262&app_name=musical_ly&channel=App&device_id=null&os_version=14.4.2&device_platform=iphone&device_type=iPhone9®ion=US&carrier_region=US", - userAgent: "TikTok 26.2.0 rv:262018 (iPhone; iOS 14.4.2; en_US) Cronet" + api: "https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/?aweme_id={postId}®ion=US&carrier_region=US", + userAgent: "TikTok/338014 CFNetwork/1410.1 Darwin/22.6.0" }, douyin: { short: "https://v.douyin.com/", @@ -32,6 +32,8 @@ function selector(j, h, id) { export default async function(obj) { let postId = obj.postId ? obj.postId : false; + if (!process.env.TIKTOK_DEVICE_INFO) return { error: 'ErrorCouldntFetch' }; + if (!postId) { let html = await fetch(`${config[obj.host].short}${obj.id}`, { redirect: "manual", @@ -48,12 +50,15 @@ export default async function(obj) { } if (!postId) return { error: 'ErrorCantGetID' }; + let deviceInfo = JSON.parse(process.env.TIKTOK_DEVICE_INFO); + deviceInfo = new URLSearchParams(deviceInfo).toString(); + let detail; - detail = await fetch(config[obj.host].api.replace("{postId}", postId), { - headers: { - "user-agent": config[obj.host].userAgent - } - }).then((r) => { return r.json() }).catch(() => { return false }); + detail = await fetch(`${config[obj.host].api.replace("{postId}", postId)}&${deviceInfo}`, { + headers: { + "user-agent": config[obj.host].userAgent + } + }).then((r) => { return r.json() }).catch(() => { return false }); detail = selector(detail, obj.host, postId); if (!detail) return { error: 'ErrorCouldntFetch' }; From c2c62c1bc29bff24f2cbd762a4c584baf8c760c6 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:01:47 +0600 Subject: [PATCH 02/25] docs/run-an-instance: add TIKTOK_DEVICE_INFO description --- docs/run-an-instance.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/run-an-instance.md b/docs/run-an-instance.md index 819e0215..01675e24 100644 --- a/docs/run-an-instance.md +++ b/docs/run-an-instance.md @@ -59,9 +59,32 @@ sudo service nscd start | `CORS_URL` | not used | `https://cobalt.tools/` | cross-origin resource sharing url. api will be available only from this url if `CORS_WILDCARD` is set to `0`. | | `COOKIE_PATH` | not used | `/cookies.json` | path for cookie file relative to main folder. | | `PROCESSING_PRIORITY` | not used | `10` | changes `nice` value* for ffmpeg subprocess. available only on unix systems. | +| `TIKTOK_DEVICE_INFO` | ➖ | *see below* | device info (including `iid` and `device_id`) for tiktok functionality. required for tiktok to work. | \* the higher the nice value, the lower the priority. [read more here](https://en.wikipedia.org/wiki/Nice_(Unix)). +#### TIKTOK_DEVICE_INFO +you need to get your own device info for tiktok functionality to work. this can be done by proxying the app through any request-intercepting proxy (such as [mitmproxy](https://mitmproxy.org)). you need to disable ssl pinning to see requests. there will be no assistance provided by cobalt for this. + +example config (replace **ALL** values with ones you got from mitm): +```json +'{ + "iid": "", + "device_id": "", + "channel": "googleplay", + "app_name": "musical_ly", + "version_code": "310503", + "device_platform": "android", + "device_type": "Redmi+7", + "os_version": "13" +}' +``` + +you can compress the json to save space. if you're using a `.env` file then the line would would look like this (***note the quotes***): +``` +TIKTOK_DEVICE_INFO='{"iid":"","device_id":"","channel":"googleplay","app_name":"musical_ly","version_code":"310503","device_platform":"android","device_type":"Redmi+7","os_version":"13"}' +``` + ### variables for web | variable name | default | example | description | |:---------------------|:---------------------|:------------------------|:--------------------------------------------------------------------------------------| From bcd8ca14b0bcaa8d2390a6cc0b6dba2f1a197c35 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:03:45 +0600 Subject: [PATCH 03/25] loc/en: remove extra comma in ContactLink --- src/localization/languages/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json index 43239ad4..8450e11a 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -1,7 +1,7 @@ { "name": "english", "substrings": { - "ContactLink": "check the status page or create an issue on github." + "ContactLink": "check the status page or create an issue on github" }, "strings": { "AppTitleCobalt": "cobalt", From 5438eb4405d5ebac64cafbc2bc46339a43655370 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:04:16 +0600 Subject: [PATCH 04/25] cobalt.css: stretch error popup content to full width --- src/front/cobalt.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/front/cobalt.css b/src/front/cobalt.css index 90b97188..67516ed5 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -452,6 +452,7 @@ button:active, display: flex; flex-direction: column; gap: 18px; + width: 100%; } .popup.small.visible { transform: translate(-50%, -50%); From 79772d45d7a8e65fe67ee9324d4255ed08181fe3 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:04:34 +0600 Subject: [PATCH 05/25] package: bump version to 7.12.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index feff48f4..99f6c747 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.12.1", + "version": "7.12.2", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", From 18545e7c910976d1c376713e10bdf93d289effbd Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:28:52 +0600 Subject: [PATCH 06/25] tiktok: clean up --- src/modules/processing/match.js | 2 - src/modules/processing/services/tiktok.js | 63 +++++++---------------- 2 files changed, 19 insertions(+), 46 deletions(-) diff --git a/src/modules/processing/match.js b/src/modules/processing/match.js index 41690571..6f715ef7 100644 --- a/src/modules/processing/match.js +++ b/src/modules/processing/match.js @@ -83,10 +83,8 @@ export default async function(host, patternMatch, url, lang, obj) { id: patternMatch.id }); break; - case "douyin": case "tiktok": r = await tiktok({ - host: host, postId: patternMatch.postId, id: patternMatch.id, fullAudio: obj.isTTFullAudio, diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index daea8c4b..ef74c0b9 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -1,33 +1,8 @@ import { genericUserAgent } from "../../config.js"; -const userAgent = genericUserAgent.split(' Chrome/1')[0], - config = { - tiktok: { - short: "https://vt.tiktok.com/", - api: "https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/?aweme_id={postId}®ion=US&carrier_region=US", - userAgent: "TikTok/338014 CFNetwork/1410.1 Darwin/22.6.0" - }, - douyin: { - short: "https://v.douyin.com/", - api: "https://www.iesdouyin.com/aweme/v1/web/aweme/detail/?aweme_id={postId}", - userAgent: "TikTok 26.2.0 rv:262018 (iPhone; iOS 14.4.2; en_US) Cronet" - } -} - -function selector(j, h, id) { - if (!j) return false; - let t; - switch (h) { - case "tiktok": - t = j.aweme_list.filter(v => v.aweme_id === id)[0]; - break; - case "douyin": - t = j.aweme_detail; - break; - } - if (t?.length < 3) return false; - return t; -} +const shortDomain = "https://vt.tiktok.com/"; +const apiPath = "https://api22-normal-c-alisg.tiktokv.com/aweme/v1/feed/?region=US&carrier_region=US"; +const apiUserAgent = "TikTok/338014 CFNetwork/1410.1 Darwin/22.6.0"; export default async function(obj) { let postId = obj.postId ? obj.postId : false; @@ -35,9 +10,11 @@ export default async function(obj) { if (!process.env.TIKTOK_DEVICE_INFO) return { error: 'ErrorCouldntFetch' }; if (!postId) { - let html = await fetch(`${config[obj.host].short}${obj.id}`, { + let html = await fetch(`${shortDomain}${obj.id}`, { redirect: "manual", - headers: { "user-agent": userAgent } + headers: { + "user-agent": genericUserAgent.split(' Chrome/1')[0] + } }).then((r) => { return r.text() }).catch(() => { return false }); if (!html) return { error: 'ErrorCouldntFetch' }; @@ -53,24 +30,22 @@ export default async function(obj) { let deviceInfo = JSON.parse(process.env.TIKTOK_DEVICE_INFO); deviceInfo = new URLSearchParams(deviceInfo).toString(); - let detail; - detail = await fetch(`${config[obj.host].api.replace("{postId}", postId)}&${deviceInfo}`, { - headers: { - "user-agent": config[obj.host].userAgent - } - }).then((r) => { return r.json() }).catch(() => { return false }); + let apiURL = new URL(apiPath); + apiURL.searchParams.append("aweme_id", postId); - detail = selector(detail, obj.host, postId); + let detail = await fetch(`${apiURL.href}&${deviceInfo}`, { + headers: { + "user-agent": apiUserAgent + } + }).then((r) => { return r.json() }).catch(() => { return false }); + + detail = detail?.aweme_list?.filter(v => v.aweme_id === postId)[0]; if (!detail) return { error: 'ErrorCouldntFetch' }; let video, videoFilename, audioFilename, isMp3, audio, images, - filenameBase = `${obj.host}_${detail.author.unique_id}_${postId}`; + filenameBase = `tiktok_${detail.author.unique_id}_${postId}`; - if (obj.host === "tiktok") { - images = detail.image_post_info ? detail.image_post_info.images : false - } else { - images = detail.images ? detail.images : false - } + images = detail.image_post_info ? detail.image_post_info.images : false; if (!obj.isAudioOnly && !images) { video = detail.video.play_addr.url_list[0]; @@ -99,7 +74,7 @@ export default async function(obj) { if (images) { let imageLinks = []; for (let i in images) { - let sel = obj.host === "tiktok" ? images[i].display_image.url_list : images[i].url_list; + let sel = images[i].display_image.url_list; sel = sel.filter(p => p.includes(".jpeg?")) imageLinks.push({url: sel[0]}) } From 299b46e940bf98fd45ad5b0865dcf058f72cbc31 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:42:01 +0600 Subject: [PATCH 07/25] tiktok: replace filter with find --- src/modules/processing/services/tiktok.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index ef74c0b9..c7645211 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -39,7 +39,7 @@ export default async function(obj) { } }).then((r) => { return r.json() }).catch(() => { return false }); - detail = detail?.aweme_list?.filter(v => v.aweme_id === postId)[0]; + detail = detail?.aweme_list?.find(v => v.aweme_id === postId); if (!detail) return { error: 'ErrorCouldntFetch' }; let video, videoFilename, audioFilename, isMp3, audio, images, From 5dcbe397dc06f936b44a5307befb6b410b83a4f9 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:44:07 +0600 Subject: [PATCH 08/25] tiktok: default to h264 but fall back to h265 --- src/modules/processing/services/tiktok.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index c7645211..046b08b3 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -47,11 +47,15 @@ export default async function(obj) { images = detail.image_post_info ? detail.image_post_info.images : false; + let playAddr = detail.video.play_addr_h264; + + if (!playAddr) playAddr = detail.video.play_addr; + if (!obj.isAudioOnly && !images) { - video = detail.video.play_addr.url_list[0]; + video = playAddr.url_list[0]; videoFilename = `${filenameBase}.mp4`; } else { - let fallback = detail.video.play_addr.url_list[0]; + let fallback = playAddr.url_list[0]; audio = fallback; audioFilename = `${filenameBase}_audio_fv`; // fv - from video if (obj.fullAudio || fallback.includes("music")) { From acdb22c41bc03f2b6f900c711cab3b4bdf89a865 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 06:51:55 +0600 Subject: [PATCH 09/25] tiktok: more cleaning up --- src/modules/processing/services/tiktok.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/processing/services/tiktok.js b/src/modules/processing/services/tiktok.js index 046b08b3..f3629109 100644 --- a/src/modules/processing/services/tiktok.js +++ b/src/modules/processing/services/tiktok.js @@ -15,7 +15,7 @@ export default async function(obj) { headers: { "user-agent": genericUserAgent.split(' Chrome/1')[0] } - }).then((r) => { return r.text() }).catch(() => { return false }); + }).then(r => r.text()).catch(() => {}); if (!html) return { error: 'ErrorCouldntFetch' }; @@ -37,7 +37,7 @@ export default async function(obj) { headers: { "user-agent": apiUserAgent } - }).then((r) => { return r.json() }).catch(() => { return false }); + }).then(r => r.json()).catch(() => {}); detail = detail?.aweme_list?.find(v => v.aweme_id === postId); if (!detail) return { error: 'ErrorCouldntFetch' }; @@ -45,7 +45,7 @@ export default async function(obj) { let video, videoFilename, audioFilename, isMp3, audio, images, filenameBase = `tiktok_${detail.author.unique_id}_${postId}`; - images = detail.image_post_info ? detail.image_post_info.images : false; + images = detail.image_post_info?.images; let playAddr = detail.video.play_addr_h264; From a86482b8947f9cca7d6bf01e3719f73199ecb201 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 07:13:26 +0600 Subject: [PATCH 10/25] docs/run-an-instance: fix tiktok device info sample Signed-off-by: wukko --- docs/run-an-instance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/run-an-instance.md b/docs/run-an-instance.md index 01675e24..204cff09 100644 --- a/docs/run-an-instance.md +++ b/docs/run-an-instance.md @@ -67,7 +67,7 @@ sudo service nscd start you need to get your own device info for tiktok functionality to work. this can be done by proxying the app through any request-intercepting proxy (such as [mitmproxy](https://mitmproxy.org)). you need to disable ssl pinning to see requests. there will be no assistance provided by cobalt for this. example config (replace **ALL** values with ones you got from mitm): -```json +``` '{ "iid": "", "device_id": "", @@ -95,4 +95,4 @@ TIKTOK_DEVICE_INFO='{"iid":"","device_id":"","c | `IS_BETA` | `0` | `1` | toggles beta tag next to cobalt logo.
`0`: disabled. `1`: enabled. | | `PLAUSIBLE_HOSTNAME` | ➖ | `plausible.io`* | enables plausible analytics with provided hostname as receiver backend. | -\* don't use plausible.io as receiver backend unless you paid for their cloud service. use your own domain when hosting community edition of plausible. refer to their [docs](https://plausible.io/docs) when needed. \ No newline at end of file +\* don't use plausible.io as receiver backend unless you paid for their cloud service. use your own domain when hosting community edition of plausible. refer to their [docs](https://plausible.io/docs) when needed. From 730ae714485aa3d3df09ce56f3101ca9ff66efc7 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 07:32:45 +0600 Subject: [PATCH 11/25] docs/examples/docker: update formatting and clean up --- docs/examples/docker-compose.example.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/examples/docker-compose.example.yml b/docs/examples/docker-compose.example.yml index b6f4a90b..450b437e 100644 --- a/docs/examples/docker-compose.example.yml +++ b/docs/examples/docker-compose.example.yml @@ -18,12 +18,10 @@ services: environment: # replace https://co.wuk.sh/ with your instance's target url in same format - - API_URL=https://co.wuk.sh/ + API_URL: "https://co.wuk.sh/" # replace eu-nl with your instance's distinctive name - - API_NAME=eu-nl - # if you want to use cookies when fetching data from services, uncomment the next line - #- COOKIE_PATH=/cookies.json - # see cookies.example.json for example file. + API_NAME: "eu-nl" + # see docs/run-an-instance.md for more information labels: - com.centurylinklabs.watchtower.scope=cobalt @@ -48,9 +46,9 @@ services: environment: # replace https://cobalt.tools/ with your instance's target url in same format - - WEB_URL=https://cobalt.tools/ + WEB_URL: "https://cobalt.tools/" # replace https://co.wuk.sh/ with preferred api instance url - - API_URL=https://co.wuk.sh/ + API_URL: "https://co.wuk.sh/" labels: - com.centurylinklabs.watchtower.scope=cobalt From be9bb95bb6705e5b9a802fdfa2b06dd21cb7c552 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 29 Mar 2024 07:34:46 +0600 Subject: [PATCH 12/25] docs/example/docker: more cleaning up --- docs/examples/docker-compose.example.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/docker-compose.example.yml b/docs/examples/docker-compose.example.yml index 450b437e..89c84642 100644 --- a/docs/examples/docker-compose.example.yml +++ b/docs/examples/docker-compose.example.yml @@ -8,7 +8,7 @@ services: init: true - # if container doesn't run detached on your machine, uncomment the next line: + # if container doesn't run detached on your machine, uncomment the next line #tty: true ports: @@ -36,7 +36,7 @@ services: init: true - # if container doesn't run detached on your machine, uncomment the next line: + # if container doesn't run detached on your machine, uncomment the next line #tty: true ports: From 48d9177fef9f319e5250469752bc8184806b5334 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 30 Mar 2024 14:14:22 +0600 Subject: [PATCH 13/25] youtube: replace innertube client (temp fix) --- package.json | 2 +- src/modules/processing/services/youtube.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 99f6c747..c40ecec8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.12.2", + "version": "7.12.3", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", diff --git a/src/modules/processing/services/youtube.js b/src/modules/processing/services/youtube.js index 10e813af..8a773375 100644 --- a/src/modules/processing/services/youtube.js +++ b/src/modules/processing/services/youtube.js @@ -33,7 +33,7 @@ export default async function(o) { } try { - info = await yt.getBasicInfo(o.id, 'ANDROID'); + info = await yt.getBasicInfo(o.id, 'YTMUSIC_ANDROID'); } catch (e) { return { error: 'ErrorCantConnectToServiceAPI' }; } From fb7cfd69d033ddd072072bc7f730c7acb003029b Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 09:38:28 +0600 Subject: [PATCH 14/25] readme: add a missing period and update "what's cobalt" section Signed-off-by: wukko --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6c08b8c6..0f5f9085 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ best way to save what you love: [cobalt.tools](https://cobalt.tools/) ![cobalt logo with repeated logo (double arrow) pattern background](https://raw.githubusercontent.com/wukko/cobalt/current/src/front/icons/pattern.png "cobalt logo with repeated logo (double arrow) pattern background") ## what's cobalt? -cobalt is a media downloader that doesn't piss you off. it's fast, friendly, and doesn't have any bullshit that modern web is filled with: ***no ads, trackers, or analytics***. +cobalt is a media downloader that doesn't piss you off. it's fast, friendly, and doesn't have any bullshit that modern web is filled with: ***no ads, trackers, or invasive analytics***. paste the link, get the file, move on. it's that simple. just how it should be. @@ -121,7 +121,7 @@ cobalt also depends on: - [node-cache](https://www.npmjs.com/package/node-cache) to cache stream info in server ram for a limited amount of time. - [psl](https://www.npmjs.com/package/psl) as the domain name parser. - [set-cookie-parser](https://www.npmjs.com/package/set-cookie-parser) to parse cookies that cobalt receives from certain services. -- [undici](https://www.npmjs.com/package/undici) for making http requests +- [undici](https://www.npmjs.com/package/undici) for making http requests. - [url-pattern](https://www.npmjs.com/package/url-pattern) to match provided links with supported patterns. ...and many other packages that these packages rely on. From 95bfa534805e63c89972e22ce506aa8e3d817989 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 20:44:00 +0600 Subject: [PATCH 15/25] css: proper rounding Signed-off-by: wukko --- src/front/cobalt.css | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/front/cobalt.css b/src/front/cobalt.css index 67516ed5..e9fe6376 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -991,47 +991,47 @@ button:active, .text-to-copy, .text-to-copy.text-backdrop, #filename-preview { - border-radius: 8px / 9px; + border-radius: 9px; } [type=checkbox] { - border-radius: 3px / 4px; + border-radius: 4px; } .popup, .scrollable .popup-content { border-radius: 12px; } .popup-header .glass-bkg { - border-top-left-radius: 11px 12px; - border-top-right-radius: 11px 12px; + border-top-left-radius: 12px; + border-top-right-radius: 12px; border-bottom: var(--accent-highlight) solid 0.1rem; top: -1px; } .popup-tabs .glass-bkg { - border-bottom-left-radius: 11px 12px; - border-bottom-right-radius: 11px 12px; + border-bottom-left-radius: 12px; + border-bottom-right-radius: 12px; border-top: var(--accent-highlight) solid 0.1rem; bottom: -1px; } .switches .switch:first-child { - border-top-left-radius: 8px 9px; - border-bottom-left-radius: 8px 9px; + border-top-left-radius: 9px; + border-bottom-left-radius: 9px; } .switches .switch:last-child { - border-top-right-radius: 8px 9px; - border-bottom-right-radius: 8px 9px; + border-top-right-radius: 9px; + border-bottom-right-radius: 9px; } .text-backdrop { - border-radius: 4px / 5px; + border-radius: 4px; } .collapse-list:first-child, .collapse-list:first-child .collapse-header { - border-top-left-radius: 7px 8px; - border-top-right-radius: 7px 8px; + border-top-left-radius: 8px; + border-top-right-radius: 8px; } .collapse-list:last-child, .collapse-list:last-child .collapse-header { - border-bottom-left-radius: 7px 8px; - border-bottom-right-radius: 7px 8px; + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; } .collapse-list:last-child.expanded .collapse-header { border-radius: 0; From 5bf8d954a41184ff9a167796c861daaf8066aa7b Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 20:49:34 +0600 Subject: [PATCH 16/25] readme: update disclaimer --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 0f5f9085..2ebd3067 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,6 @@ cobalt is a tool for easing content downloads from internet and takes ***zero li cobalt is ***NOT*** a piracy tool and cannot be used as such. it can only download free, publicly accessible content. such content can be easily downloaded through any browser's dev tools. pressing one button is easier, so i made a convenient, ad-less tool for such repeated actions. -cobalt is my passion project, update schedule depends solely on my free time, motivation, and mood. don't expect any consistency in update releases. - ## cobalt license cobalt code is licensed under [AGPL-3.0](https://github.com/wukko/cobalt/blob/current/LICENSE). From ae9e9ec4917e1357dcb5b541a005afd02404303f Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 22:15:31 +0600 Subject: [PATCH 17/25] front/elements: add id to urgent notice child Signed-off-by: wukko --- src/modules/pageRender/elements.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/pageRender/elements.js b/src/modules/pageRender/elements.js index 79129398..e59385e1 100644 --- a/src/modules/pageRender/elements.js +++ b/src/modules/pageRender/elements.js @@ -217,7 +217,7 @@ export function celebrationsEmoji() { export function urgentNotice(obj) { if (obj.visible) { return `
` + - `${emoji(obj.emoji, 18)} ${obj.text}` + + `${emoji(obj.emoji, 18)} ${obj.text}` + `
` } return `` From 66d471a7901321e2cf9ec0db7880257349371f03 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 22:50:42 +0600 Subject: [PATCH 18/25] front/css: fix logo css Signed-off-by: wukko --- src/front/cobalt.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/front/cobalt.css b/src/front/cobalt.css index e9fe6376..b5b372f6 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -262,9 +262,8 @@ button:active, align-items: center; } #logo { - text-align: left; + text-align: center; font-size: 1rem; - white-space: nowrap; height: 2.5rem; align-items: center; display: flex; From be0c771def5ab539c120cc56022964673417fa10 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 23:45:13 +0600 Subject: [PATCH 19/25] package: bump youtubei.js version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c40ecec8..64f46d41 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,6 @@ "set-cookie-parser": "2.6.0", "undici": "^6.7.0", "url-pattern": "1.0.3", - "youtubei.js": "^9.1.0" + "youtubei.js": "^9.2.0" } } From 3c30156ed9037ec2a11f873f4e46ec41baf382f0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sun, 31 Mar 2024 23:45:32 +0600 Subject: [PATCH 20/25] youtube: change client back --- src/modules/processing/services/youtube.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/processing/services/youtube.js b/src/modules/processing/services/youtube.js index 8a773375..10e813af 100644 --- a/src/modules/processing/services/youtube.js +++ b/src/modules/processing/services/youtube.js @@ -33,7 +33,7 @@ export default async function(o) { } try { - info = await yt.getBasicInfo(o.id, 'YTMUSIC_ANDROID'); + info = await yt.getBasicInfo(o.id, 'ANDROID'); } catch (e) { return { error: 'ErrorCantConnectToServiceAPI' }; } From 156372a1efe12a5ddfe31cbe69670f5c55af11f9 Mon Sep 17 00:00:00 2001 From: wukko Date: Mon, 1 Apr 2024 09:32:15 +0600 Subject: [PATCH 21/25] servicesConfig: add support for /photo/ twitter links --- src/modules/processing/servicesConfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/processing/servicesConfig.json b/src/modules/processing/servicesConfig.json index 4f07ebda..1b6730c1 100644 --- a/src/modules/processing/servicesConfig.json +++ b/src/modules/processing/servicesConfig.json @@ -22,6 +22,7 @@ "patterns": [ ":user/status/:id", ":user/status/:id/video/:index", + ":user/status/:id/photo/:index", ":user/status/:id/mediaviewer", ":user/status/:id/mediaViewer" ], From 9973655abebb77563fde0a703d6e8b049f178633 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 5 Apr 2024 11:52:59 +0600 Subject: [PATCH 22/25] css: reduce button padding for main box --- src/front/cobalt.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/front/cobalt.css b/src/front/cobalt.css index b5b372f6..7b59a1bf 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -799,7 +799,7 @@ button:active, } #cobalt-main-box #bottom button { width: auto; - padding: var(--gap) 1rem; + padding: var(--gap) 0.9rem; } .collapse-list { background: var(--subbackground); From 33a5a60969d9f69379587495b42cca4f8875c3be Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 5 Apr 2024 11:57:06 +0600 Subject: [PATCH 23/25] front: remove an option to hide new version dot turns out this option was confusing people (and also didn't do much) --- src/front/cobalt.js | 18 ++++++++++-------- src/localization/languages/en.json | 1 - src/localization/languages/ru.json | 1 - src/modules/pageRender/page.js | 4 ---- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/front/cobalt.js b/src/front/cobalt.js index 9d022e64..ad2e9e59 100644 --- a/src/front/cobalt.js +++ b/src/front/cobalt.js @@ -22,7 +22,6 @@ const switchers = { }; const checkboxes = [ "alwaysVisibleButton", - "disableChangelog", "downloadPopup", "fullTikTokAudio", "muteAudio", @@ -171,17 +170,21 @@ function notificationCheck(type) { default: changed = false; } - if (changed && sGet("changelogStatus") === `${version}` || type === "disable") { + if (changed && sGet("changelogStatus") === `${version}`) { setTimeout(() => { eid("about-footer").innerHTML = eid("about-footer").innerHTML.replace(notification, ''); eid("tab-button-about-changelog").innerHTML = eid("tab-button-about-changelog").innerHTML.replace(notification, '') }, 900) } - if (sGet("disableChangelog") !== "true") { - if (!sGet("seenAbout") && !eid("about-footer").innerHTML.includes(notification)) eid("about-footer").innerHTML = `${notification}${eid("about-footer").innerHTML}`; - if (sGet("changelogStatus") !== `${version}`) { - if (!eid("about-footer").innerHTML.includes(notification)) eid("about-footer").innerHTML = `${notification}${eid("about-footer").innerHTML}`; - if (!eid("tab-button-about-changelog").innerHTML.includes(notification)) eid("tab-button-about-changelog").innerHTML = `${notification}${eid("tab-button-about-changelog").innerHTML}`; + if (!sGet("seenAbout") && !eid("about-footer").innerHTML.includes(notification)) { + eid("about-footer").innerHTML = `${notification}${eid("about-footer").innerHTML}`; + } + if (sGet("changelogStatus") !== `${version}`) { + if (!eid("about-footer").innerHTML.includes(notification)) { + eid("about-footer").innerHTML = `${notification}${eid("about-footer").innerHTML}`; + } + if (!eid("tab-button-about-changelog").innerHTML.includes(notification)) { + eid("tab-button-about-changelog").innerHTML = `${notification}${eid("tab-button-about-changelog").innerHTML}`; } } } @@ -298,7 +301,6 @@ function checkbox(action) { case "reduceTransparency": eid("cobalt-body").classList.toggle('no-transparency'); break; case "disableAnimations": eid("cobalt-body").classList.toggle('no-animation'); break; } - action === "disableChangelog" && sGet(action) === "true" ? notificationCheck("disable") : notificationCheck(); } function changeButton(type, text) { switch (type) { diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json index 8450e11a..546c2841 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -80,7 +80,6 @@ "Miscellaneous": "miscellaneous", "ModeToggleAuto": "auto", "ModeToggleAudio": "audio", - "SettingsDisableNotifications": "hide notifications", "MediaPickerTitle": "pick what to save", "MediaPickerExplanationPC": "click or right click to download what you want.", "MediaPickerExplanationPhone": "press or press and hold to download what you want.", diff --git a/src/localization/languages/ru.json b/src/localization/languages/ru.json index a013ef52..8f66b5b0 100644 --- a/src/localization/languages/ru.json +++ b/src/localization/languages/ru.json @@ -80,7 +80,6 @@ "Miscellaneous": "разное", "ModeToggleAuto": "авто", "ModeToggleAudio": "аудио", - "SettingsDisableNotifications": "cкрыть уведомления", "MediaPickerTitle": "выбери, что сохранить", "MediaPickerExplanationPC": "кликни то, что хочешь скачать. также можно скачать правой кнопки мыши.", "MediaPickerExplanationPhone": "нажми, или нажми и удерживай, чтобы скачать.", diff --git a/src/modules/pageRender/page.js b/src/modules/pageRender/page.js index 3a8b6c6d..58bb3a97 100644 --- a/src/modules/pageRender/page.js +++ b/src/modules/pageRender/page.js @@ -523,10 +523,6 @@ export default function(obj) { }, { action: "disableMetadata", name: t("SettingsDisableMetadata") - }, { - action: "disableChangelog", - name: t("SettingsDisableNotifications"), - padding: "no-margin" }]) }) }] From cceae752758fac825866ad3fb678379e578e3488 Mon Sep 17 00:00:00 2001 From: wukko Date: Fri, 5 Apr 2024 11:57:23 +0600 Subject: [PATCH 24/25] package: bump version to 7.12.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64f46d41..8885f1f8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.12.3", + "version": "7.12.4", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", From 512e3feac9ea6bb09ada0bfbfa786b71296fc953 Mon Sep 17 00:00:00 2001 From: dumbmoron Date: Sun, 7 Apr 2024 00:07:19 +0000 Subject: [PATCH 25/25] servicesConfig/instagram: add support for reels link with username --- src/modules/processing/servicesConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/processing/servicesConfig.json b/src/modules/processing/servicesConfig.json index 1b6730c1..633fa2a6 100644 --- a/src/modules/processing/servicesConfig.json +++ b/src/modules/processing/servicesConfig.json @@ -79,7 +79,7 @@ "instagram": { "alias": "instagram reels, posts & stories", "patterns": [ - "reels/:postId", "reel/:postId", "p/:postId", ":username/p/:postId", + "reels/:postId", ":username/reel/:postId", "reel/:postId", "p/:postId", ":username/p/:postId", "tv/:postId", "stories/:username/:storyId" ], "enabled": true