From 287d80ce8694340b52ac39babd65f2e2a59b21b6 Mon Sep 17 00:00:00 2001 From: Ron Rise Date: Fri, 12 Jul 2024 20:59:54 -0400 Subject: [PATCH] Add browser --- aws/client.go | 35 +++++++++++++ aws/s3.go | 48 +++++++++++++++++ go.mod | 18 ++++--- go.sum | 37 +++++--------- main.go | 113 +++++++++++++++++++++++++++++++++-------- templates/index.gohtml | 31 +++++++++++ 6 files changed, 232 insertions(+), 50 deletions(-) create mode 100644 aws/client.go create mode 100644 aws/s3.go create mode 100644 templates/index.gohtml diff --git a/aws/client.go b/aws/client.go new file mode 100644 index 0000000..b5160f2 --- /dev/null +++ b/aws/client.go @@ -0,0 +1,35 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3" +) + +type Config struct { + AwsKey string + AwsSecret string + AwsRole string + Bucket string +} + +type Service struct { + s3 *s3.S3 + bucket string +} + +func NewClient(config *Config) *Service { + awsSession := session.Must(session.NewSession(&aws.Config{ + Credentials: credentials.NewStaticCredentials(config.AwsKey, config.AwsSecret, ""), + Region: aws.String("us-east-1"), + })) + + assumeRoleCredentials := stscreds.NewCredentials(awsSession, config.AwsRole) + + return &Service{ + s3: s3.New(awsSession, &aws.Config{Credentials: assumeRoleCredentials}), + bucket: config.Bucket, + } +} diff --git a/aws/s3.go b/aws/s3.go new file mode 100644 index 0000000..b6f18a4 --- /dev/null +++ b/aws/s3.go @@ -0,0 +1,48 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" +) + +type Image struct { + Url string + Download string + Name string + S3Path string +} + +type BucketList struct { + Images []Image + StartAfter string +} + +func (s *Service) ListBucketContents(continuationToken *string) (*BucketList, error) { + v2, err := s.s3.ListObjectsV2(&s3.ListObjectsV2Input{ + Bucket: aws.String(s.bucket), + MaxKeys: aws.Int64(20), + ContinuationToken: continuationToken, + }) + + if err != nil { + return nil, err + } + + bucketList := BucketList{ + Images: make([]Image, 0), + } + + if v2.NextContinuationToken != nil { + bucketList.StartAfter = *v2.NextContinuationToken + } + + for _, item := range v2.Contents { + image := Image{ + Name: *item.Key, + S3Path: "s3://" + s.bucket + "/" + *item.Key, + } + bucketList.Images = append(bucketList.Images, image) + } + + return &bucketList, nil +} diff --git a/go.mod b/go.mod index 257c167..8dc8c57 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,25 @@ module github.com/siteworxpro/img-proxy-url-generator -go 1.22.2 +go 1.22.5 -require github.com/bigkevmcd/go-configparser v0.0.0-20230427073640-c6b631f70126 +require ( + github.com/aws/aws-sdk-go v1.54.19 + github.com/bigkevmcd/go-configparser v0.0.0-20240624060122-ccd05f93a9d2 + github.com/charmbracelet/lipgloss v0.12.1 + github.com/urfave/cli/v2 v2.27.2 +) require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/lipgloss v0.10.0 // indirect + github.com/charmbracelet/x/ansi v0.1.4 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/urfave/cli/v2 v2.27.2 // indirect - github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect - golang.org/x/sys v0.20.0 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + golang.org/x/sys v0.22.0 // indirect ) diff --git a/go.sum b/go.sum index 3e7bc30..11a73a2 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,19 @@ -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= -github.com/aws/aws-sdk-go v1.49.16 h1:KAQwhLg296hfffRdh+itA9p7Nx/3cXS/qOa3uF9ssig= -github.com/aws/aws-sdk-go v1.49.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.54.18 h1:t8DGtN8A2wEiazoJxeDbfPsbxCKtjoRLuO7jBSgJzo4= +github.com/aws/aws-sdk-go v1.54.18/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.54.19 h1:tyWV+07jagrNiCcGRzRhdtVjQs7Vy41NwsuOcl0IbVI= +github.com/aws/aws-sdk-go v1.54.19/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/bigkevmcd/go-configparser v0.0.0-20230427073640-c6b631f70126 h1:uru++pUKoS/yYU3Ohq9VItZdK/cT7FFJH/UUjOlxc+s= github.com/bigkevmcd/go-configparser v0.0.0-20230427073640-c6b631f70126/go.mod h1:zqqfbfnDeSdRs1WihmMjSbhb2Ptw8Jbus831xoqiIec= +github.com/bigkevmcd/go-configparser v0.0.0-20240624060122-ccd05f93a9d2 h1:2qnRmzKO1fVs2UOqyt6tRMpVB8FrOnx8IG8C2lK0cjU= +github.com/bigkevmcd/go-configparser v0.0.0-20240624060122-ccd05f93a9d2/go.mod h1:vzEQfW+A1T+AMJmTIX+SXNLNECHOM7GEinHhw0IjykI= github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= +github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= +github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= +github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= 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/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= @@ -26,8 +28,6 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= @@ -45,29 +45,20 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= -github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= 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-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= 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= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 44179f4..40efa64 100644 --- a/main.go +++ b/main.go @@ -3,9 +3,13 @@ package main import ( "fmt" "github.com/bigkevmcd/go-configparser" + "github.com/siteworxpro/img-proxy-url-generator/aws" "github.com/siteworxpro/img-proxy-url-generator/generator" "github.com/siteworxpro/img-proxy-url-generator/printer" "github.com/urfave/cli/v2" + "html/template" + "log" + "net/http" "os" ) @@ -15,23 +19,19 @@ var imgGenerator *generator.Generator var Version = "v0.0.0" +var awsConfig aws.Config + func main() { pr := printer.NewPrinter() - app := &cli.App{ - Name: "img-proxy-url-generator", - Usage: "URL Generator for the img proxy service", - DefaultCommand: "generate", - Version: Version, - Commands: []*cli.Command{ - { - Name: "generate", - Usage: "Generate an image from a URL", - Action: func(c *cli.Context) error { - return run(c, pr) - }, - }, + var commands []*cli.Command + + commands = append(commands, &cli.Command{ + Name: "generate", + Usage: "Generate an image from a URL", + Action: func(c *cli.Context) error { + return run(c, pr) }, Flags: []cli.Flag{ &cli.StringFlag{ @@ -39,12 +39,6 @@ func main() { Aliases: []string{"i"}, Required: true, }, - &cli.StringFlag{ - Name: "config", - Aliases: []string{"c"}, - Usage: "Config file to load from", - DefaultText: "imgproxy.cfg", - }, &cli.StringFlag{ Name: "format", Aliases: []string{"f"}, @@ -56,12 +50,39 @@ func main() { Usage: "Processing options to be passed to the generator ref: https://docs.imgproxy.net/usage/processing", }, }, + }) + + _, err := os.Stat("./templates") + if !os.IsNotExist(err) { + commands = append(commands, &cli.Command{ + Name: "server", + Usage: "Start a webserver for s3 file browsing", + Action: func(c *cli.Context) error { + return startServer(c, pr) + }, + }) + } + + app := &cli.App{ + Name: "img-proxy-url-generator", + Usage: "URL Generator for the img proxy service", + DefaultCommand: "generate", + Version: Version, + Commands: commands, Action: func(c *cli.Context) error { return run(c, pr) }, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "config", + Aliases: []string{"c"}, + Usage: "Config file to load from", + DefaultText: "imgproxy.cfg", + }, + }, } - err := app.Run(os.Args) + err = app.Run(os.Args) if err != nil { pr.LogError(err.Error()) @@ -69,6 +90,51 @@ func main() { } } +func startServer(c *cli.Context, p *printer.Printer) error { + err := initGenerator(c.String("config")) + if err != nil { + return err + } + + awsClient := aws.NewClient(&awsConfig) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + contToken := r.URL.Query().Get("next") + + var next *string + if contToken == "" { + next = nil + } else { + next = &contToken + } + + contents, err := awsClient.ListBucketContents(next) + if err != nil { + return + } + + for i, content := range contents.Images { + contents.Images[i].Url, _ = signURL("s3://"+awsConfig.Bucket+"/"+content.Name, []string{"pr:sq"}, "") + contents.Images[i].Download, _ = signURL("s3://"+awsConfig.Bucket+"/"+content.Name, []string{""}, "") + } + + file, _ := os.ReadFile("./templates/index.gohtml") + + tmpl := template.Must(template.New("index").Parse(string(file))) + + err = tmpl.Execute(w, contents) + + if err != nil { + println(err.Error()) + } + }) + + p.LogSuccess("Starting http server on port 8080. http://localhost:8080") + log.Fatal(http.ListenAndServe(":8080", nil)) + + return nil +} + func run(c *cli.Context, p *printer.Printer) error { err := initGenerator(c.String("config")) @@ -135,6 +201,13 @@ func initGenerator(config string) error { return err } + if p.HasSection("aws") { + awsConfig.AwsSecret, _ = p.Get("aws", "secret") + awsConfig.AwsKey, _ = p.Get("aws", "key") + awsConfig.AwsRole, _ = p.Get("aws", "role") + awsConfig.Bucket, _ = p.Get("aws", "bucket") + } + return nil } diff --git a/templates/index.gohtml b/templates/index.gohtml new file mode 100644 index 0000000..fde1439 --- /dev/null +++ b/templates/index.gohtml @@ -0,0 +1,31 @@ + + + + + + + + +
+ {{ range .Images }} +
+
+ + {{ .Name }} + +
+
+ {{ .S3Path }} +
+
+ {{ end }} +
+
+ Next +
+ + \ No newline at end of file