99 lines
2.1 KiB
Go
99 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
|
|
}
|