Serge Bazanski | 5e695e8 | 2021-03-07 14:29:40 +0000 | [diff] [blame] | 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "fmt" |
| 6 | "html/template" |
| 7 | "math/rand" |
| 8 | "net/http" |
| 9 | "net/url" |
| 10 | "strings" |
| 11 | "time" |
| 12 | |
| 13 | "github.com/golang/glog" |
| 14 | |
| 15 | "code.hackerspace.pl/hscloud/hswaw/oodviewer/templates" |
| 16 | ) |
| 17 | |
| 18 | var ( |
| 19 | tplBase = template.Must(template.New("base").Parse(string(templates.Data["base.html"]))) |
| 20 | tplTerm = template.Must(template.Must(tplBase.Clone()).Parse(string(templates.Data["term.html"]))) |
| 21 | tplTerms = template.Must(template.Must(tplBase.Clone()).Parse(string(templates.Data["terms.html"]))) |
| 22 | ) |
| 23 | |
| 24 | // handleTermsJson returns a JSON list of all terms. |
| 25 | func (a *app) handleTermsJson(w http.ResponseWriter, r *http.Request) { |
| 26 | terms, err := a.getTerms(r.Context()) |
| 27 | if err != nil { |
| 28 | glog.Errorf("getTerms: %v", err) |
| 29 | w.WriteHeader(500) |
| 30 | fmt.Fprintf(w, "internal error") |
| 31 | return |
| 32 | } |
| 33 | // Target API from old oodviewer, even if it's terrible. |
| 34 | var res [][]interface{} |
| 35 | for _, term := range terms { |
| 36 | res = append(res, []interface{}{ |
| 37 | term.Name, term.Entries, |
| 38 | }) |
| 39 | } |
| 40 | w.Header().Set("Content-Type", "application/json") |
| 41 | json.NewEncoder(w).Encode(res) |
| 42 | } |
| 43 | |
| 44 | // handleTerms renders a HTML page containing all terms. |
| 45 | func (a *app) handleTerms(w http.ResponseWriter, r *http.Request) { |
| 46 | terms, err := a.getTerms(r.Context()) |
| 47 | if err != nil { |
| 48 | glog.Errorf("getTerms: %v", err) |
| 49 | w.WriteHeader(500) |
| 50 | fmt.Fprintf(w, "internal error") |
| 51 | return |
| 52 | } |
| 53 | |
| 54 | termsData := make([]struct { |
| 55 | URL string |
| 56 | Name string |
| 57 | Count uint64 |
| 58 | }, len(terms)) |
| 59 | |
| 60 | for i, term := range terms { |
Serge Bazanski | 25c53fc | 2021-03-16 21:28:48 +0100 | [diff] [blame] | 61 | termsData[i].URL = "/term/" + url.QueryEscape(term.Name) |
Serge Bazanski | 5e695e8 | 2021-03-07 14:29:40 +0000 | [diff] [blame] | 62 | termsData[i].Name = term.Name |
| 63 | termsData[i].Count = term.Entries |
| 64 | } |
| 65 | |
| 66 | tplTerms.Execute(w, map[string]interface{}{ |
| 67 | "Terms": termsData, |
| 68 | }) |
| 69 | } |
| 70 | |
| 71 | // handleTermJson returns a JSON list of all entries contained within a term. |
| 72 | func (a *app) handleTermJson(w http.ResponseWriter, r *http.Request) { |
| 73 | parts := strings.Split(r.URL.Path, "/") |
| 74 | name := parts[len(parts)-1] |
| 75 | |
| 76 | entries, err := a.getEntries(r.Context(), name) |
| 77 | if err != nil { |
| 78 | glog.Errorf("getEntries: %v", err) |
| 79 | w.WriteHeader(500) |
| 80 | fmt.Fprintf(w, "internal error") |
| 81 | return |
| 82 | } |
| 83 | w.Header().Set("Content-Type", "application/json") |
| 84 | json.NewEncoder(w).Encode(entries) |
| 85 | } |
| 86 | |
| 87 | // handleRandomTermJson returns a JSON serialized randomly chosen entry from a |
| 88 | // given term. |
| 89 | func (a *app) handleRandomTermJson(w http.ResponseWriter, r *http.Request) { |
| 90 | parts := strings.Split(r.URL.Path, "/") |
| 91 | name := parts[len(parts)-1] |
| 92 | |
| 93 | entries, err := a.getEntries(r.Context(), name) |
| 94 | if err != nil { |
| 95 | glog.Errorf("getEntries: %v", err) |
| 96 | w.WriteHeader(500) |
| 97 | fmt.Fprintf(w, "internal error") |
| 98 | return |
| 99 | } |
| 100 | if len(entries) < 1 { |
| 101 | w.WriteHeader(404) |
| 102 | fmt.Fprintf(w, "no such entry") |
| 103 | return |
| 104 | } |
| 105 | entry := entries[rand.Intn(len(entries))] |
| 106 | w.Header().Set("Content-Type", "application/json") |
| 107 | json.NewEncoder(w).Encode(entry) |
| 108 | } |
| 109 | |
| 110 | // handleTerm renders an HTML page of all entries contained within a term. |
| 111 | func (a *app) handleTerm(w http.ResponseWriter, r *http.Request) { |
| 112 | parts := strings.Split(r.URL.Path, "/") |
| 113 | name := parts[len(parts)-1] |
| 114 | |
| 115 | entries, err := a.getEntries(r.Context(), name) |
| 116 | if err != nil { |
| 117 | glog.Errorf("getEntries: %v", err) |
| 118 | w.WriteHeader(500) |
| 119 | fmt.Fprintf(w, "internal error") |
| 120 | return |
| 121 | } |
| 122 | |
| 123 | entriesData := make([]struct { |
| 124 | Entry string |
| 125 | Author string |
| 126 | Added string |
| 127 | }, len(entries)) |
| 128 | for i, entry := range entries { |
| 129 | entriesData[i].Entry = entry.Entry |
| 130 | entriesData[i].Author = entry.Author |
| 131 | entriesData[i].Added = time.Unix(entry.Added, 0).String() |
| 132 | } |
| 133 | |
| 134 | tplTerm.Execute(w, map[string]interface{}{ |
| 135 | "Name": name, |
| 136 | "Entries": entriesData, |
| 137 | }) |
| 138 | } |