diff --git a/.env-example b/.env-example new file mode 100644 index 0000000..5e811c0 --- /dev/null +++ b/.env-example @@ -0,0 +1 @@ +PAT="your read only pat" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/cmd/main.go b/cmd/main.go index ce5d219..846e242 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,9 +4,14 @@ import ( "github.com/labstack/echo/v4" "github.com/lorenzhohermuth/portfolio/internal/handler" "github.com/lorenzhohermuth/portfolio/internal/mdparser" + "github.com/gofor-little/env" ) func main() { + envErr := env.Load(".env") + if envErr != nil { + panic(envErr) + } app := echo.New() index := 0 diff --git a/go.mod b/go.mod index 4a68653..89cc853 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,14 @@ module github.com/lorenzhohermuth/portfolio go 1.22.1 require ( - github.com/a-h/templ v0.2.648 // indirect - github.com/labstack/echo/v4 v4.11.4 // indirect + github.com/a-h/templ v0.2.648 + github.com/labstack/echo/v4 v4.11.4 +) + +require ( + github.com/gofor-little/env v1.0.18 // indirect + github.com/google/go-github v17.0.0+incompatible // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -12,6 +18,7 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.19.0 // indirect + golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 707f5c5..59fc21f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,16 @@ github.com/a-h/templ v0.2.648 h1:A1ggHGIE7AONOHrFaDTM8SrqgqHL6fWgWCijQ21Zy9I= github.com/a-h/templ v0.2.648/go.mod h1:SA7mtYwVEajbIXFRh3vKdYm/4FYyLQAtPH1+KxzGPA8= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gofor-little/env v1.0.18 h1:k87nb3OjhiZyq2mmNbuW9Hvm/vqUszNPe1C8HPb9etM= +github.com/gofor-little/env v1.0.18/go.mod h1:2BE2i6c9e/C6EaGnfhpqzfNERUqkzJ+s/ApnRyl+588= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= @@ -9,6 +20,11 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= @@ -17,9 +33,14 @@ golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= +golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= 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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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/interactive/projects.md b/interactive/projects.md new file mode 100644 index 0000000..c57e853 --- /dev/null +++ b/interactive/projects.md @@ -0,0 +1,15 @@ +# Project 1 +![test](/static/test.jpg) +Project one + +# Project 2 +![test](/static/test.jpg) +Project two + +# Project 3 +![test](/static/test.jpg) +Project tree + +# Project 4 +![test](/static/test.jpg) +Project four diff --git a/interactive/work.md b/interactive/work.md new file mode 100644 index 0000000..e69de29 diff --git a/internal/mdparser/mdparser.go b/internal/mdparser/mdparser.go new file mode 100644 index 0000000..a219121 --- /dev/null +++ b/internal/mdparser/mdparser.go @@ -0,0 +1,74 @@ +package mdparser + +import ( + "context" + "fmt" + "os" + "regexp" + "strings" + + "github.com/lorenzhohermuth/portfolio/pkg/github" + "github.com/lorenzhohermuth/portfolio/view/component" +) + +const pathProjects string = "projects.md" +const pathWork string = "work.md" + +func GetProjects() []component.CarouselEntry { + github.FetchGHFile(context.Background(), "/cmd") + components := make([]component.CarouselEntry, 0) + + dat, err := os.ReadFile("interactive/projects.md") + if err != nil { + panic(err) + } + + lines := strings.Split(string(dat), "\n") + tmpTitle := "" + tmpText := "" + tmpImg := "" + for _, l := range lines { + isFilled, elm := parseMd(l, &tmpTitle, &tmpText, &tmpImg) + if isFilled { + components = append(components, elm) + } + } + + fmt.Println(components) + return components +} + +func getChar(text string, pos int) string { + text = strings.TrimSpace(text) + if text == "" { + return "" + } + return string([]rune(text)[pos]) +} + +func parseMd(line string, title *string, text *string, img *string) (bool, component.CarouselEntry){ + char := getChar(line, 0) + + if char == "" { + elm := component.CarouselEntry{ + ImgPath: *img, + Title: *title, + Text: *text, + } + *img = "" + *title = "" + *text = "" + return true, elm + + } else if char == "#" { + *title = strings.TrimSpace(line[1:]) + + } else if char == "!" { + rgx := regexp.MustCompile(`\((.*?)\)`) + *img = rgx.FindStringSubmatch(line)[1] + + } else { + *text += line + } + return false, component.CarouselEntry{} +} diff --git a/pkg/github/github.go b/pkg/github/github.go new file mode 100644 index 0000000..7e9456e --- /dev/null +++ b/pkg/github/github.go @@ -0,0 +1,77 @@ +package github + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/gofor-little/env" + "github.com/google/go-github/github" + "golang.org/x/oauth2" +) + +const ( + owner = "lorenzhohermuth" + repo = "portfolio" + basePath = "/" +) + +type response struct { + content *github.RepositoryContent + err error +} + +func FetchGHFile(ctx context.Context, path string) (string, error){ + ctx, cancel := context.WithTimeout(ctx, time.Millisecond * 500) + defer cancel() + + resChan := make(chan response) + + go func() { + res, err := fetchGithub(ctx, path) + resChan <- response{ + content: res, + err: err, + } + }() + + for { + select { + case <- ctx.Done(): + return "", fmt.Errorf("fetching from Github took to long") + case resp := <- resChan: + text, errRepoCont := resp.content.GetContent() + if errRepoCont != nil { + panic(errRepoCont) + } + + return text, resp.err + } + } + +} + +func fetchGithub(ctx context.Context, path string) (*github.RepositoryContent, error) { + client := github.NewClient(getAuthToken()) + fileContent, repoCont, res, err := client.Repositories.GetContents(ctx, owner, repo, path, nil) + //fmt.Printf("content : %#v\n", fileContent) + fmt.Printf("repoContent : %#v\n", repoCont) + if len(repoCont) > 0 { + fmt.Println("file : ", repoCont[0].GetName()) + } + fmt.Printf("response : %#v\n\n", res) + return fileContent, err +} + +func getAuthToken() *http.Client { + ctx := context.Background() + pat, err := env.MustGet("PAT") + if err != nil { + panic(err) + } + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: pat}, + ) + return oauth2.NewClient(ctx, ts) +}