From 7ebe28ce50d3448a0cbc09b6d1eaa21812ebeb5d Mon Sep 17 00:00:00 2001 From: dumbmoron <136796770+dumbmoron@users.noreply.github.com> Date: Sun, 2 Jul 2023 00:40:47 +0200 Subject: [PATCH 1/9] create docker build github action --- .github/workflows/docker.yml | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..96225d0 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,52 @@ +name: Build Docker image + +on: + push: + branches: ['current'] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get version from package.json + id: package-version + uses: martinbeentjes/npm-get-version-action@v1.3.1 + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + tags: | + type=raw,value=latest + type=raw,value=${{ steps.package-version.outputs.current-version }} + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 239db34c6752de36de892c51e9b6a5e8a133bb7f Mon Sep 17 00:00:00 2001 From: dumbmoron <136796770+dumbmoron@users.noreply.github.com> Date: Sun, 2 Jul 2023 05:21:08 +0200 Subject: [PATCH 2/9] remove support for armv6 no armv6 build of node:18-bullseye-slim, can be readded once this is fixed --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 96225d0..edfe0b5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -46,7 +46,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 + platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From d2e5b6f1fbfefddea8f940d474613eee50065344 Mon Sep 17 00:00:00 2001 From: dumbmoron <136796770+dumbmoron@users.noreply.github.com> Date: Sun, 2 Jul 2023 05:24:28 +0200 Subject: [PATCH 3/9] add per-commit image tag --- .github/workflows/docker.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index edfe0b5..86ad0a7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,6 +33,9 @@ jobs: - name: Get version from package.json id: package-version uses: martinbeentjes/npm-get-version-action@v1.3.1 + - name: Get short commit hash + id: commit-hash + run: echo "commit_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v4 @@ -40,6 +43,7 @@ jobs: tags: | type=raw,value=latest type=raw,value=${{ steps.package-version.outputs.current-version }} + type=raw,value=${{ steps.package-version.outputs.current-version }}-${{ steps.commit-hash.outputs.commit_short }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image From be21c86d89efe8a89f0dea05f77ba68a0b7bbb86 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 26 Aug 2023 00:03:24 +0600 Subject: [PATCH 4/9] youtube: added support for live links --- package.json | 2 +- src/modules/processing/hostOverrides.js | 8 +++++++- src/test/tests.json | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 034ca7a..4c075ad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.1.2", + "version": "7.1.3", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", diff --git a/src/modules/processing/hostOverrides.js b/src/modules/processing/hostOverrides.js index 211cd2a..11104bd 100644 --- a/src/modules/processing/hostOverrides.js +++ b/src/modules/processing/hostOverrides.js @@ -3,10 +3,16 @@ export default function (inHost, inURL) { let url = String(inURL); switch(host) { + case "youtube": + if (url.startsWith("https://youtube.com/live/") || url.startsWith("https://www.youtube.com/")) { + url = url.split("?")[0].replace("www.", ""); + url = `https://youtube.com/watch?v=${url.replace("https://youtube.com/live/", "")}` + } + break; case "youtu": if (url.startsWith("https://youtu.be/")) { host = "youtube"; - url = `https://youtube.com/watch?v=${url.replace("https://youtu.be/", "")}`; + url = `https://youtube.com/watch?v=${url.replace("https://youtu.be/", "")}` } break; case "vxtwitter": diff --git a/src/test/tests.json b/src/test/tests.json index 3415550..905f5c7 100644 --- a/src/test/tests.json +++ b/src/test/tests.json @@ -465,6 +465,14 @@ "code": 200, "status": "stream" } + }, { + "name": "live link, defaults", + "url": "https://www.youtube.com/live/ENxZS6PUDuI?feature=shared", + "params": {}, + "expected": { + "code": 200, + "status": "stream" + } }, { "name": "inexistent video", "url": "https://youtube.com/watch?v=gnjuHYWGEW", From 8dcb6d8ea7d204b1012b1a6ffb4918eb63fa00a0 Mon Sep 17 00:00:00 2001 From: wukko Date: Sat, 26 Aug 2023 00:53:05 +0600 Subject: [PATCH 5/9] a typo just broke everything --- src/modules/processing/hostOverrides.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/processing/hostOverrides.js b/src/modules/processing/hostOverrides.js index 11104bd..a9f2fc2 100644 --- a/src/modules/processing/hostOverrides.js +++ b/src/modules/processing/hostOverrides.js @@ -4,7 +4,7 @@ export default function (inHost, inURL) { switch(host) { case "youtube": - if (url.startsWith("https://youtube.com/live/") || url.startsWith("https://www.youtube.com/")) { + if (url.startsWith("https://youtube.com/live/") || url.startsWith("https://www.youtube.com/live/")) { url = url.split("?")[0].replace("www.", ""); url = `https://youtube.com/watch?v=${url.replace("https://youtube.com/live/", "")}` } From 055eff92da42ddb299b12a3e7c0378c6fe8e5a54 Mon Sep 17 00:00:00 2001 From: wukko Date: Tue, 29 Aug 2023 23:24:00 +0600 Subject: [PATCH 6/9] 7.2: small improvements - increased video length to 5 hours from 3 hours. - fixed clickable area for urgent notice. - possibly fixed random 0kb files. --- package.json | 2 +- src/config.json | 2 +- src/front/cobalt.css | 6 +++++- src/modules/pageRender/elements.js | 4 +++- src/modules/stream/types.js | 7 +++++-- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 4c075ad..ca34e23 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.1.3", + "version": "7.2", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", diff --git a/src/config.json b/src/config.json index 6337654..1537223 100644 --- a/src/config.json +++ b/src/config.json @@ -1,6 +1,6 @@ { "streamLifespan": 20000, - "maxVideoDuration": 10800000, + "maxVideoDuration": 18000000, "genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "authorInfo": { "name": "wukko", diff --git a/src/front/cobalt.css b/src/front/cobalt.css index 8e666dd..896df72 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -797,12 +797,16 @@ button:active, width: 100%; text-align: center; position: absolute; - cursor: pointer; display: flex; justify-content: center; align-items: center; padding-top: calc(env(safe-area-inset-top) + 1rem); } +.urgent-text { + display: flex; + align-items: center; + cursor: pointer; +} .no-transparency .glass-bkg, .no-transparency #popup-backdrop { backdrop-filter: none; diff --git a/src/modules/pageRender/elements.js b/src/modules/pageRender/elements.js index 66e6de1..7ba13bd 100644 --- a/src/modules/pageRender/elements.js +++ b/src/modules/pageRender/elements.js @@ -205,7 +205,9 @@ export function celebrationsEmoji() { } export function urgentNotice(obj) { if (obj.visible) { - return `
${emoji(obj.emoji, 18)} ${obj.text}
` + return `
` + + `${emoji(obj.emoji, 18)} ${obj.text}` + + `
` } return `` } diff --git a/src/modules/stream/types.js b/src/modules/stream/types.js index eeec5a5..50cd11c 100644 --- a/src/modules/stream/types.js +++ b/src/modules/stream/types.js @@ -16,7 +16,8 @@ export async function streamDefault(streamInfo, res) { res.setHeader('Content-disposition', `attachment; filename="${streamInfo.isAudioOnly ? `${streamInfo.filename}.${streamInfo.audioFormat}` : regFilename}"`); const { body: stream, headers } = await request(streamInfo.urls, { - headers: { 'user-agent': genericUserAgent } + headers: { 'user-agent': genericUserAgent }, + maxRedirections: 16 }); res.setHeader('content-type', headers['content-type']); @@ -33,7 +34,9 @@ export async function streamLiveRender(streamInfo, res) { try { if (streamInfo.urls.length !== 2) return fail(res); - let { body: audio } = await request(streamInfo.urls[1]); + let { body: audio } = await request(streamInfo.urls[1], { + maxRedirections: 16 + }); let format = streamInfo.filename.split('.')[streamInfo.filename.split('.').length - 1], args = [ From f5ad598d2f8d3d0c1b8b465bb2a2894d9181c362 Mon Sep 17 00:00:00 2001 From: dumbmoron <136796770+dumbmoron@users.noreply.github.com> Date: Tue, 29 Aug 2023 20:18:19 +0200 Subject: [PATCH 7/9] github action: manual trigger instead of per-commit --- .github/workflows/docker.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 86ad0a7..d70b182 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,8 +1,7 @@ name: Build Docker image on: - push: - branches: ['current'] + workflow_dispatch: env: REGISTRY: ghcr.io From ac3998ddda555b8893dd55a3f018df87aaddf72e Mon Sep 17 00:00:00 2001 From: dumbmoron <136796770+dumbmoron@users.noreply.github.com> Date: Thu, 24 Aug 2023 06:36:38 +0000 Subject: [PATCH 8/9] import particular mode module only if needed mostly relevant because frontend does not need an innertube session --- src/cobalt.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cobalt.js b/src/cobalt.js index d03bca2..949cccb 100644 --- a/src/cobalt.js +++ b/src/cobalt.js @@ -9,9 +9,6 @@ import { loadLoc } from "./localization/manager.js"; import path from 'path'; import { fileURLToPath } from 'url'; -import { runWeb } from "./core/web.js"; -import { runAPI } from "./core/api.js"; - const app = express(); const gitCommit = shortCommit(); @@ -28,8 +25,10 @@ const apiMode = process.env.apiURL && process.env.apiPort && !((process.env.webU const webMode = process.env.webURL && process.env.webPort && !((process.env.apiURL && process.env.apiPort) || (process.env.selfURL && process.env.port)); if (apiMode) { + const { runAPI } = await import('./core/api.js'); runAPI(express, app, gitCommit, gitBranch, __dirname) } else if (webMode) { + const { runWeb } = await import('./core/web.js'); await runWeb(express, app, gitCommit, gitBranch, __dirname) } else { console.log(Red(`cobalt wasn't configured yet or configuration is invalid.\n`) + Bright(`please run the setup script to fix this: `) + Green(`npm run setup`)) From be00900a499c6a47d57111a6c03c58497b70e1eb Mon Sep 17 00:00:00 2001 From: wukko Date: Wed, 6 Sep 2023 19:37:03 +0600 Subject: [PATCH 9/9] fixes for poor rendering in chrome - fixed blurry header - fixed blurry tab bar - fixed blurry switches - fixed weirdly rounded corners in popups - fixed 1px gap on edges of various elements in popup - fixed overscrolling in other settings tab - fixed unexpected button highlight effect in mobile version - removed outdated fixed for tiny screens --- src/front/cobalt.css | 146 ++++++++++------------------- src/localization/languages/en.json | 3 +- src/localization/languages/ru.json | 3 +- src/modules/pageRender/elements.js | 20 +++- src/modules/pageRender/page.js | 10 +- src/test/tests.json | 2 +- 6 files changed, 73 insertions(+), 111 deletions(-) diff --git a/src/front/cobalt.css b/src/front/cobalt.css index 896df72..0e11615 100644 --- a/src/front/cobalt.css +++ b/src/front/cobalt.css @@ -175,6 +175,24 @@ input[type="text"], backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px); } +.glass-bkg.alone { + z-index: -1; + top: 0; + left: 0; + bottom: 0; + right: 0; + position: absolute; +} +.glass-bkg.small { + top: 0; + left: 0; + bottom: 0; + right: 0; + z-index: -1; + position: absolute; + border: var(--accent-highlight) solid 0.15rem; + border-radius: 8px/9px; +} .desktop button:hover, .desktop .switch:hover, .desktop .checkbox:hover, @@ -198,7 +216,7 @@ button:active, .popup.small .switch { background: var(--accent-button-elevated); } -.popup.small .switch:hover { +.desktop .popup.small .switch:hover { background: var(--accent-hover-elevated); } .switch.text-backdrop, @@ -267,7 +285,6 @@ button:active, } .box { background: var(--background); - border: var(--glass) solid .2rem; color: var(--accent); } #url-input-area { @@ -375,7 +392,8 @@ button:active, max-height: 95%; opacity: 0; transform: translate(-50%,-48%)scale(.95); - box-shadow: 0 0 20px 0 var(--accent-hover-transparent); + box-shadow: 0 0 0 0.2rem var(--glass) inset, + 0 0 20px 0 var(--accent-hover-transparent); } .popup.visible { visibility: visible; @@ -404,7 +422,6 @@ button:active, .popup.small { width: 20%; box-shadow: 0px 0px 60px 0px var(--accent-hover); - border: var(--accent-highlight) solid 0.15rem; padding: 1.7rem; transform: translate(-50%,-50%)scale(.95); pointer-events: all; @@ -530,7 +547,6 @@ button:active, z-index: 999; padding-top: calc(env(safe-area-inset-top)/2 + 1.7rem); width: 100%; - border-bottom: var(--accent-highlight) solid 0.1rem; } .settings-category { padding-bottom: 1rem; @@ -629,7 +645,6 @@ button:active, width: auto; flex-direction: row; flex-wrap: nowrap; - overflow-x: scroll; scrollbar-width: none; } .switches .switch { @@ -672,7 +687,6 @@ button:active, width: 100%; padding-top: 0.2rem; padding-bottom: 1.7rem; - border-top: var(--accent-highlight) solid 0.1rem; } .popup-tabs-child { width: 100%; @@ -907,13 +921,17 @@ button:active, .scrollable #popup-content { border-radius: 8px / 9px; } -#popup-header { - border-top-left-radius: 5px; - border-top-right-radius: 5px; +#popup-header .glass-bkg { + border-top-left-radius: 8px 9px; + border-top-right-radius: 8px 9px; + border-bottom: var(--accent-highlight) solid 0.1rem; + top: -1px; } -#popup-tabs { - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; +#popup-tabs .glass-bkg { + border-bottom-left-radius: 8px 9px; + border-bottom-right-radius: 8px 9px; + border-top: var(--accent-highlight) solid 0.1rem; + bottom: -1px; } .switches .first { border-top-left-radius: 5px 6px; @@ -1009,87 +1027,6 @@ button:active, width: calc(100% - 1.3rem); } } -@media screen and (max-width: 320px) { - :root { - --gap: 0.38rem; - --gap-no-icon: 0.38rem; - --line-height: 1.2rem; - } - #popup-title { - font-size: 1.07rem; - line-height: 1.5rem; - } - .checkbox { - width: calc(100% - 1rem); - } - .footer-button, - #audioMode-false, - #audioMode-true, - #paste { - font-size: 0!important; - } - .footer-button .emoji, - #audioMode-false .emoji, - #audioMode-true .emoji, - #paste .emoji { - margin-right: 0; - } - .switch, - .checkbox, - .category-title, - .subtitle, - #popup-desc, - .collapse-title { - font-size: 0.7rem; - } - .collapse-header { - padding: 0.5rem; - } - #popup-above-title, - #url-input-area { - font-size: 0.6rem; - } - .explanation { - font-size: 0.6rem; - margin-top: 0.5rem; - line-height: 1rem!important; - } - #popup-desc { - line-height: 1.2rem; - font-size: 0.64rem; - } - .changelog-subtitle, #popup-subtitle { - font-size: 0.8rem!important; - } - .category-title { - margin-bottom: 0.8rem; - } - .emoji { - height: 18px; - width: 18px; - } - .desc-padding { - padding-bottom: 0.8rem; - } - #logo { - font-size: 0.8rem; - } - .popup, - .popup.scrollable, - .popup.small { - height: 98%; - } - [type=checkbox] { - width: 15px; - height: 15px; - border: 0.12rem solid var(--accent); - } - [type=checkbox]:before { - transform: scaleY(.8)scaleX(.7)rotate(45deg); - left: 3.4px; - top: -2px; - } -} @media screen and (max-width: 720px) { #cobalt-main-box { width: calc(100% - (0.7rem * 2)); @@ -1128,10 +1065,20 @@ button:active, padding-top: calc(env(safe-area-inset-bottom)/2 + 1rem); } .popup, - #popup-header, - #popup-tabs { + #popup-header .glass-bkg, + #popup-tabs .glass-bkg, + .glass-bkg.small { border-radius: 0; } + #popup-tabs .glass-bkg { + bottom: 0; + } + .switches { + overflow-x: scroll; + } + .checkbox { + margin-right: 0; + } .popup.center { top: unset; left: unset; @@ -1145,11 +1092,13 @@ button:active, left: 0; transform: none; position: absolute; - border: none; - border-top: var(--accent-highlight) solid 0.15rem; padding-bottom: calc(env(safe-area-inset-bottom)/2 + 1.7rem); transform: translateY(30rem); } + .glass-bkg.small { + border: none; + border-top: var(--accent-highlight) solid 0.15rem; + } .popup.small.visible { transform: none; transition: transform 200ms cubic-bezier(0.075, 0.82, 0.165, 1), opacity 130ms ease-in-out; @@ -1177,6 +1126,7 @@ button:active, width: 100%; height: 100%; max-height: 100%; + box-shadow: none; } #popup-tabs { padding-bottom: calc(env(safe-area-inset-bottom)/2 + 1.5rem); diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json index b087f99..4f4d0ac 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -136,6 +136,7 @@ "KeyboardShortcutClosePopup": "close all popups", "CollapseLegal": "legal stuff", "FairUse": "cobalt is a tool for easing content downloads from internet and takes zero liability. you are responsible for what you download, how you use and distribute that content.\n\ncobalt does not log any info about you, it's impossible for me to snitch on you, but please be mindful when using content of others and always credit original creators!\n\nwhen used in education purposes (lecture, homework, etc) please attach the source link.\n\nfair use and credits benefit everyone.", - "UrgentFeatureUpdate71": "more supported services!" + "UrgentFeatureUpdate71": "more supported services!", + "UrgentThanks": "thank you for support!" } } diff --git a/src/localization/languages/ru.json b/src/localization/languages/ru.json index d65353b..3330dcb 100644 --- a/src/localization/languages/ru.json +++ b/src/localization/languages/ru.json @@ -137,6 +137,7 @@ "KeyboardShortcutClosePopup": "закрыть все окна", "CollapseLegal": "правовые штучки", "FairUse": "кобальт - это инструмент для облегчения скачивания контента из интернета, и он не несёт никакой ответственности. ты несёшь ответственность за то, что скачиваешь, как используешь и распространяешь скачанный контент.\n\nкобальт не собирает никакой информации о тебе, и не может донести на тебя, но, пожалуйста, будь сознателен при использовании чужого контента и всегда указывай авторов!\n\nпри использовании в образовательных целях (лекции, домашние задания и т.д.), пожалуйста, прикладывай ссылку на источник.\n\nчестное использование и указание авторства выгодно всем.", - "UrgentFeatureUpdate71": "расширение поддержки сервисов!" + "UrgentFeatureUpdate71": "расширение поддержки сервисов!", + "UrgentThanks": "спасибо за поддержку!" } } diff --git a/src/modules/pageRender/elements.js b/src/modules/pageRender/elements.js index 7ba13bd..a1940d5 100644 --- a/src/modules/pageRender/elements.js +++ b/src/modules/pageRender/elements.js @@ -68,17 +68,19 @@ export function popup(obj) { } return ` ${obj.standalone ? `