diff options
author | Benjamin Chausse <benjamin@chausse.xyz> | 2024-06-05 23:15:25 -0400 |
---|---|---|
committer | Benjamin Chausse <benjamin@chausse.xyz> | 2024-06-05 23:15:25 -0400 |
commit | 0a74bc555320401f99f91f651b0cf6c25957e7ea (patch) | |
tree | 9fd043fa63a212cc384cd631359e52df42c46cce |
Initial commit
-rw-r--r-- | .gitignore | 37 | ||||
-rw-r--r-- | go.mod | 15 | ||||
-rw-r--r-- | go.sum | 12 | ||||
-rw-r--r-- | sixkcd.go | 123 |
4 files changed, 187 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..936ee9e --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +sixkcd + +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ @@ -0,0 +1,15 @@ +module github.com/ChausseBenjamin/sixkcd + +go 1.22.3 + +require ( + github.com/mattn/go-sixel v0.0.5 + github.com/urfave/cli/v2 v2.27.2 +) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/soniakeys/quant v1.0.0 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect +) @@ -0,0 +1,12 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/mattn/go-sixel v0.0.5 h1:55w2FR5ncuhKhXrM5ly1eiqMQfZsnAHIpYNGZX03Cv8= +github.com/mattn/go-sixel v0.0.5/go.mod h1:h2Sss+DiUEHy0pUqcIB6PFXo5Cy8sTQEFr3a9/5ZLNw= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/soniakeys/quant v1.0.0 h1:N1um9ktjbkZVcywBVAAYpZYSHxEfJGzshHCxx/DaI0Y= +github.com/soniakeys/quant v1.0.0/go.mod h1:HI1k023QuVbD4H8i9YdfZP2munIHU4QpjsImz6Y6zds= +github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= +github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= diff --git a/sixkcd.go b/sixkcd.go new file mode 100644 index 0000000..efb65a7 --- /dev/null +++ b/sixkcd.go @@ -0,0 +1,123 @@ +package main + +import ( + "encoding/json" + "fmt" + "image" + _ "image/png" + _ "image/jpeg" + "io" + "log" + "math/rand" + "net/http" + "os" + "strconv" + + "github.com/mattn/go-sixel" + "github.com/urfave/cli/v2" +) + +const ( + hostname = "https://xkcd.com" + target = "info.0.json" +) + +type Xkcd struct { + Month string + Num int + Link string + Year string + News string + Safe_title string + Transcript string + Alt string + Img string + Title string + Day string +} + +func main() { + app := &cli.App{ + Name: "siXKCD", + Usage: "Sixel viewer/fetcher for XKCD Comics", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "id", + Aliases: []string{"i"}, + Usage: "Specify which comic `ID` to fetch.\nA value of 0 will fetch the latest comic (default: random)", + }, + }, + Action: func(ctx *cli.Context) error { + comic := fetchComic("latest") + switch ctx.String("id") { + case "0": + // Latest is already fetched + break + case "": + // Random + rand := rand.Intn(comic.Num+1) + comic = fetchComic(strconv.Itoa(rand)) + default: + comic = fetchComic(ctx.String("id")) + } + var img image.Image = fetchImg(comic.Img) + + fmt.Println("Title: ", comic.Title) + encoder := sixel.NewEncoder(os.Stdout) + _ = encoder.Encode(img) + if comic.Alt != "" { + fmt.Println(comic.Alt) + } + + + return nil + }, + } + + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +} + +func fetchComic(id string) Xkcd { + var res *http.Response + + var err error + + if id == "latest" { + res, err = http.Get(hostname+"/"+target) + } else { + res, err = http.Get(hostname+"/"+id+"/"+target) + } + + if err != nil { + log.Fatal(err) + } + + content, err := io.ReadAll(res.Body) + res.Body.Close() + if err != nil { + log.Fatal(err) + } + today := Xkcd{} + err = json.Unmarshal(content, &today) + if err != nil { + log.Fatal(err) + } + + return today +} + +func fetchImg(url string) image.Image { + res, err := http.Get(url) + if err != nil { + log.Fatal(err) + } + img, _, err := image.Decode(res.Body) + if err != nil { + log.Fatal(err) + } + res.Body.Close() + + return img +} |