api: Begin implementing an API

This commit is contained in:
Tom 2023-04-28 10:25:36 +02:00
parent 1a5e83be10
commit 2fac0390b1
11 changed files with 186 additions and 23 deletions

View file

@ -0,0 +1,64 @@
package home
import (
"context"
"net/http"
"time"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/FAU-CDI/wisski-distillery/internal/status"
"github.com/tkw1536/pkglib/httpx"
)
type API struct {
component.Base
Dependencies struct {
Home *Home
}
}
var (
_ component.Routeable = (*API)(nil)
)
func (api *API) Routes() component.Routes {
return component.Routes{
Prefix: "/api/v1/systems",
Exact: true,
Decorator: api.Config.HTTP.APIDecorator("GET"),
}
}
type APISystemInfo struct {
Slug string
URL string
Tagline string
EntityCount int
BundleCount int
LastEdit time.Time
}
func (api *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
return httpx.JSON(func(r *http.Request) ([]APISystemInfo, error) {
var statuses []status.WissKI
if api.Dependencies.Home.ShouldShowList(r) {
statuses = api.Dependencies.Home.homeInstances.Get(nil)
}
if len(statuses) == 0 {
return []APISystemInfo{}, nil
}
infos := make([]APISystemInfo, len(statuses))
for i, status := range statuses {
infos[i].Slug = status.Slug
infos[i].URL = status.URL
infos[i].EntityCount = status.Statistics.Bundles.TotalCount()
infos[i].BundleCount = status.Statistics.Bundles.TotalBundles
infos[i].LastEdit = status.Statistics.Bundles.LastEdit().Time
}
return infos, nil
}), nil
}

View file

@ -29,7 +29,6 @@ var aboutTemplate = template.Must(template.New("about.html").Parse(aboutHTML))
// aboutContext is passed to about.html
type aboutContext struct {
Instances []status.WissKI // list of WissKI Instancaes
SignedIn bool // is there a signed in user?
Logo template.HTML
SelfRedirect string
}
@ -48,6 +47,23 @@ type publicContext struct {
const logoHTML = template.HTML(`<img src="/logo.svg" alt="WissKI Distillery Logo" class="biglogo">`)
// ShouldShowList determines if the given request should show a WissKI list
func (home *Home) ShouldShowList(r *http.Request) bool {
allowPrivate := home.Config.Home.List.Private.Value
allowPublic := home.Config.Home.List.Public.Value
if allowPrivate == allowPublic {
return allowPrivate
}
user, _ := home.Dependencies.Auth.UserOf(r)
if user == nil {
return allowPublic
} else {
return allowPrivate
}
}
func (home *Home) publicHandler(ctx context.Context) http.Handler {
title := home.Config.Home.Title
@ -75,10 +91,6 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
pc.aboutContext.Logo = logoHTML
pc.aboutContext.Instances = home.homeInstances.Get(nil)
pc.aboutContext.SelfRedirect = home.Config.Home.SelfRedirect.String()
{
user, _ := home.Dependencies.Auth.UserOf(r)
pc.aboutContext.SignedIn = user != nil
}
// render the about template
@ -89,13 +101,8 @@ func (home *Home) publicHandler(ctx context.Context) http.Handler {
// and return about!
pc.About = template.HTML(builder.String())
// user is not signed in!
if pc.aboutContext.SignedIn {
pc.ListEnabled = home.Config.Home.List.Private.Value
} else {
pc.ListEnabled = home.Config.Home.List.Public.Value
}
// check if we should show the list of WissKIs
pc.ListEnabled = home.ShouldShowList(r)
// title of the list
pc.ListTitle = home.Config.Home.List.Title

View file

@ -0,0 +1,43 @@
package news
import (
"context"
"encoding/json"
"net/http"
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
"github.com/tkw1536/pkglib/httpx"
)
type API struct {
component.Base
}
var (
_ component.Routeable = (*API)(nil)
)
func (api *API) Routes() component.Routes {
return component.Routes{
Prefix: "/api/v1/news/",
Exact: true,
Decorator: api.Config.HTTP.APIDecorator("GET"),
}
}
func (api *API) HandleRoute(ctx context.Context, path string) (http.Handler, error) {
items, err := Items()
if err != nil {
return nil, err
}
data, err := json.Marshal(items)
if err != nil {
return nil, err
}
return httpx.Response{
ContentType: "application/json",
Body: data,
}, nil
}

View file

@ -187,5 +187,9 @@ func (dis *Distillery) allComponents() []initFunc {
auto[*cron.Cron],
auto[*home.UpdateHome],
auto[*home.UpdateInstanceList],
// API
auto[*home.API],
auto[*news.API],
}
}