diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d70b1821..8b7042d9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -29,20 +29,22 @@ jobs: 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: Get short commit hash - id: commit-hash - run: echo "commit_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + - name: Get release metadata + id: release-meta + run: | + version=$(cat package.json | jq -r .version) + echo "commit_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + echo "major_version=$(echo "$version" | cut -d. -f1)" >> $GITHUB_OUTPUT - 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 }} - type=raw,value=${{ steps.package-version.outputs.current-version }}-${{ steps.commit-hash.outputs.commit_short }} + type=raw,value=${{ steps.release-meta.outputs.version }} + type=raw,value=${{ steps.release-meta.outputs.major_version }} + type=raw,value=${{ steps.release-meta.outputs.version }}-${{ steps.release-meta.outputs.commit_short }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image diff --git a/docs/examples/docker-compose.example.yml b/docs/examples/docker-compose.example.yml index 8a5f9d67..b5ce8a30 100644 --- a/docs/examples/docker-compose.example.yml +++ b/docs/examples/docker-compose.example.yml @@ -2,7 +2,7 @@ version: '3.5' services: cobalt-api: - image: ghcr.io/wukko/cobalt:latest + image: ghcr.io/wukko/cobalt:7 restart: unless-stopped container_name: cobalt-api @@ -17,7 +17,6 @@ services: #- 127.0.0.1:9000:9000 environment: - - apiPort=9000 # replace apiURL with your instance's target url in same format - apiURL=https://co.wuk.sh/ # replace apiName with your instance's distinctive name @@ -33,7 +32,7 @@ services: #- ./cookies.json:/cookies.json cobalt-web: - image: ghcr.io/wukko/cobalt:latest + image: ghcr.io/wukko/cobalt:7 restart: unless-stopped container_name: cobalt-web @@ -48,7 +47,6 @@ services: #- 127.0.0.1:9001:9001 environment: - - webPort=9001 # replace webURL with your instance's target url in same format - webURL=https://cobalt.tools/ # replace apiURL with preferred api instance url @@ -63,4 +61,4 @@ services: restart: unless-stopped command: --cleanup --scope cobalt --interval 900 volumes: - - /var/run/docker.sock:/var/run/docker.sock \ No newline at end of file + - /var/run/docker.sock:/var/run/docker.sock diff --git a/package.json b/package.json index 6b1ca082..e1db6461 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cobalt", "description": "save what you love", - "version": "7.6.8", + "version": "7.7", "author": "wukko", "exports": "./src/cobalt.js", "type": "module", diff --git a/src/cobalt.js b/src/cobalt.js index 949cccba..2d90e07e 100644 --- a/src/cobalt.js +++ b/src/cobalt.js @@ -21,8 +21,8 @@ app.disable('x-powered-by'); await loadLoc(); -const apiMode = process.env.apiURL && process.env.apiPort && !((process.env.webURL && process.env.webPort) || (process.env.selfURL && process.env.port)); -const webMode = process.env.webURL && process.env.webPort && !((process.env.apiURL && process.env.apiPort) || (process.env.selfURL && process.env.port)); +const apiMode = process.env.apiURL && !process.env.webURL; +const webMode = process.env.webURL && process.env.apiURL; if (apiMode) { const { runAPI } = await import('./core/api.js'); @@ -31,5 +31,9 @@ if (apiMode) { 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`)) + 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`) + ) } diff --git a/src/config.json b/src/config.json index b1d17674..303af1ed 100644 --- a/src/config.json +++ b/src/config.json @@ -1,6 +1,6 @@ { - "streamLifespan": 20000, - "maxVideoDuration": 18000000, + "streamLifespan": 90000, + "maxVideoDuration": 10800000, "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/core/api.js b/src/core/api.js index 84464b56..4e78fbb5 100644 --- a/src/core/api.js +++ b/src/core/api.js @@ -139,9 +139,9 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { version: version, commit: gitCommit, branch: gitBranch, - name: process.env.apiName ? process.env.apiName : "unknown", + name: process.env.apiName || "unknown", url: process.env.apiURL, - cors: process.env.cors && process.env.cors === "0" ? 0 : 1, + cors: process.env?.cors === "0" ? 0 : 1, startTime: `${startTimestamp}` }); default: @@ -167,12 +167,12 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { res.redirect('/api/json') }); - app.listen(process.env.apiPort, () => { + app.listen(process.env.apiPort || 9000, () => { console.log(`\n` + `${Cyan("cobalt")} API ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` + `Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` + `URL: ${Cyan(`${process.env.apiURL}`)}\n` + - `Port: ${process.env.apiPort}\n` + `Port: ${process.env.apiPort || 9000}\n` ) }); } diff --git a/src/core/web.js b/src/core/web.js index c2512c1f..08a6ffed 100644 --- a/src/core/web.js +++ b/src/core/web.js @@ -76,12 +76,12 @@ export async function runWeb(express, app, gitCommit, gitBranch, __dirname) { return res.redirect('/') }); - app.listen(process.env.webPort, () => { + app.listen(process.env.webPort || 9001, () => { console.log(`\n` + `${Cyan("cobalt")} WEB ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` + `Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` + `URL: ${Cyan(`${process.env.webURL}`)}\n` + - `Port: ${process.env.webPort}\n` + `Port: ${process.env.webPort || 9001}\n` ) }) } diff --git a/src/front/cobalt.js b/src/front/cobalt.js index 4a3ad9e6..47a0d368 100644 --- a/src/front/cobalt.js +++ b/src/front/cobalt.js @@ -1,4 +1,4 @@ -const version = 38; +const version = 39; const ua = navigator.userAgent.toLowerCase(); const isIOS = ua.match("iphone os"); @@ -423,9 +423,16 @@ async function download(url) { let jp = await res.json(); if (jp.status === "continue") { changeDownloadButton(2, '>>>'); - if (isMobile || isSafari) { - window.location.href = j.url; - } else window.open(j.url, '_blank'); + if (sGet("downloadPopup") === "true") { + popup('download', 1, j.url) + setTimeout(() => { + hideAllPopups() + }, 85000) + } else { + if (isMobile || isSafari) { + window.location.href = j.url; + } else window.open(j.url, '_blank'); + } setTimeout(() => { changeButton(1) }, 2500); } else { changeButton(0, jp.text); diff --git a/src/front/updateBanners/meowthpolishegg.webp b/src/front/updateBanners/meowthpolishegg.webp new file mode 100644 index 00000000..d0891b41 Binary files /dev/null and b/src/front/updateBanners/meowthpolishegg.webp differ diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json index 62ef6a90..463d8cd9 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -105,7 +105,7 @@ "FollowSupport": "keep in touch with cobalt for support, polls, news, and more:", "SupportNote": "please note that response may take a while, there's only one person managing everything.", "SourceCode": "report issues, explore source code, star or fork the repo:", - "PrivacyPolicy": "cobalt's privacy policy is simple: no data about you is ever collected or stored. zero, zilch, nada, nothing.\nwhat you download is solely your business, not mine or anyone else's.\n\nif your download requires live render, some non-backtraceable data is temporarily stored in server's RAM. it's necessary for this feature to function.\n\nin this case info about requested content is stored for 20 seconds and then permanently removed.\nno one (even me) has access to this data. official cobalt codebase doesn't provide a way to read it outside of processing functions.\n\nyou can check cobalt's source code yourself and see that everything is as stated.", + "PrivacyPolicy": "cobalt's privacy policy is simple: no data about you is ever collected or stored. zero, zilch, nada, nothing.\nwhat you download is solely your business, not mine or anyone else's.\n\nif your download requires live render, some non-backtraceable data is temporarily stored in server's RAM. it's necessary for this feature to function.\n\nin this case info about requested content is stored for 90 seconds and then permanently removed.\nno one (even me) has access to this data. official cobalt codebase doesn't provide a way to read it outside of processing functions.\n\nyou can check cobalt's source code yourself and see that everything is as stated.", "ErrorYTUnavailable": "this youtube video is unavailable, it could be region or age restricted. try another one!", "ErrorYTTryOtherCodec": "i couldn't find anything to download with your settings. try another codec or quality!\n\nsometimes youtube api sometimes acts unexpectedly. try again or try another settings.", "SettingsCodecSubtitle": "youtube codec", @@ -156,6 +156,7 @@ "FilenamePreviewVideoTitle": "Video Title", "FilenamePreviewAudioTitle": "Audio Title", "FilenamePreviewAudioAuthor": "Audio Author", - "UrgentFilenameUpdate": "customizable file names!" + "UrgentFilenameUpdate": "customizable file names!", + "UrgentTwitterPatch": "fixes and easier downloads" } } diff --git a/src/localization/languages/ru.json b/src/localization/languages/ru.json index ec2e60d7..9e9bbe0c 100644 --- a/src/localization/languages/ru.json +++ b/src/localization/languages/ru.json @@ -106,7 +106,7 @@ "FollowSupport": "подписывайся на соц.сети кобальта для новостей, поддержки, участия в опросах, и многого другого:", "SupportNote": "так как я занимаюсь разработкой и поддержкой в одиночку, время ожидания ответа может достигать нескольких часов. но я отвечаю всем, так что не стесняйся.", "SourceCode": "пиши о проблемах, шарься в исходнике, или же форкай репозиторий:", - "PrivacyPolicy": "политика конфиденциальности кобальта довольно проста: никакие данные о тебе никогда не собираются и не хранятся. нуль, ноль, нада, ничего.\nто, что ты скачиваешь, - твоё личное дело, а не чьё-либо ещё.\n\nесли твоей загрузке требуется лайв рендер, то некоторые неотслеживаемые данные временно держатся в ОЗУ сервера. это необходимо для работы данной функции.\n\nв этом случае данные о запрошенном контенте хранятся в течение 20 секунд. по истечении этого времени всё стирается. ни у кого (даже у меня) нет доступа к временно хранящимся данным, так как официальная кодовая база кобальта не предусматривает возможности их чтения вне функций обработки.\n\nты всегда можешь посмотреть исходный код кобальта и убедиться, что всё так, как заявлено.", + "PrivacyPolicy": "политика конфиденциальности кобальта довольно проста: никакие данные о тебе никогда не собираются и не хранятся. нуль, ноль, нада, ничего.\nто, что ты скачиваешь, - твоё личное дело, а не чьё-либо ещё.\n\nесли твоей загрузке требуется лайв рендер, то некоторые неотслеживаемые данные временно держатся в ОЗУ сервера. это необходимо для работы данной функции.\n\nв этом случае данные о запрошенном контенте хранятся в течение 90 секунд. по истечении этого времени всё стирается. ни у кого (даже у меня) нет доступа к временно хранящимся данным, так как официальная кодовая база кобальта не предусматривает возможности их чтения вне функций обработки.\n\nты всегда можешь посмотреть исходный код кобальта и убедиться, что всё так, как заявлено.", "ErrorYTUnavailable": "это видео недоступно, возможно оно ограничено по региону или доступу. попробуй другое!", "ErrorYTTryOtherCodec": "я не нашёл того, что мог бы скачать с твоими настройками. попробуй другой кодек или качество!", "SettingsCodecSubtitle": "кодек для видео с youtube", @@ -158,6 +158,7 @@ "FilenamePreviewVideoTitle": "Название Видео", "FilenamePreviewAudioTitle": "Название Аудио", "FilenamePreviewAudioAuthor": "Автор Аудио", - "UrgentFilenameUpdate": "изменяемые названия файлов!" + "UrgentFilenameUpdate": "изменяемые названия файлов!", + "UrgentTwitterPatch": "фиксы и удобное скачивание" } } diff --git a/src/modules/changelog/changelog.json b/src/modules/changelog/changelog.json index 3455405b..b9b1fbdc 100644 --- a/src/modules/changelog/changelog.json +++ b/src/modules/changelog/changelog.json @@ -1,5 +1,16 @@ { "current": { + "version": "7.7", + "date": "December 2, 2023", + "title": "bugfixes and better downloads!", + "banner": { + "file": "meowthpolishegg.webp", + "width": 851, + "height": 640 + }, + "content": "this update fixes various issues with supported services. no new features yet, but twitter fix is surely something good to have in the meantime!\n\nservice improvements:\n*; broken twitter videos are now automatically fixed by cobalt.\n*; all vimeo videos and audios should now possible to download.\n*; vimeo: fixed short resolution displayed in \"basic\" and \"pretty\" filename styles.\n\ninterface improvements:\n*; streamables are now easier to save on ios.\n\ninternal improvements:\n*; port env variable is now not strictly necessary for cobalt to run.\n*; minor clean up.\n\nchanges since 7.6:\n*; fix for an issue related to youtube dubs.\n*; fixed a memory leak related to live renders.\n*; handling all errors related to twitter downloads.\n*; fixed support for reddit links in various languages.\n*; added rich filenames support for twitch clips.\n*; updated support and donation lists.\n\nstay tuned for future updates and have a great day :D" + }, + "history": [{ "version": "7.6", "date": "October 15, 2023", "title": "customizable file names, instagram stories, and first cobalt sponsor!", @@ -9,8 +20,7 @@ "height": 640 }, "content": "as many have (very) often requested, cobalt now lets you pick between several file name format styles!\ngo to settings > other and change it to whichever you like! there's a preview of each style, so you know how exactly files are gonna look like.\n\nif you liked file names the way they were before, don't worry: classic style is still the default :)\n\non a different but not any less important note: cobalt is now sponsored by royalehosting.net!\noverall service performance and stability is gonna be better, but also more content will be possible to download thanks to geniuine server locations. and yes, still no ads or trackers.\n\nthis update also includes a bunch of other changes, check them out:\n\nservice improvements:\n*; added support for instagram stories thanks to #194.\n*; fixed reddit support thanks to #221.\n*; added support for rich file names for youtube, vimeo, soundcloud, rutube, and vk.\n*; numbers and emoji no longer disappear from file name and metadata.\n*; mute and audio dub file name tags don't appear together anymore.\n*; youtube: dub file name tag doesn't appear anymore if audio track is default.\n\ninterface improvements:\n*; added a list of sponsors to about tab. if you host an instance, it's disabled by default, but can be enabled with showSponsors env variable.\n*; about button now opens about tab when no new changelog is available.\n*; fixed download button thickness on ios.\n\nyou now can reach out to cobalt via email for support! it's located in the about tab along with other socials, such as discord.\n\ni hope you enjoy this long-awaited update and have a blissful day :D" - }, - "history": [{ + }, { "version": "7.5", "date": "September 16, 2023", "title": "support for twitch clips and rutube!", diff --git a/src/modules/pageRender/page.js b/src/modules/pageRender/page.js index b572a8b7..e782e25b 100644 --- a/src/modules/pageRender/page.js +++ b/src/modules/pageRender/page.js @@ -562,8 +562,8 @@ export default function(obj) {