From 369d2c3e395903f6aff1d1869a81290d8bc994fa Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Sat, 14 Oct 2017 16:04:26 +0200 Subject: Initial commit --- main.go | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 main.go (limited to 'main.go') diff --git a/main.go b/main.go new file mode 100644 index 0000000..70ccac4 --- /dev/null +++ b/main.go @@ -0,0 +1,171 @@ +package main + +import ( + "code.laria.me/code.laria.me/projects" + "flag" + "fmt" + "html/template" + "log" + "net/http" + "path" + "strings" +) + +var ( + HttpLaddr = flag.String("http_laddr", ":8093", "Serve HTTP from this address") + DataDir = flag.String("data_dir", "/usr/lib/code.laria.me", "Data directory (static files/templates)") + ProjectDir = flag.String("project_dir", "/srv/code.laria.me", "Project directory") +) + +func main() { + flag.Parse() + + repo := projects.NewProjectRepo(*ProjectDir) + repo.ScanProjects() + + templates := NewTemplates(path.Join(*DataDir, "templates")) + if err := templates.LoadAll(); err != nil { + log.Fatalln(err) + } + + http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) { + if req.URL.Query().Get("go-get") == "1" { + for _, p := range repo.Projects { + if p.GoGet != "" { + fmt.Fprintf( + resp, + "", + p.Name, + p.GoGet, + ) + } + } + + return + } + + if req.URL.Path == "/" { + var data mainTemplateData + data.Projects = repo.Projects + data.Tagcloud = repo.Tagcloud + data.Tags = []string{"programming", "code", "git", "source", "sourcecode"} + + templates.Main.Execute(resp, data) + return + } + + proj, ok := repo.Projects[req.URL.Path[1:]] + if ok { + templates.Project.Execute(resp, proj) + return + } + + resp.WriteHeader(404) + templates.Notfound.Execute(resp, commonTemplateData{}) + }) + http.Handle("/tags/", http.StripPrefix("/tags/", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + tag := req.URL.String() + projs, ok := repo.Tags[tag] + if !ok { + resp.WriteHeader(404) + templates.Notfound.Execute(resp, commonTemplateData{}) + return + } + + var data tagTemplateData + + data.Tags = []string{tag} + data.Title = tag + data.Tag = tag + data.Projects = make(map[string]projects.Project) + + for pname := range projs { + p, ok := repo.Projects[pname] + if ok { + data.Projects[pname] = p + } + } + + templates.Tag.Execute(resp, data) + }))) + http.HandleFunc("/__refresh__", func(resp http.ResponseWriter, req *http.Request) { + // Should be shielded from the internet, e.g. by putting this into the nginx config: + // location /__refresh__ { return 403; } + + resp.Header().Add("Content-Type", "text/plain") + + if err := templates.LoadAll(); err != nil { + fmt.Fprintf(resp, "Failed loading templates: %s", err) + + log.Panicln(err) + } + repo.ScanProjects() + resp.Write([]byte("OK")) + }) + http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(path.Join(*DataDir, "static"))))) + + log.Fatalln(http.ListenAndServe(*HttpLaddr, nil)) +} + +type Templates struct { + Main, Project, Tag, Notfound *template.Template + dir string +} + +func NewTemplates(dir string) *Templates { + return &Templates{ + dir: dir, + } +} + +func (t *Templates) LoadAll() error { + var err error + if err = t.loadMain(); err != nil { + return err + } + if t.Project, err = t.loadSub("project"); err != nil { + return err + } + if t.Tag, err = t.loadSub("tag"); err != nil { + return err + } + if t.Notfound, err = t.loadSub("notfound"); err != nil { + return err + } + return nil +} + +func (t *Templates) loadMain() (err error) { + t.Main, err = template.New("main.html").Funcs(template.FuncMap{ + "join": strings.Join, + }).ParseFiles(path.Join(t.dir, "main.html")) + if err != nil { + return err + } + t.Main.Funcs(template.FuncMap{ + "join": strings.Join, + }) + + return nil +} + +func (t *Templates) loadSub(name string) (*template.Template, error) { + return template.Must(t.Main.Clone()).ParseFiles(path.Join(t.dir, name+".html")) +} + +type commonTemplateData struct { + Title, Description string + Tags []string +} + +type mainTemplateData struct { + commonTemplateData + Projects map[string]projects.Project + Tagcloud map[string]projects.TagcloudElem +} + +type tagTemplateData struct { + commonTemplateData + Tag string + Projects map[string]projects.Project +} -- cgit v1.2.3-54-g00ecf