Removed S3

This commit is contained in:
Atridad Lahiji 2024-09-08 23:42:36 -06:00
parent c0923aaf2b
commit 2edff6915a
Signed by: atridad
SSH key fingerprint: SHA256:LGomp8Opq0jz+7kbwNcdfTcuaLRb5Nh0k5AchDDb438
15 changed files with 51 additions and 203 deletions

View file

@ -71,8 +71,5 @@ So, up to this point, you may have been thinking: "Gee Atri... you can't do anyt
With Go managing route handlers and API routes, the template language running the UI, and HTMX governing interactivity on the front end, you can effectively write a fully dynamic full-stack application without writing a line of JavaScript code. It even runs quite a bit faster than some of the JS world's frameworks (Astro, for instance). It is actually what powers this site right now! The fundamentals are essential here and come together for a clean and enjoyable developer experience. I encourage everyone in the JS world to give it a shot! Perhaps it is not your thing, and that's okay! But you might also just fall in love with it! With Go managing route handlers and API routes, the template language running the UI, and HTMX governing interactivity on the front end, you can effectively write a fully dynamic full-stack application without writing a line of JavaScript code. It even runs quite a bit faster than some of the JS world's frameworks (Astro, for instance). It is actually what powers this site right now! The fundamentals are essential here and come together for a clean and enjoyable developer experience. I encourage everyone in the JS world to give it a shot! Perhaps it is not your thing, and that's okay! But you might also just fall in love with it!
# Giving It A Shot
I have a [repository](https://github.com/atridadl/goth.stack) as well as a [demo](https://goth-stack.fly.dev/) ready to go with everything you need to start!
# Thanks! # Thanks!
If you found this helpful, please let me know by email at [me@atri.dad](mailto:me@atri.dad). Until next time! If you found this helpful, please let me know by email at [me@atri.dad](mailto:me@atri.dad). Until next time!

10
go.mod
View file

@ -12,9 +12,9 @@ require (
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/image v0.19.0 // indirect golang.org/x/image v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect golang.org/x/net v0.29.0 // indirect
golang.org/x/text v0.17.0 // indirect golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect golang.org/x/time v0.6.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
) )
@ -30,7 +30,7 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/yuin/goldmark v1.7.4 github.com/yuin/goldmark v1.7.4
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
golang.org/x/crypto v0.26.0 // indirect golang.org/x/crypto v0.27.0 // indirect
golang.org/x/sys v0.24.0 // indirect golang.org/x/sys v0.25.0 // indirect
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )

10
go.sum
View file

@ -63,18 +63,28 @@ github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

33
lib/files.go Normal file
View file

@ -0,0 +1,33 @@
package lib
import (
"os"
"path/filepath"
)
// ListFiles returns a slice of file paths in the given directory
func ListFiles(dir string) ([]string, error) {
var filePaths []string
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
for _, entry := range entries {
if entry.IsDir() {
// Recursively list files in subdirectories
subDir := filepath.Join(dir, entry.Name())
subFiles, err := ListFiles(subDir)
if err != nil {
return nil, err
}
filePaths = append(filePaths, subFiles...)
} else {
// Add file path to the slice
filePath := filepath.Join(dir, entry.Name())
filePaths = append(filePaths, filePath)
}
}
return filePaths, nil
}

125
lib/s3.go
View file

@ -1,125 +0,0 @@
package lib
import (
"fmt"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
// Generates a presigned URL for the given key. Returns the pre-signed URL.
func GeneratePublicURL(key string) string {
// Get the S3 bucket name
bucket := os.Getenv("BUCKET_NAME")
if bucket == "" {
fmt.Println("No S3 bucket specified.")
return ""
}
// Create the S3 session
endpoint := os.Getenv("AWS_ENDPOINT_URL_S3")
accessKeyID := os.Getenv("AWS_ACCESS_KEY_ID")
secretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
region := os.Getenv("AWS_REGION")
sess, err := session.NewSession(&aws.Config{
Region: &region,
Credentials: credentials.NewStaticCredentials(
accessKeyID,
secretAccessKey,
"",
),
Endpoint: aws.String(endpoint),
})
if err != nil {
return ""
}
svc := s3.New(sess)
// Generate the presigned URL
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: &bucket,
Key: &key,
})
urlStr, err := req.Presign(15 * time.Minute)
if err != nil {
return ""
}
return urlStr
}
// Generates a list of presigned URLs for all items in the given directory. Returns an array of pre-signed URLs.
func GeneratePublicURLsFromDirectory(directory string) []string {
// Get the S3 bucket name
bucket := os.Getenv("BUCKET_NAME")
if bucket == "" {
fmt.Println("No S3 bucket specified.")
return []string{}
}
// Create the S3 session
endpoint := os.Getenv("AWS_ENDPOINT_URL_S3")
accessKeyID := os.Getenv("AWS_ACCESS_KEY_ID")
secretAccessKey := os.Getenv("AWS_SECRET_ACCESS_KEY")
region := os.Getenv("AWS_REGION")
sess, err := session.NewSession(&aws.Config{
Region: &region,
Credentials: credentials.NewStaticCredentials(
accessKeyID,
secretAccessKey,
"",
),
Endpoint: aws.String(endpoint),
})
if err != nil {
return []string{}
}
svc := s3.New(sess)
// Create the input for the ListObjectsV2 call
input := &s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
Prefix: aws.String(directory),
}
// Get the list of items in the directory
result, err := svc.ListObjectsV2(input)
if err != nil {
return []string{}
}
//Remove the items in results that are directories
for i := 0; i < len(result.Contents); i++ {
if *result.Contents[i].Key == directory {
result.Contents = append(result.Contents[:i], result.Contents[i+1:]...)
i--
}
}
// Generate the presigned URLs
urls := []string{}
for _, item := range result.Contents {
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: item.Key,
})
urlStr, err := req.Presign(15 * time.Minute)
if err != nil {
continue
}
urls = append(urls, urlStr)
}
return urls
}

