Compare commits

...

2 Commits

Author SHA1 Message Date
Luther Wen Xu ccc23cead0
feat: Implement basic handler functionality
The `default` handler is currently all empty and should be setup in the
future. It's currently present as the default theme is in fact, default.

The debug template can be used to debug the content being passed into
the template as it just prints them out.
2020-12-01 15:12:30 +07:00
Luther Wen Xu 2225bc34e4
feat: Implement config parsing and start a server based on config 2020-12-01 15:12:24 +07:00
16 changed files with 181 additions and 3 deletions

2
.gitignore vendored

@ -0,0 +1,2 @@
config.json
content/

@ -0,0 +1,56 @@
package main
import (
"encoding/json"
"errors"
"os"
)
const configPath = "config.json"
type config struct {
Port int `json:"port"`
ThemeName string `json:"theme"`
}
// createDefaultConfig checks if a config file is present. If not, it creates the default config file.
// It returns true if a file is created.
func createDefaultConfig() (bool, error) {
info, err := os.Stat(configPath)
if err == nil {
if info.IsDir() {
return false, errors.New("config.json is a directory")
}
return false, nil
}
if !os.IsNotExist(err) {
return false, err
}
// Create the file.
f, err := os.Create(configPath)
if err != nil {
return false, err
}
encoder := json.NewEncoder(f)
encoder.SetIndent("", "\t")
err = encoder.Encode(config{
Port: 80,
ThemeName: "default",
})
return true, err
}
// parseConfig parses the config file into a struct
func parseConfig() (config, error) {
// Open the file.
f, err := os.Open(configPath)
if err != nil {
return config{}, err
}
defer f.Close()
// Decode it into the config struct.
var cfg config
err = json.NewDecoder(f).Decode(&cfg)
return cfg, err
}

@ -2,4 +2,7 @@ module gitea.teamortix.com/Team-Ortix/blgo
go 1.15 go 1.15
require github.com/stretchr/testify v1.6.1 require (
github.com/sirupsen/logrus v1.7.0
github.com/stretchr/testify v1.6.1
)

@ -1,10 +1,17 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,17 @@
package handler
import "net/http"
// Index is the handler that displays the index page.
func Index(w http.ResponseWriter, r *http.Request) {
CurrentTheme.ExecuteTemplate(w, "index.tmpl", nil)
}
// Handler is the mux-ing handler.
func Handler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {
Index(w, r)
return
}
Post(w, r)
}

@ -0,0 +1,27 @@
package handler
import (
"net/http"
"os"
)
// Post is the handler that renders a post.
func Post(w http.ResponseWriter, r *http.Request) {
fileName := "content" + r.URL.Path + ".md"
// Check if the post exists and is not a directory.
info, err := os.Stat(fileName)
if os.IsNotExist(err) || (info != nil && info.IsDir()) {
w.WriteHeader(http.StatusNotFound)
CurrentTheme.ExecuteTemplate(w, "404.tmpl", nil)
return
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
CurrentTheme.ExecuteTemplate(w, "500.tmpl", err)
return
}
// TODO Make it actually pass in a post.
CurrentTheme.ExecuteTemplate(w, "post.tmpl", nil)
}

@ -0,0 +1,21 @@
package handler
import "html/template"
// CurrentTheme is the set of template being used.
var CurrentTheme *template.Template
// SetTheme parses the provided theme name and sets it as the current theme.
func SetTheme(themeName string) error {
var err error
folder := "templates/" + themeName + "/"
CurrentTheme, err = template.ParseFiles(
folder+"index.tmpl", // Homepage (listing).
folder+"404.tmpl", // Post not found.
folder+"500.tmpl", // Internal error.
folder+"post.tmpl", // Page for posts.
)
return err
}

@ -1,9 +1,42 @@
package main package main
import ( import (
"fmt" "net/http"
"strconv"
"github.com/sirupsen/logrus"
"gitea.teamortix.com/Team-Ortix/blgo/handler"
) )
func main() { func main() {
fmt.Print("zoop") created, err := createDefaultConfig()
switch {
case err != nil:
logrus.Fatalf("Error while reading config file: %v", err)
case created:
logrus.Info("The default config file has been created. Please edit it and re-run the program.")
return
}
cfg, err := parseConfig()
if err != nil {
logrus.Fatalf("Error while parsing the config: %v", err)
}
logrus.Info("Parsing template theme \"", cfg.ThemeName, "\"...")
err = handler.SetTheme(cfg.ThemeName)
if err != nil {
logrus.Fatalf("Error while parsing templates: %v", err)
}
logrus.Info("Completed template parsing.")
http.HandleFunc("/", handler.Handler)
portStr := strconv.Itoa(cfg.Port)
logrus.Info("Listening on port " + portStr + "...")
err = http.ListenAndServe(":"+portStr, nil)
if err != nil {
logrus.Fatalf("error while listen and serving: %v", err)
}
} }

@ -0,0 +1,3 @@
404 Page.
Passed in: {{.}}

@ -0,0 +1,3 @@
500 Page.
Error: {{.}}

@ -0,0 +1,3 @@
Index page
Passed in: {{.}}

@ -0,0 +1,3 @@
Post Page.
Passed in: {{.}}