pronounsfu/backend/prns/main.go

100 lines
2.1 KiB
Go

package prns
import (
"context"
"net/http"
"os"
"os/signal"
"strings"
dbpkg "codeberg.org/pronounscc/pronouns.cc/backend/db"
"codeberg.org/pronounscc/pronouns.cc/backend/log"
"github.com/urfave/cli/v2"
)
var Command = &cli.Command{
Name: "shortener",
Usage: "URL shortener service",
Action: run,
}
func run(c *cli.Context) error {
port := ":" + os.Getenv("PRNS_PORT")
baseURL := os.Getenv("BASE_URL")
db, err := dbpkg.New()
if err != nil {
log.Fatalf("creating database: %v", err)
return err
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Errorf("recovered from panic: %v", err)
}
}()
id := strings.TrimPrefix(r.URL.Path, "/")
if len(id) == 5 {
u, err := db.UserBySID(r.Context(), id)
if err != nil {
if err != dbpkg.ErrUserNotFound {
log.Errorf("getting user: %v", err)
}
http.Redirect(w, r, baseURL, http.StatusTemporaryRedirect)
return
}
http.Redirect(w, r, baseURL+"/@"+u.Username, http.StatusTemporaryRedirect)
return
}
if len(id) == 6 {
m, err := db.MemberBySID(r.Context(), id)
if err != nil {
if err != dbpkg.ErrMemberNotFound {
log.Errorf("getting member: %v", err)
}
http.Redirect(w, r, baseURL, http.StatusTemporaryRedirect)
return
}
u, err := db.User(r.Context(), m.UserID)
if err != nil {
log.Errorf("getting user for member %v: %v", m.ID, err)
http.Redirect(w, r, baseURL, http.StatusTemporaryRedirect)
return
}
http.Redirect(w, r, baseURL+"/@"+u.Username+"/"+m.Name, http.StatusTemporaryRedirect)
return
}
http.Redirect(w, r, baseURL, http.StatusTemporaryRedirect)
})
e := make(chan error)
go func() {
e <- http.ListenAndServe(port, nil)
}()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
log.Infof("API server running at %v!", port)
select {
case <-ctx.Done():
log.Info("Interrupt signal received, shutting down...")
db.Close()
return nil
case err := <-e:
log.Fatalf("Error running server: %v", err)
}
return nil
}