View file

@ -44,7 +44,6 @@ func main() {
e.GET("/", pages.Home) e.GET("/", pages.Home)
e.GET("/projects", pages.Projects) e.GET("/projects", pages.Projects)
e.GET("/talks", pages.Talks) e.GET("/talks", pages.Talks)
e.GET("/testimonials", pages.Testimonials)
e.GET("/posts", pages.Posts) e.GET("/posts", pages.Posts)
e.GET("/posts/:post", pages.Post) e.GET("/posts/:post", pages.Post)
e.GET("/tools", pages.Tools) e.GET("/tools", pages.Tools)

View file

@ -100,14 +100,9 @@ func Home(c echo.Context) error {
buttons := []lib.ButtonLink{ buttons := []lib.ButtonLink{
{ {
Name: "Resumé", Name: "Resumé",
Href: lib.GeneratePublicURL("Atridad_Lahiji_Resume.pdf"), Href: "/public/files/Atridad_Lahiji_Resume.pdf",
Internal: false, Internal: false,
}, },
{
Name: "Testimonials",
Href: "/testimonials",
Internal: true,
},
{ {
Name: "Posts", Name: "Posts",
Href: "/posts", Href: "/posts",

View file

@ -21,7 +21,7 @@ func Talks(c echo.Context) error {
{ {
Name: "Hypermedia as the engine of application state - an Introduction", Name: "Hypermedia as the engine of application state - an Introduction",
Description: "A talk on building reactive websites using tools like HTMX instead of JSON + JS. Will be presented at the Dev Edmonton Fabruary 2024 JS/Ruby/Python Meetup", Description: "A talk on building reactive websites using tools like HTMX instead of JSON + JS. Will be presented at the Dev Edmonton Fabruary 2024 JS/Ruby/Python Meetup",
Href: lib.GeneratePublicURL("hypermedia_talk_atridad.pdf"), Href: "/public/files/hypermedia_talk_atridad.pdf",
Tags: []string{"golang", "htmx", "ssr"}, Tags: []string{"golang", "htmx", "ssr"},
Date: "February 01, 2024", Date: "February 01, 2024",
}, },

View file

@ -14,11 +14,6 @@
Talks Talks
</a> </a>
</li> </li>
<li>
<a class="no-underline" href="/testimonials">
Testimonials
</a>
</li>
<li> <li>
<a class="no-underline" href="/tools"> <a class="no-underline" href="/tools">
Tools Tools

View file

@ -1,32 +0,0 @@
{{define "title"}}
Atridad Lahiji // Testimonials
{{end}}
{{define "headercontent"}}
Atridad Lahiji // Testimonials
{{end}}
{{define "head"}}
<link rel="stylesheet" href="/public/css/styles.css" />
{{end}}
{{define "main"}}
<h2 class="text-2xl font-extrabold tracking-tight text-white sm:text-[2rem]">
What <a class="link link-secondary"
href="https://steamcommunity.com/app/1230140/reviews/?browsefilter=toprated&snr=1_5_100010_" target="_blank"
rel="noreferrer">People</a> Say About Me
</h2>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
{{range .Images}}
<div>
<img class="object-cover object-center w-full max-w-full rounded-lg" src={{.}} alt="Review of Atri"
loading="lazy" />
</div>
{{end}}
</div>
{{end}}
{{define "foot"}}
{{end}}

View file

@ -1,24 +0,0 @@
package pages
import (
"atri.dad/lib"
"github.com/labstack/echo/v4"
)
type TestimonialsProps struct {
Images []string
}
func Testimonials(c echo.Context) error {
images := lib.GeneratePublicURLsFromDirectory("testimonials/")
props := TestimonialsProps{
Images: images,
}
// Specify the partials used by this page
partials := []string{"header", "navitems"}
// Render the template
return lib.RenderTemplate(c.Response().Writer, "base", partials, props)
}

View file

@ -21,7 +21,7 @@ func Resize(c echo.Context) error {
{ {
Name: "Hypermedia as the engine of application state - an Introduction", Name: "Hypermedia as the engine of application state - an Introduction",
Description: "A talk on building reactive websites using tools like HTMX instead of JSON + JS. Will be presented at the Dev Edmonton Fabruary 2024 JS/Ruby/Python Meetup", Description: "A talk on building reactive websites using tools like HTMX instead of JSON + JS. Will be presented at the Dev Edmonton Fabruary 2024 JS/Ruby/Python Meetup",
Href: lib.GeneratePublicURL("hypermedia_talk_atridad.pdf"), // Href: lib.GeneratePublicURL("hypermedia_talk_atridad.pdf"),
Tags: []string{"golang", "htmx", "ssr"}, Tags: []string{"golang", "htmx", "ssr"},
Date: "February 01, 2024", Date: "February 01, 2024",
}, },

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB