Skip to content

Commit a208ca1

Browse files
committed
v2.0.1: support for api keys, benchmarks!
1 parent 4cadf7c commit a208ca1

File tree

4 files changed

+119
-6
lines changed

4 files changed

+119
-6
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Planned features for cobalt-cli:
4242
- [x] Display progress bar to track download progress (when supported by cobalt).
4343
- [ ] Hability to use custom downloader program (wget, curl, got, etc);
4444
- [ ] Translations.
45+
- [X] Benchmarking.
4546

4647

4748
## Usage
@@ -59,7 +60,8 @@ usage: cobalt-cli [-h|--help] [url "<value>"] [-c|--video-codec (av1|vp9|h264)]
5960
[-m|--mode (auto|audio|mute)] [-x|--proxy]
6061
[-d|--disable-metadata] [-t|--tiktok-h265]
6162
[-T|--tiktok-full-audio] [-g|--gif] [-s|--save] [-a|--api
62-
"<value>"] [-i|--instances] [-v|--verbose]
63+
"<value>"] [-i|--instances] [-v|--verbose] [-k|--key
64+
"<value>"] [-b|--benchmark]
6365
6466
save what you want, directly from the terminal, no unwanted
6567
distractions involved. powered by cobalt's api
@@ -106,6 +108,11 @@ Arguments:
106108
https://cobalt-backend.canine.tools
107109
-i --instances Show community instances and exit. Default: false
108110
-v --verbose Enable verbose logging. Default: false
111+
-k --key API key by the instance owner. You may need to
112+
provide one to use download. Can be set with
113+
COBALT_API_KEY environment variable. Default:
114+
-b --benchmark Run a benchmark to test the download speed and
115+
integrity. Default: false
109116
```
110117

111118
### Instances

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ go 1.22
55
toolchain go1.23.1
66

77
require (
8-
github.com/jedib0t/go-pretty/v6 v6.6.0
9-
github.com/lostdusty/gobalt/v2 v2.0.3
8+
github.com/jedib0t/go-pretty/v6 v6.6.1
9+
github.com/lostdusty/gobalt/v2 v2.0.4
10+
github.com/schollz/progressbar/v3 v3.16.1
1011
github.com/sirupsen/logrus v1.9.3
1112
)
1213

1314
require (
1415
github.com/mattn/go-runewidth v0.0.16 // indirect
1516
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
1617
github.com/rivo/uniseg v0.4.7 // indirect
17-
github.com/schollz/progressbar/v3 v3.16.1 // indirect
1818
github.com/stretchr/testify v1.9.0 // indirect
1919
golang.org/x/sys v0.26.0 // indirect
2020
golang.org/x/term v0.25.0 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
33
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
44
github.com/jedib0t/go-pretty/v6 v6.6.0 h1:wmZVuAcEkZRT+Aq1xXpE8IGat4vE5WXOMmBpbQqERXw=
55
github.com/jedib0t/go-pretty/v6 v6.6.0/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
6+
github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc=
7+
github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
68
github.com/lostdusty/gobalt/v2 v2.0.3 h1:jCV/VXyz6wbK0lLQRosDsuSR7bBUPjdGhTu9OJeC3N4=
79
github.com/lostdusty/gobalt/v2 v2.0.3/go.mod h1:LiuOQrhZ81oUD8EtVIOXvdI0+iibamw0XYUeOhe8ibw=
10+
github.com/lostdusty/gobalt/v2 v2.0.4 h1:MkIPh4zuHUDo0qlqFPpxDtyK3NUEI2cIGmjlLmLXar8=
11+
github.com/lostdusty/gobalt/v2 v2.0.4/go.mod h1:LiuOQrhZ81oUD8EtVIOXvdI0+iibamw0XYUeOhe8ibw=
812
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
913
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
1014
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=

main.go

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package main
22

33
import (
4+
"bytes"
5+
"crypto/sha256"
46
"fmt"
57
"io"
68
"net/http"
@@ -9,6 +11,7 @@ import (
911
"runtime"
1012
"strconv"
1113
"strings"
14+
"time"
1215

1316
"github.com/jedib0t/go-pretty/v6/table"
1417
"github.com/lostdusty/gobalt/v2"
@@ -17,7 +20,7 @@ import (
1720
"github.com/tgoncuoglu/argparse"
1821
)
1922

20-
var version = "2.0.0-Alpha"
23+
var version = "2.0.1"
2124
var useragent = fmt.Sprintf("cobalt-cli/%v (+https://github.com/lostdusty/cobalt; go/%v; %v/%v)", version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
2225

2326
func main() {
@@ -116,6 +119,16 @@ func main() {
116119
Help: "Enable verbose logging",
117120
Default: false,
118121
})
122+
apiKey := cobaltParser.String("k", "key", &argparse.Options{
123+
Required: false,
124+
Help: "API key by the instance owner. You may need to provide one to use download. Can be set with COBALT_API_KEY environment variable",
125+
Default: gobalt.ApiKey,
126+
})
127+
flagBenchmark := cobaltParser.Flag("b", "benchmark", &argparse.Options{
128+
Required: false,
129+
Help: "Run a benchmark to test the download speed and integrity",
130+
Default: false,
131+
})
119132

120133
err := cobaltParser.Parse(os.Args)
121134
if err != nil {
@@ -144,9 +157,32 @@ func main() {
144157
return
145158
}
146159

160+
if *apiKey != "" {
161+
log.Debug("API key was provided via flag, setting it to gobalt")
162+
gobalt.ApiKey = *apiKey
163+
log.Debugf("Key from flag: %v | Key from Gobalt: %v | Key from COBALT_API_KEY: %v", *apiKey, gobalt.ApiKey, os.Getenv("COBALT_API_KEY"))
164+
}
165+
166+
gobalt.CobaltApi = *apiUrl
167+
168+
if *flagBenchmark {
169+
log.Debug("Flag to run benchmark is set, running benchmark")
170+
result, err := doBenchmark()
171+
if err != nil {
172+
log.Fatal(err)
173+
}
174+
mapBool := map[bool]string{true: "Yes!", false: "No :("}
175+
benchmarkTable := table.NewWriter()
176+
benchmarkTable.SetOutputMirror(os.Stdout)
177+
benchmarkTable.AppendHeader(table.Row{"Instance", "Time to download", "Download speed (KB/s)", "File size (KB)", "File hash matches?"})
178+
benchmarkTable.AppendRow(table.Row{result.Name, result.TimeToDownload, result.DownloadSpeed, result.FileSize, mapBool[result.HashMatches]})
179+
benchmarkTable.SetStyle(table.StyleLight)
180+
benchmarkTable.Render()
181+
return
182+
}
183+
147184
newDownload := gobalt.CreateDefaultSettings()
148185
log.Debugf("Creating new cobalt download with default options: %v", newDownload)
149-
gobalt.CobaltApi = *apiUrl
150186
newDownload.Url = *urlToDownload
151187
switch *youtubeVideoCodec {
152188
case "av1":
@@ -260,6 +296,7 @@ func fetchContent(options gobalt.Settings, save bool) error {
260296
)
261297
io.Copy(io.MultiWriter(f, bar), responseDownload.Body)
262298
f.Sync()
299+
fmt.Println()
263300
log.Info("File downloaded successfully!")
264301
}
265302

@@ -281,3 +318,68 @@ func communityInstances() {
281318
instancesTable.SetStyle(table.StyleRounded)
282319
instancesTable.Render()
283320
}
321+
322+
type Benchmark struct {
323+
Name string // Instance name
324+
TimeToDownload time.Duration // Time to download the file
325+
DownloadSpeed int // Download speed in KB/s
326+
FileSize int // File size in KB
327+
FileHash string // File hash in SHA256
328+
HashMatches bool // If the hash matches the known good hash
329+
}
330+
331+
func doBenchmark() (*Benchmark, error) {
332+
//Know good hash: a092e6e57ff79077b5b3a6db97739cd925b462662bac82236f9de4227ac84757
333+
cobaltBench := &Benchmark{
334+
Name: gobalt.CobaltApi,
335+
}
336+
337+
log.Info("Starting benchmark...")
338+
downloadBenchmark := gobalt.CreateDefaultSettings()
339+
downloadBenchmark.Url = "https://x.com/lostydust/status/1720929746987425821"
340+
downloadBenchmark.Proxy = true
341+
downloadBenchmark.VideoQuality = 1080
342+
343+
log.Debug("Running benchmark with the following options: ", downloadBenchmark)
344+
log.Debugf("API: %s | Key: %s", gobalt.CobaltApi, gobalt.ApiKey)
345+
grabUrl, err := gobalt.Run(downloadBenchmark)
346+
if err != nil {
347+
return nil, err
348+
}
349+
log.Debug("Ok, got tunnel url: ", grabUrl.URL)
350+
requestDownload, err := http.NewRequest("GET", grabUrl.URL, nil)
351+
requestDownload.Header.Set("User-Agent", useragent)
352+
if err != nil {
353+
return nil, err
354+
}
355+
fileBuffer := bytes.NewBuffer(nil)
356+
log.Debug("Starting download now...")
357+
start := time.Now()
358+
responseDownload, err := gobalt.Client.Do(requestDownload)
359+
if err != nil {
360+
return nil, err
361+
}
362+
defer responseDownload.Body.Close()
363+
if responseDownload.StatusCode != http.StatusOK {
364+
err = fmt.Errorf("got http status %v while benchmarking the file", responseDownload.Status)
365+
return nil, err
366+
}
367+
_, err = io.Copy(fileBuffer, responseDownload.Body)
368+
if err != nil {
369+
return nil, err
370+
}
371+
372+
elapsed := time.Since(start)
373+
log.Debug("Downloaded file in ", elapsed.Seconds(), " seconds")
374+
hashfile := sha256.New()
375+
hashfile.Write(fileBuffer.Bytes())
376+
cobaltBench.TimeToDownload = elapsed
377+
cobaltBench.FileSize = fileBuffer.Len() / 1024
378+
cobaltBench.DownloadSpeed = int(float64(cobaltBench.FileSize) / elapsed.Seconds())
379+
cobaltBench.FileHash = fmt.Sprintf("%x", hashfile.Sum(nil))
380+
cobaltBench.HashMatches = cobaltBench.FileHash == "a092e6e57ff79077b5b3a6db97739cd925b462662bac82236f9de4227ac84757"
381+
log.Debugf("File hash: %s", cobaltBench.FileHash)
382+
log.Debugf("Hash matches? %v", cobaltBench.FileHash == "a092e6e57ff79077b5b3a6db97739cd925b462662bac82236f9de4227ac84757")
383+
log.Info("[PASS] Benchmark finished!")
384+
return cobaltBench, nil
385+
}

0 commit comments

Comments
 (0)