summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Chausse <benjamin@chausse.xyz>2024-06-05 23:15:25 -0400
committerBenjamin Chausse <benjamin@chausse.xyz>2024-06-05 23:15:25 -0400
commit0a74bc555320401f99f91f651b0cf6c25957e7ea (patch)
tree9fd043fa63a212cc384cd631359e52df42c46cce
Initial commit
-rw-r--r--.gitignore37
-rw-r--r--go.mod15
-rw-r--r--go.sum12
-rw-r--r--sixkcd.go123
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/
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..ab9c2da
--- /dev/null
+++ b/go.mod
@@ -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
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..9f2957b
--- /dev/null
+++ b/go.sum
@@ -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
+}