Removed S3
This commit is contained in:
parent
c0923aaf2b
commit
2edff6915a
15 changed files with 51 additions and 203 deletions
|
@ -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!
|
||||
|
||||
# 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!
|
||||
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
10
go.mod
|
@ -12,9 +12,9 @@ require (
|
|||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/image v0.19.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/text v0.17.0 // indirect
|
||||
golang.org/x/image v0.20.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/time v0.6.0 // 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/yuin/goldmark v1.7.4
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
|
10
go.sum
10
go.sum
|
@ -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=
|
||||
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.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.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
|
||||
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/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.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/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.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.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/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
33
lib/files.go
Normal file
33
lib/files.go
Normal 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
125
lib/s3.go
|
@ -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: ®ion,
|
||||
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: ®ion,
|
||||
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
|
||||
}
|
1
main.go
1
main.go
|
@ -44,7 +44,6 @@ func main() {
|
|||
e.GET("/", pages.Home)
|
||||
e.GET("/projects", pages.Projects)
|
||||
e.GET("/talks", pages.Talks)
|
||||
e.GET("/testimonials", pages.Testimonials)
|
||||
e.GET("/posts", pages.Posts)
|
||||
e.GET("/posts/:post", pages.Post)
|
||||
e.GET("/tools", pages.Tools)
|
||||
|
|
|
@ -100,14 +100,9 @@ func Home(c echo.Context) error {
|
|||
buttons := []lib.ButtonLink{
|
||||
{
|
||||
Name: "Resumé",
|
||||
Href: lib.GeneratePublicURL("Atridad_Lahiji_Resume.pdf"),
|
||||
Href: "/public/files/Atridad_Lahiji_Resume.pdf",
|
||||
Internal: false,
|
||||
},
|
||||
{
|
||||
Name: "Testimonials",
|
||||
Href: "/testimonials",
|
||||
Internal: true,
|
||||
},
|
||||
{
|
||||
Name: "Posts",
|
||||
Href: "/posts",
|
||||
|
|
|
@ -21,7 +21,7 @@ func Talks(c echo.Context) error {
|
|||
{
|
||||
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",
|
||||
Href: lib.GeneratePublicURL("hypermedia_talk_atridad.pdf"),
|
||||
Href: "/public/files/hypermedia_talk_atridad.pdf",
|
||||
Tags: []string{"golang", "htmx", "ssr"},
|
||||
Date: "February 01, 2024",
|
||||
},
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
Talks
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="no-underline" href="/testimonials">
|
||||
Testimonials
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="no-underline" href="/tools">
|
||||
Tools
|
||||
|
|
|
@ -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}}
|
|
@ -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)
|
||||
}
|
|
@ -21,7 +21,7 @@ func Resize(c echo.Context) error {
|
|||
{
|
||||
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",
|
||||
Href: lib.GeneratePublicURL("hypermedia_talk_atridad.pdf"),
|
||||
// Href: lib.GeneratePublicURL("hypermedia_talk_atridad.pdf"),
|
||||
Tags: []string{"golang", "htmx", "ssr"},
|
||||
Date: "February 01, 2024",
|
||||
},
|
||||
|
|
BIN
public/files/Atridad_Lahiji_Resume.pdf
Normal file
BIN
public/files/Atridad_Lahiji_Resume.pdf
Normal file
Binary file not shown.
BIN
public/files/hypermedia_talk_atridad.pdf
Normal file
BIN
public/files/hypermedia_talk_atridad.pdf
Normal file
Binary file not shown.
BIN
public/img/articles/scalability.png
Normal file
BIN
public/img/articles/scalability.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
Loading…
Add table
Reference in a new issue