summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRose Hogenson <rhogenson@google.com>2026-07-23 16:07:38 -0700
committerRose Hogenson <rhogenson@google.com>2026-07-23 16:07:38 -0700
commit50e829808d7c61e04ed35af5d178aedffa15f90c (patch)
treedd22a6542e5a27a23272679ab9762f0eecf5f4e8
parentAdd a helper function for making an outlined template (diff)
downloadroseh.moe-50e829808d7c61e04ed35af5d178aedffa15f90c.tar.zst
Add a package index
-rw-r--r--roseh.moe.go85
-rw-r--r--templates/pkg-index.html.template12
2 files changed, 86 insertions, 11 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index cef9657..407d112 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -26,6 +26,7 @@ import (
"net/http/httputil"
"net/url"
"os"
+ "slices"
"strconv"
"strings"
"sync"
@@ -86,9 +87,20 @@ func loadSecrets() error {
return nil
}
+type packageConfig struct {
+ url string
+ description string
+}
+
+type commandConfig struct {
+ url string
+ description string
+ multi bool
+}
+
type serviceConfiguration struct {
- packageRedirects map[string]string
- commandRedirects map[string]string
+ packageRedirects map[string]packageConfig
+ commandRedirects map[string]commandConfig
}
var (
@@ -117,26 +129,36 @@ func loadConfig() (*serviceConfiguration, error) {
}
var fileConfig struct {
Package []struct {
- Name string `xml:",attr"`
- URL string `xml:",attr"`
+ Name string `xml:",attr"`
+ URL string `xml:",attr"`
+ Description string `xml:",attr"`
} `xml:"Redirects>Package"`
Command []struct {
- Name string `xml:",attr"`
- URL string `xml:",attr"`
+ Name string `xml:",attr"`
+ URL string `xml:",attr"`
+ Description string `xml:",attr"`
+ Multi bool `xml:",attr"`
} `xml:"Redirects>Command"`
}
if err := xml.Unmarshal(fileBytes, &fileConfig); err != nil {
return nil, err
}
config := &serviceConfiguration{
- packageRedirects: make(map[string]string),
- commandRedirects: make(map[string]string),
+ packageRedirects: make(map[string]packageConfig),
+ commandRedirects: make(map[string]commandConfig),
}
for _, pkg := range fileConfig.Package {
- config.packageRedirects[pkg.Name] = pkg.URL
+ config.packageRedirects[pkg.Name] = packageConfig{
+ url: pkg.URL,
+ description: pkg.Description,
+ }
}
for _, cmd := range fileConfig.Command {
- config.commandRedirects[cmd.Name] = cmd.URL
+ config.commandRedirects[cmd.Name] = commandConfig{
+ url: cmd.URL,
+ description: cmd.Description,
+ multi: cmd.Multi,
+ }
}
serviceConfigMu.Lock()
serviceConfig = config
@@ -808,10 +830,50 @@ func cmd(w http.ResponseWriter, r *http.Request) {
}
}
+var (
+ //go:embed templates/pkg-index.html.template
+ pkgIndexString string
+ pkgIndexTemplate = template.Must(outlinedTemplate(pkgIndexString))
+)
+
+type pkgIndexTemplatePackage struct {
+ Name string
+ Description string
+}
+
+type pkgIndexTemplateArgs struct {
+ Packages []pkgIndexTemplatePackage
+}
+
+func pkgIndex(w http.ResponseWriter, r *http.Request) {
+ serviceConfig, err := loadConfig()
+ if err != nil {
+ log.Printf("Warning: failed to load config: %s", err)
+ http.Error(w, "Failed to load config", http.StatusInternalServerError)
+ return
+ }
+ packages := make([]string, 0, len(serviceConfig.packageRedirects))
+ for pkg := range serviceConfig.packageRedirects {
+ packages = append(packages, pkg)
+ }
+ slices.Sort(packages)
+ templatePackages := make([]pkgIndexTemplatePackage, len(packages))
+ for i, pkg := range packages {
+ templatePackages[i] = pkgIndexTemplatePackage{
+ Name: pkg,
+ Description: serviceConfig.packageRedirects[pkg].description,
+ }
+ }
+ if err := pkgIndexTemplate.Execute(w, pkgIndexTemplateArgs{Packages: templatePackages}); err != nil {
+ log.Printf("Warning: pkgIndex: %s", err)
+ }
+}
+
func pkg(w http.ResponseWriter, r *http.Request) {
serviceConfig, err := loadConfig()
if err != nil {
- http.Error(w, fmt.Sprintf("load config: %s", err), http.StatusInternalServerError)
+ log.Printf("Warning: failed to load config: %s", err)
+ http.Error(w, "Failed to load config", http.StatusInternalServerError)
return
}
source, ok := serviceConfig.packageRedirects[r.PathValue("pkg")]
@@ -865,6 +927,7 @@ func main() {
mux.HandleFunc("GET /notepad", notepad)
mux.HandleFunc("POST /notepad", autosave)
mux.HandleFunc("GET /cmd/{cmd}", cmd)
+ mux.HandleFunc("GET /pkg", pkgIndex)
mux.HandleFunc("GET /pkg/{pkg}", pkg)
mux.Handle("GET /code/", http.StripPrefix("/code/", http.FileServer(http.Dir(*codeDir))))
mux.HandleFunc("GET /static/", static)
diff --git a/templates/pkg-index.html.template b/templates/pkg-index.html.template
new file mode 100644
index 0000000..7628b86
--- /dev/null
+++ b/templates/pkg-index.html.template
@@ -0,0 +1,12 @@
+{{define "head"}}
+ <title>Packages</title>
+{{end}}
+
+<section>
+ <p>Package index</p>
+ <ul>
+ {{range .Packages}}
+ <li><p><a href="https://pkg.go.dev/roseh.moe/pkg/{{.Name}}">{{.Name}}</a> - {{.Description}}</p></li>
+ {{end}}
+ </ul>
+</section>