Skip to content

Commit 8df52f5

Browse files
committed
v1.0.7: don't panic, describe your error better
1 parent 6bd4964 commit 8df52f5

File tree

5 files changed

+115
-63
lines changed

5 files changed

+115
-63
lines changed

README.md

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,20 @@ Unofficial [cobalt](https://cobalt.tools) command line client made in go. cobalt
3030
|-----------------|--------------------|
3131
| Windows | [**x64**](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-windows-amd64.zip) / [x86](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-windows-386.zip) / [arm](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-windows-arm.zip) |
3232
| Linux | [**x64**](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-linux-amd64.tar.gz) / [x86](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-linux-386.tar.gz) / [arm64](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-linux-arm64.tar.gz) |
33-
| MacOS | [Intel](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-darwin-amd64.tar.gz) / [**M1, M2, M3**](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-darwin-arm64.tar.gz) |
33+
| Mac | [Intel](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-darwin-amd64.tar.gz) / [**M1, M2, M3**](https://github.com/princessmortix/cobalt/releases/latest/download/cobalt-darwin-arm64.tar.gz) |
3434

3535
You can also check the [releases page](https://github.com/princessmortix/cobalt/releases/latest) to download the latest version according to your platform.
3636

37+
Alternatively, if you have Go installed, you can use `go install github.com/lostdusty/cobalt@latest` to install to your machine.
38+
3739
## Roadmap
3840
Planned features for cobalt-cli:
3941

4042
- [x] Json output;
4143
- [ ] Time expiration for the returned url.
4244
- [ ] Option to save file to the current/custom folder, likely `-s` flag;
4345
- [ ] Display progress bar to track download progress (when supported by cobalt).
44-
- [ ] Hability to use custom downloader program (wget, curl, got, etc);
46+
- [ ] Hability to use custom downloader program (wget, curl, got, etc);
4547
- [ ] Translations.
4648

4749

@@ -50,13 +52,21 @@ cobalt-cli has two subcommands:
5052
- download: downloads something using cobalt
5153
- instances: lists all known cobalt instances
5254

55+
```
56+
Usage: cobalt <command>
57+
Commands:
58+
download - Use this command to download something.
59+
instances - Use this command to view stats about other cobalt instances.
60+
Error: No command was provided. Please specify a command.
61+
```
62+
5363
### Download
5464
```
5565
usage: cobalt download [-h|--help] [-u|--url "<value>"] [-c|--video-codec
5666
(av1|vp9|h264)] [-q|--video-quality
5767
(144|240|360|480|720|1080|1440|2160)] [-f|--audio-format
5868
(opus|ogg|wav|mp3|best)] [-p|--filename-pattern
59-
(basic|pretty|nerdy|classic)] [-a|--no-video] [-V|--vimeo-dash]
69+
(basic|pretty|nerdy|classic)] [-a|--no-video] [-T|--tiktok-h265]
6070
[-t|--full-tiktok-audio] [-v|--no-audio] [-d|--dubbed-audio]
6171
[-m|--metadata] [-g|--gif] [-j|--json] [-s|--status] [-i|--api
6272
"<value>"] [-l|--language "<value>"] [-b|--browser]
@@ -71,9 +81,10 @@ Arguments:
7181
downloads. AV1: 8K/HDR, lower support | VP9: 4K/HDR,
7282
best quality | H264: 1080p, works everywhere.
7383
Default: h264
74-
-q --video-quality Quality of the video. Default: 1080
75-
-f --audio-format Audio format/codec to be used. Using the default the
76-
audio won't be re-encoded. Default: best
84+
-q --video-quality Quality of the video, also applies only to youtube
85+
downloads. Default: 1080
86+
-f --audio-format Audio format/codec to be used. "best" doesn't
87+
re-encodes the audio. Default: best
7788
-p --filename-pattern File name pattern. Classic:
7889
youtube_yPYZpwSpKmA_1920x1080_h264.mp4 | audio:
7990
youtube_yPYZpwSpKmA_audio.mp3 // Basic: Video Title
@@ -84,32 +95,32 @@ Arguments:
8495
youtube, yPYZpwSpKmA).mp4 | audio: Audio Title -
8596
Audio Author (soundcloud, 1242868615).mp3. Default:
8697
pretty
87-
-a --no-video Extract audio only. Default: false
88-
-V --vimeo-dash Downloads Vimeo videos using dash instead of
89-
progressive. Default: false
90-
-t --full-tiktok-audio Enables download of original sound used in a tiktok
91-
video. Default: false
98+
-a --no-video Downloads only the audio, and removes the video.
99+
Default: false
100+
-T --tiktok-h265 Downloads TikTok videos using h265 codec. Default:
101+
false
102+
-t --full-tiktok-audio Download the original sound used in a tiktok video.
103+
Default: false
92104
-v --no-audio Downloads only the video, without audio, when
93105
possible. Default: false
94106
-d --dubbed-audio Downloads youtube audio dubbed, if present. Change
95107
the language using -l <ISO 639-1 format>. Default:
96108
false
97109
-m --metadata Disables file metadata. Default: false
98-
-g --gif Disables conversion of twitter gifs to a .gif file.
99-
Default: true
100-
-j --json Output to stdin as json. Default: false
101-
-s --status Will only check status of the select cobalt server,
102-
print and exit. All other options will be ignored,
103-
except -j. Default: false
104-
-i --api Change the cobalt api endpoint to be used. See
105-
others instances in https://instances.hyper.lol.
106-
Default: https://co.wuk.sh
110+
-g --gif Convert twitter gifs to .gif. Default: true
111+
-j --json Output to stdout as json
112+
-s --status Check status of the selected cobalt server, prints
113+
and exits. All other options will be ignored, except
114+
-j | --json. Default: false
115+
-i --api Change the cobalt api url used. See others instances
116+
in https://instances.hyper.lol. Default:
117+
https://api.cobalt.tools
107118
-l --language Downloads dubbed youtube audio according to the
108119
language set following the ISO 639-1 format. Only
109120
takes effect if -d was passed as an argument.
110121
Default: en
111-
-b --browser Opens the response link in default browser, if
112-
successful. Default: false
122+
-b --browser Downloads the requested media in your browser.
123+
Default: false
113124
```
114125

115126
### Instances
@@ -125,7 +136,7 @@ Arguments:
125136
```
126137

127138
## JSON Output
128-
See the documentation for the json output of cobalt-cli.
139+
Documentation for the json output of cobalt-cli.
129140
### Download
130141
All json output from the download subcommands follows this format:
131142
```json
@@ -177,7 +188,7 @@ Check out too:
177188

178189

179190
# About & Thanks
180-
- [cobalt](https://github.com/wukko/cobalt) made by [wukko](https://github.com/wukko) && [jj](https://github.com/dumbmoron), super cool people;
191+
- [cobalt](https://github.com/imputnet/cobalt) made by [wukko](https://github.com/wukko) && [jj](https://github.com/dumbmoron), cool people;
181192
- [argparse](https://github.com/akamensky/argparse), for handling args;
182193
- Icon made by [me](https://lostdusty.com.br);
183194
- You, for using my application!

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ go 1.21.6
55
require (
66
github.com/akamensky/argparse v1.4.0
77
github.com/emvi/iso-639-1 v1.1.0
8-
github.com/lostdusty/gobalt v1.0.6
8+
github.com/lostdusty/gobalt v1.0.7
99
github.com/mergestat/timediff v0.0.3
1010
)
1111

1212
require (
13-
github.com/jedib0t/go-pretty/v6 v6.5.8
13+
github.com/jedib0t/go-pretty/v6 v6.5.9
1414
github.com/mattn/go-runewidth v0.0.15 // indirect
1515
github.com/rivo/uniseg v0.4.7 // indirect
16-
golang.org/x/sys v0.19.0 // indirect
16+
golang.org/x/sys v0.21.0 // indirect
1717
)

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
55
github.com/emvi/iso-639-1 v1.1.0 h1:EhZiYVA+ysa/b7+0T2DD9hcX7E/5sh4o1KyDAIPu7VE=
66
github.com/emvi/iso-639-1 v1.1.0/go.mod h1:CSA53/Tx0xF9bk2DEA0Mr0wTdIxq7pqoVZgBOfoL5GI=
7-
github.com/jedib0t/go-pretty/v6 v6.5.8 h1:8BCzJdSvUbaDuRba4YVh+SKMGcAAKdkcF3SVFbrHAtQ=
8-
github.com/jedib0t/go-pretty/v6 v6.5.8/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
9-
github.com/lostdusty/gobalt v1.0.6 h1:vCVAlZS7dyc8x3Xdt4WmMeO9v2wriSIXwaK+binNz2U=
10-
github.com/lostdusty/gobalt v1.0.6/go.mod h1:gv+Hmbv0SC3lWpJvUvxJYRmmcuBjlmhKCIRskk0lSjY=
7+
github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU=
8+
github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
9+
github.com/lostdusty/gobalt v1.0.7 h1:8iL4eqp4NGn4lw9URYHD9DZYtIBMs2m81MWE+a9w/NM=
10+
github.com/lostdusty/gobalt v1.0.7/go.mod h1:gv+Hmbv0SC3lWpJvUvxJYRmmcuBjlmhKCIRskk0lSjY=
1111
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
1212
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
1313
github.com/mergestat/timediff v0.0.3 h1:ucCNh4/ZrTPjFZ081PccNbhx9spymCJkFxSzgVuPU+Y=
@@ -19,7 +19,7 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
1919
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
2020
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
2121
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
22-
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
23-
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
22+
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
23+
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2424
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
2525
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ func main() {
4040

4141
optionVideoQuality := doDownload.Selector("q", "video-quality", []string{"144", "240", "360", "480", "720", "1080", "1440", "2160"}, &argparse.Options{
4242
Required: false,
43-
Help: "Quality of the video",
43+
Help: "Quality of the video, also applies only to youtube downloads",
4444
Default: "1080",
4545
})
4646

4747
optionAudioFormat := doDownload.Selector("f", "audio-format", []string{"opus", "ogg", "wav", "mp3", "best"}, &argparse.Options{
4848
Required: false,
49-
Help: "Audio format/codec to be used. Using the default the audio won't be re-encoded",
49+
Help: "Audio format/codec to be used. \"best\" doesn't re-encodes the audio",
5050
Default: "best",
5151
})
5252

@@ -58,19 +58,19 @@ func main() {
5858

5959
optionAudioOnly := doDownload.Flag("a", "no-video", &argparse.Options{
6060
Required: false,
61-
Help: "Extract audio only",
61+
Help: "Downloads only the audio, and removes the video",
6262
Default: false,
6363
})
6464

65-
optionVimeoDash := doDownload.Flag("V", "vimeo-dash", &argparse.Options{
65+
optionTikTokH265 := doDownload.Flag("T", "tiktok-h265", &argparse.Options{
6666
Required: false,
67-
Help: "Downloads Vimeo videos using dash instead of progressive",
67+
Help: "Downloads TikTok videos using h265 codec",
6868
Default: false,
6969
})
7070

7171
optionFullTikTokAudio := doDownload.Flag("t", "full-tiktok-audio", &argparse.Options{
7272
Required: false,
73-
Help: "Enables download of original sound used in a tiktok video",
73+
Help: "Download the original sound used in a tiktok video",
7474
Default: false,
7575
})
7676

@@ -94,21 +94,28 @@ func main() {
9494

9595
optionConvertTwitterGif := doDownload.Flag("g", "gif", &argparse.Options{
9696
Required: false,
97-
Help: "Disables conversion of twitter gifs to a .gif file",
97+
Help: "Convert twitter gifs to .gif",
9898
Default: true,
9999
})
100100

101-
var outputJson, jsonOutput = doDownload.Flag("j", "json", &argparse.Options{Required: false, Help: "Output to stdout as json"}), getCobaltInstances.Flag("j", "json", &argparse.Options{Required: false, Help: "Output to stdout as json"})
101+
var outputJson, jsonOutput = doDownload.Flag("j", "json", &argparse.Options{
102+
Required: false,
103+
Help: "Output to stdout as json",
104+
}),
105+
getCobaltInstances.Flag("j", "json", &argparse.Options{
106+
Required: false,
107+
Help: "Output to stdout as json",
108+
})
102109

103110
commandStatus := doDownload.Flag("s", "status", &argparse.Options{
104111
Required: false,
105-
Help: "Will only check status of the select cobalt server, print and exit. All other options will be ignored, except -j",
112+
Help: "Check status of the selected cobalt server, prints and exits. All other options will be ignored, except -j | --json",
106113
Default: false,
107114
})
108115

109116
customCobaltApi := doDownload.String("i", "api", &argparse.Options{
110117
Required: false,
111-
Help: "Change the cobalt api endpoint to be used. See others instances in https://instances.hyper.lol",
118+
Help: "Change the cobalt api url used. See others instances in https://instances.hyper.lol",
112119
Default: gobalt.CobaltApi,
113120
})
114121

@@ -120,22 +127,30 @@ func main() {
120127

121128
openInBrowser := doDownload.Flag("b", "browser", &argparse.Options{
122129
Required: false,
123-
Help: "Opens the response link in default browser, if successful",
130+
Help: "Downloads the requested media in your browser",
124131
Default: false,
125132
})
126133

127134
err := flagParser.Parse(os.Args)
128135
if err != nil && errors.Is(err, flagParser.Parse(os.Args)) {
129-
panic(fmt.Errorf("expected sub-command '%v' or '%v'", doDownload.GetName(), getCobaltInstances.GetName()))
136+
fmt.Print(`Usage: cobalt <command>
137+
Commands:
138+
  download  - Use this command to download something.
139+
  instances - Use this command to view stats about other cobalt instances.
140+
Error: No command was provided. Please specify a command.
141+
`)
142+
return
130143
}
131144

132145
if getCobaltInstances.Happened() {
133146
err := getInstances(*jsonOutput)
134147
if err != nil {
135148
if *jsonOutput {
136-
panic(errorJson(err))
149+
fmt.Println(errorJson(err))
150+
return
137151
}
138-
panic(err)
152+
fmt.Println(err)
153+
return
139154
}
140155
return
141156
}
@@ -144,9 +159,11 @@ func main() {
144159
err := checkStatus(*customCobaltApi, *outputJson)
145160
if err != nil {
146161
if *jsonOutput {
147-
panic(errorJson(err))
162+
fmt.Println(errorJson(err))
163+
return
148164
}
149-
panic(err)
165+
fmt.Println(err)
166+
return
150167
}
151168
return
152169
}
@@ -159,9 +176,11 @@ func main() {
159176
validateLanguage := iso6391.ValidCode(strings.ToLower(*customLanguage))
160177
if !validateLanguage {
161178
if *outputJson {
162-
panic(fmt.Errorf("invalid language code, check if the language code is following ISO 639-1 format"))
179+
fmt.Println(fmt.Errorf("invalid language code, check if the language code is following ISO 639-1 format"))
180+
return
163181
}
164-
panic("Invalid language code: " + *customLanguage)
182+
fmt.Println("Invalid language code: " + *customLanguage)
183+
return
165184
}
166185

167186
newSettings := gobalt.CreateDefaultSettings()
@@ -208,24 +227,28 @@ func main() {
208227
newSettings.DisableVideoMetadata = *optionDisableMetadata
209228
newSettings.DubbedYoutubeAudio = *optionDubAudio
210229
newSettings.FullTikTokAudio = *optionFullTikTokAudio
211-
newSettings.UseVimeoDash = *optionVimeoDash
230+
newSettings.TikTokH265 = *optionTikTokH265
212231
newSettings.Url = *URL
213232
newSettings.VideoOnly = *optionVideoOnly
214233
quality, err := strconv.Atoi(*optionVideoQuality)
215234
if err != nil {
216235
if *outputJson {
217-
panic(fmt.Errorf("expected int on flag -q, got something else: %s", *optionVideoQuality))
236+
fmt.Println(fmt.Errorf("expected int on flag -q, got something else: %s", *optionVideoQuality))
237+
return
218238
}
219-
panic(fmt.Errorf("expected int on flag -q, got something else: %s\nError details: %e", *optionVideoQuality, err))
239+
fmt.Println(fmt.Errorf("expected int on flag -q, got something else: %s\nError details: %e", *optionVideoQuality, err))
240+
return
220241
}
221242
newSettings.VideoQuality = quality
222243

223244
cobaltRequest, err := gobalt.Run(newSettings)
224245
if err != nil {
225246
if *outputJson {
226-
panic(errorJson(err))
247+
fmt.Println(errorJson(err))
248+
return
227249
}
228-
panic(err)
250+
fmt.Println(err)
251+
return
229252
}
230253

231254
if *outputJson {
@@ -257,7 +280,7 @@ func main() {
257280
for _, urls := range cobaltRequest.URLs {
258281
err := openInDefaultBrowser(urls)
259282
if err != nil {
260-
fmt.Println("Failed to open URL on default browser:", err)
283+
fmt.Printf("Failed to open URL on default browser: %v\nWill print instead.", err)
261284
}
262285
}
263286
}
@@ -335,9 +358,9 @@ func getInstances(args bool) error {
335358

336359
instancesTable := table.NewWriter()
337360
instancesTable.SetOutputMirror(os.Stdout)
338-
instancesTable.AppendHeader(table.Row{"name", "api url (frontend)", "api online (frontend)", "cors", "since", "version (branch, commit)"})
361+
instancesTable.AppendHeader(table.Row{"name", "api url (frontend)", "API/Front online", "cors", "since", "version (branch, commit)"})
339362
for _, v := range instances {
340-
instancesTable.AppendRow(table.Row{v.Name, fmt.Sprintf("%v (front: %v)", v.URL, v.FrontendUrl), fmt.Sprintf("%v (front: %v)", v.ApiOnline, v.FrontEndOnline), v.Cors, utilHumanTime(v.StartTime), fmt.Sprintf("%v (%v, %v)", v.Version, v.Branch, v.Commit)})
363+
instancesTable.AppendRow(table.Row{v.Name, fmt.Sprintf("%v (front: %v)", v.URL, v.FrontendUrl), fmt.Sprintf("%v", resolveApiFrontOnline(v.ApiOnline, v.FrontEndOnline)), resolveCors(v.Cors), utilHumanTime(v.StartTime), fmt.Sprintf("%v (%v, %v)", v.Version, v.Branch, v.Commit)})
341364
}
342365
instancesTable.SetStyle(table.StyleRounded)
343366
instancesTable.Render()
@@ -349,3 +372,21 @@ func utilHumanTime(unixTime int64) string {
349372
since := time.UnixMilli(unixTime)
350373
return timediff.TimeDiff(since)
351374
}
375+
376+
func resolveApiFrontOnline(api, front bool) string {
377+
a, f := "no", "no"
378+
if api {
379+
a = "yes"
380+
}
381+
if front {
382+
f = "yes"
383+
}
384+
return fmt.Sprintf("%s/%s", a, f)
385+
}
386+
387+
func resolveCors(cors int) string {
388+
if cors == 1 {
389+
return "on"
390+
}
391+
return "off"
392+
}

0 commit comments

Comments
 (0)