aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go171
1 files changed, 171 insertions, 0 deletions
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,
+ "<meta name=\"go-import\" content=\"code.laria.me/%s %s\">",
+ 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
+}