11package main
22
33import (
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 "
2124var useragent = fmt .Sprintf ("cobalt-cli/%v (+https://github.com/lostdusty/cobalt; go/%v; %v/%v)" , version , runtime .Version (), runtime .GOOS , runtime .GOARCH )
2225
2326func 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