basically new readme and more languages
- indonesian localization by @LyfeV - rewrote readme - added new line at the end for files that were missing it
This commit is contained in:
parent
ca1a5a32b4
commit
c0289b6a8c
26 changed files with 73 additions and 44 deletions
69
README.md
69
README.md
|
@ -1,34 +1,62 @@
|
||||||
# cobalt
|
# cobalt
|
||||||
Sleek and easy to use social media downloader built on JavaScript. Try it out live: [co.wukko.me](https://co.wukko.me/)!
|
Sleek and easy to use social media downloader built with JavaScript.
|
||||||
|
|
||||||
|
Try it now: [co.wukko.me](https://co.wukko.me/)
|
||||||
|
|
||||||
![cobalt logo](https://raw.githubusercontent.com/wukko/cobalt/current/src/front/icons/wide.png "cobalt logo")
|
![cobalt logo](https://raw.githubusercontent.com/wukko/cobalt/current/src/front/icons/wide.png "cobalt logo")
|
||||||
|
|
||||||
## What is cobalt?
|
## What's cobalt?
|
||||||
cobalt aims to be the ultimate social media downloader, that is efficient, pretty, and doesn't bother you with ads or privacy invasion agreement popups.
|
cobalt aims to be the ultimate social media downloader, that is efficient, pretty, and doesn't bother you with ads or privacy invasion agreement popups. It also doesn't remux anything, so you get media in best quality possible (unless you change that in settings).
|
||||||
|
|
||||||
cobalt doesn't remux any videos, so you get videos of max quality available (unless you change that in settings).
|
## Supported services
|
||||||
|
|
||||||
## What's supported?
|
### Video
|
||||||
- Twitter
|
|
||||||
- TikTok
|
|
||||||
- douyin
|
|
||||||
- YouTube and YouTube Music
|
|
||||||
- bilibili.com
|
- bilibili.com
|
||||||
|
- douyin
|
||||||
- Reddit
|
- Reddit
|
||||||
|
- TikTok
|
||||||
|
- Twitter
|
||||||
|
- YouTube
|
||||||
|
- YouTube Music
|
||||||
- VK
|
- VK
|
||||||
|
|
||||||
|
### Audio
|
||||||
|
- YouTube
|
||||||
|
- YouTube Music
|
||||||
|
|
||||||
|
## Translations
|
||||||
|
- Spanish: [@adrigoomy](https://github.com/adrigoomy)
|
||||||
|
- French: [@lexito-o](https://github.com/lexito-o)
|
||||||
|
- Indonesian: [@LyfeV](https://github.com/LyfeV)
|
||||||
|
|
||||||
|
## How you can help cobalt speak your language
|
||||||
|
Take English or Russian localization from [this directory](https://github.com/wukko/cobalt/tree/current/src/localization/languages) and use it as a base for your translation. Then simply make a pull request and it'll be out for everyone upon review!
|
||||||
|
|
||||||
|
### What you should keep in mind:
|
||||||
|
- Do **NOT** use formal language, that's boring and lame. Use informal language on all occasions.
|
||||||
|
- Strings are **ALWAYS** lowercase unless it's an internal value like {ContactLink} or STRESSED LIKE THIS.
|
||||||
|
- Keep translations as friendly and fun as possible.
|
||||||
|
- Word-for-word translations from original language are not valid.
|
||||||
|
- You can rephrase sentences as long as they keep the same sense.
|
||||||
|
- You can add wordplays or puns if it feels natural to do so.
|
||||||
|
- Even though I love cursing, keep that away from translations.
|
||||||
|
- Be nice.
|
||||||
|
|
||||||
## TO-DO
|
## TO-DO
|
||||||
|
|
||||||
|
### Services
|
||||||
|
- [ ] Tumblr support
|
||||||
- [ ] niconico support
|
- [ ] niconico support
|
||||||
- [ ] Instagram support
|
- [ ] Instagram support
|
||||||
- [ ] Quality switching for bilibili and Twitter
|
- [ ] SoundCloud support (?)
|
||||||
- [ ] Language picker in settings
|
- [ ] Add an option to save Twitter GIFs as `.gif` instead of `.mp4`
|
||||||
- [ ] Make cobalt fully PWA compatible (add a service worker)
|
- [ ] Quality switching for bilibili
|
||||||
- [ ] Make switch buttons in settings selectable with keyboard
|
|
||||||
- [ ] Remake page rendering module to be more versatile
|
|
||||||
- [ ] Matching could be redone, I'll see what I can do
|
|
||||||
|
|
||||||
## Disclaimer
|
### Other
|
||||||
This is my passion project, so update scheduele depends on my motivation. Don't expect any consistency in that.
|
- [ ] Language picker in settings
|
||||||
|
- [ ] Make switch buttons in settings selectable with keyboard
|
||||||
|
- [ ] Make cobalt fully PWA compatible (add a service worker)
|
||||||
|
- [ ] Make page rendering module more versatile
|
||||||
|
|
||||||
## Host an instance yourself
|
## Host an instance yourself
|
||||||
Code might be a little messy, but I do my best to improve it with every commit.
|
Code might be a little messy, but I do my best to improve it with every commit.
|
||||||
|
@ -50,12 +78,15 @@ Code might be a little messy, but I do my best to improve it with every commit.
|
||||||
- xml-js
|
- xml-js
|
||||||
- ytdl-core
|
- ytdl-core
|
||||||
|
|
||||||
Setup script installs all needed **npm** dependencies, but you have to install Node.js and git yourself, if you don't have those already.
|
Setup script installs all needed `npm` dependencies, but you have to install `Node.js` and `git` yourself.
|
||||||
|
|
||||||
1. Clone the repo: `git clone https://github.com/wukko/cobalt`
|
1. Clone the repo: `git clone https://github.com/wukko/cobalt`
|
||||||
2. Run setup script and follow instructions: `npm run setup`
|
2. Run setup script and follow instructions: `npm run setup`
|
||||||
3. Run cobalt via `npm start`
|
3. Run cobalt via `npm start`
|
||||||
4. Done.
|
4. Done.
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
This is my passion project, so update scheduele depends solely on my motivation. Don't expect any consistency in that.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
cobalt is under [AGPL-3.0 license](https://github.com/wukko/cobalt/blob/current/LICENSE), please keep that in mind.
|
cobalt is under [AGPL-3.0](https://github.com/wukko/cobalt/blob/current/LICENSE).
|
||||||
|
|
|
@ -10,4 +10,4 @@
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"**/node_modules/*"
|
"**/node_modules/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,4 +127,4 @@ if (fs.existsSync('./.env')) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('Required config files are missing. Please run "npm run setup" first.')
|
console.log('Required config files are missing. Please run "npm run setup" first.')
|
||||||
}
|
}
|
||||||
|
|
|
@ -496,4 +496,4 @@ input[type="checkbox"] {
|
||||||
.bottom-link {
|
.bottom-link {
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,4 +200,4 @@ eid("url-input-area").addEventListener("keyup", (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
eid("download-button").click();
|
eid("download-button").click();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -73,4 +73,4 @@
|
||||||
"Download": "download",
|
"Download": "download",
|
||||||
"CopyURL": "copy url"
|
"CopyURL": "copy url"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,4 +73,4 @@
|
||||||
"Download": "скачать",
|
"Download": "скачать",
|
||||||
"CopyURL": "скопировать ссылку"
|
"CopyURL": "скопировать ссылку"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,4 +33,4 @@ export async function getJSON(originalURL, ip, lang, format, quality) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return apiJSON(0, { t: loc(lang, 'ErrorSomethingWentWrong') });
|
return apiJSON(0, { t: loc(lang, 'ErrorSomethingWentWrong') });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,4 @@ supportedLanguages = config.supportedLanguages,
|
||||||
quality = config.quality,
|
quality = config.quality,
|
||||||
internetExplorerRedirect = config.internetExplorerRedirect,
|
internetExplorerRedirect = config.internetExplorerRedirect,
|
||||||
donations = config.donations,
|
donations = config.donations,
|
||||||
ffmpegArgs = config.ffmpegArgs
|
ffmpegArgs = config.ffmpegArgs
|
||||||
|
|
|
@ -119,4 +119,4 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return apiJSON(0, { t: genericError(lang, host) })
|
return apiJSON(0, { t: genericError(lang, host) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,4 +202,4 @@ export default function(obj) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return `${loc(obj.lang, 'ErrorPageRenderFail', obj.hash)}`;
|
return `${loc(obj.lang, 'ErrorPageRenderFail', obj.hash)}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,4 +73,4 @@
|
||||||
"patterns": ["video/:postId", ":id"],
|
"patterns": ["video/:postId", ":id"],
|
||||||
"enabled": true
|
"enabled": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,3 @@ export default async function(obj) {
|
||||||
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,4 +25,4 @@ export default async function(obj) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,4 +54,4 @@ export default async function (obj) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,4 +44,4 @@ export default async function(obj) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,4 +71,3 @@ export default async function (obj) {
|
||||||
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,4 +51,4 @@ let final = () => {
|
||||||
console.log("You can re-run this script any time to update the configuration.")
|
console.log("You can re-run this script any time to update the configuration.")
|
||||||
console.log("\nYou're now ready to start the main project.\nHave fun!")
|
console.log("\nYou're now ready to start the main project.\nHave fun!")
|
||||||
rl.close()
|
rl.close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,4 +43,4 @@ export function verifyStream(ip, id, hmac, exp, salt) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { status: 500, body: { status: "error", text: "Internal Server Error" } };
|
return { status: 500, body: { status: "error", text: "Internal Server Error" } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,4 +29,4 @@ export default function(service, quality, maxQuality) {
|
||||||
return closest(quality, s)
|
return closest(quality, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,4 +110,4 @@ export async function streamAudioOnly(streamInfo, res) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
internalError(res);
|
internalError(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,4 +8,4 @@ export function md5(string) {
|
||||||
}
|
}
|
||||||
export function UUID() {
|
export function UUID() {
|
||||||
return randomUUID();
|
return randomUUID();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,4 @@ export function getCommitInfo() {
|
||||||
let d = execSync(`git show -s --format='%s;;;%B'`).toString().trim().replace(/[\r\n]/gm, '\n').split(';;;')
|
let d = execSync(`git show -s --format='%s;;;%B'`).toString().trim().replace(/[\r\n]/gm, '\n').split(';;;')
|
||||||
d[1] = d[1].replace(d[0], '').trim().toString().replace(/[\r\n]/gm, '<br>')
|
d[1] = d[1].replace(d[0], '').trim().toString().replace(/[\r\n]/gm, '<br>')
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,4 +8,4 @@ export function errorUnsupported(lang) {
|
||||||
}
|
}
|
||||||
export function genericError(lang, host) {
|
export function genericError(lang, host) {
|
||||||
return loc(lang, 'ErrorBrokenLink', host);
|
return loc(lang, 'ErrorBrokenLink', host);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,4 @@ export default function(path) {
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,4 +56,4 @@ export function unicodeDecode(str) {
|
||||||
return str.replace(/\\u[\dA-F]{4}/gi, (unicode) => {
|
return str.replace(/\\u[\dA-F]{4}/gi, (unicode) => {
|
||||||
return String.fromCharCode(parseInt(unicode.replace(/\\u/g, ""), 16));
|
return String.fromCharCode(parseInt(unicode.replace(/\\u/g, ""), 16));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue