You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
7.0 KiB
Go
294 lines
7.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"io"
|
|
|
|
"git.phc.dm.unipi.it/phc/website/appunti"
|
|
"git.phc.dm.unipi.it/phc/website/articles"
|
|
"git.phc.dm.unipi.it/phc/website/auth"
|
|
"git.phc.dm.unipi.it/phc/website/lista_utenti"
|
|
"git.phc.dm.unipi.it/phc/website/model"
|
|
"git.phc.dm.unipi.it/phc/website/rss"
|
|
"git.phc.dm.unipi.it/phc/website/storia"
|
|
"git.phc.dm.unipi.it/phc/website/templates"
|
|
"git.phc.dm.unipi.it/phc/website/util"
|
|
)
|
|
|
|
type Service interface {
|
|
//
|
|
// Pages
|
|
//
|
|
HandleStaticPage(w io.Writer, view string, ctx Context) error
|
|
|
|
// Storia
|
|
HandleStoriaPage(w io.Writer, ctx Context) error
|
|
|
|
// Appunti
|
|
HandleAppuntiPage(w io.Writer, query string, ctx Context) error
|
|
HandleAppuntiCondivisiPage(w io.Writer, ctx Context) error
|
|
HandleDispensaPage(w io.Writer, id string, ctx Context) error
|
|
|
|
// News
|
|
HandleNewsPage(w io.Writer, ctx Context) error
|
|
|
|
// Guide
|
|
HandleGuidePage(w io.Writer, ctx Context) error
|
|
|
|
// User
|
|
HandleProfilePage(w io.Writer, ctx Context) error
|
|
|
|
// Article Pages
|
|
HandleNewsArticlePage(w io.Writer, articleID string, ctx Context) error
|
|
HandleGuideArticlePage(w io.Writer, articleID string, ctx Context) error
|
|
|
|
// RSS
|
|
HandleNewsFeedPage(w io.Writer) error
|
|
HandleGuideFeedPage(w io.Writer) error
|
|
|
|
//
|
|
// API
|
|
//
|
|
|
|
// User
|
|
HandleLogin(username, password string) (*model.Session, error)
|
|
HandleUser(token string) *model.User
|
|
HandleRequiredUser(ctx Context) (*model.User, error)
|
|
|
|
// User Listing
|
|
HandleUtenti() ([]*model.User, error)
|
|
HandleListaUtenti() ([]*model.ListUser, error)
|
|
|
|
// Appunti
|
|
HandleCreateDispensa(template model.Dispensa, ctx Context) (string, error)
|
|
HandleGetDispensa(dispensaId string) (*model.Dispensa, error)
|
|
}
|
|
|
|
//
|
|
// Typed context
|
|
//
|
|
|
|
// UserKey is a typed type for *model.User used to extract a user form a [handler.Context]
|
|
const UserKey ContextKey[*model.User] = "user"
|
|
|
|
func (ctx Context) getUser() *model.User {
|
|
return GetContextValue(ctx, UserKey)
|
|
}
|
|
|
|
// Handler holds references to abstract services for easy testing provided by every module (TODO: Make every field an interface of -Service)
|
|
type DefaultHandler struct {
|
|
AuthService auth.Service
|
|
Appunti appunti.Service
|
|
Renderer *templates.TemplateRenderer
|
|
NewsArticlesRegistry *articles.Registry
|
|
GuideArticlesRegistry *articles.Registry
|
|
ListaUtenti lista_utenti.Service
|
|
Storia storia.StoriaService
|
|
}
|
|
|
|
var _ Service = &DefaultHandler{}
|
|
|
|
func (h *DefaultHandler) HandleStaticPage(w io.Writer, view string, ctx Context) error {
|
|
return h.Renderer.Render(w, view, util.Map{
|
|
"User": ctx.getUser(),
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleUtenti() ([]*model.User, error) {
|
|
utenti, err := h.AuthService.GetUsers()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return utenti, nil
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleListaUtenti() ([]*model.ListUser, error) {
|
|
utenti, err := h.ListaUtenti.GetUtenti()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return utenti, nil
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleStoriaPage(w io.Writer, ctx Context) error {
|
|
storia, err := h.Storia.GetStoria()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Renderer.Render(w, "storia.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Storia": storia,
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleAppuntiPage(w io.Writer, query string, ctx Context) error {
|
|
return h.Renderer.Render(w, "appunti.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Query": query,
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleAppuntiCondivisiPage(w io.Writer, ctx Context) error {
|
|
return h.Renderer.Render(w, "appunti-condivisi.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleDispensaPage(w io.Writer, id string, ctx Context) error {
|
|
dispensa, err := h.Appunti.GetDispensa(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Renderer.Render(w, "dispensa.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Dispensa": dispensa,
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleNewsPage(w io.Writer, ctx Context) error {
|
|
articles, err := h.NewsArticlesRegistry.GetArticles()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Renderer.Render(w, "news.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Articles": articles,
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleGuidePage(w io.Writer, ctx Context) error {
|
|
articles, err := h.GuideArticlesRegistry.GetArticles()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Renderer.Render(w, "guide.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Articles": articles,
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleLogin(username, password string) (*model.Session, error) {
|
|
session, err := h.AuthService.Login(username, password)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleUser(token string) *model.User {
|
|
user, _ := auth.UserForSession(h.AuthService, token)
|
|
return user
|
|
}
|
|
|
|
var ErrNoUser = fmt.Errorf(`user not logged in`)
|
|
|
|
func (h *DefaultHandler) HandleRequiredUser(ctx Context) (*model.User, error) {
|
|
user := ctx.getUser()
|
|
if user == nil {
|
|
return nil, ErrNoUser
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleProfilePage(w io.Writer, ctx Context) error {
|
|
user := ctx.getUser()
|
|
if user == nil {
|
|
return ErrNoUser
|
|
}
|
|
|
|
return h.Renderer.Render(w, "profilo.html", util.Map{
|
|
"User": user,
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleNewsArticlePage(w io.Writer, articleID string, ctx Context) error {
|
|
article, err := h.NewsArticlesRegistry.GetArticle(articleID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
html, err := article.Render()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Renderer.Render(w, "news-base.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Article": article,
|
|
"ContentHTML": template.HTML(html),
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleGuideArticlePage(w io.Writer, articleID string, ctx Context) error {
|
|
article, err := h.GuideArticlesRegistry.GetArticle(articleID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
html, err := article.Render()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return h.Renderer.Render(w, "guide-base.html", util.Map{
|
|
"User": ctx.getUser(),
|
|
"Article": article,
|
|
"ContentHTML": template.HTML(html),
|
|
})
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleNewsFeedPage(w io.Writer) error {
|
|
registry, err := h.NewsArticlesRegistry.GetArticles()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
newsFeed := rss.GenerateRssFeed(registry, "news", "Feed Notizie PHC", "https://phc.dm.unipi.it/news", "Le ultime nuove sul PHC.")
|
|
|
|
return newsFeed.WriteRss(w)
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleGuideFeedPage(w io.Writer) error {
|
|
registry, err := h.GuideArticlesRegistry.GetArticles()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
guideFeed := rss.GenerateRssFeed(registry, "guide", "Feed Guide PHC", "https://phc.dm.unipi.it/guide", "Le più recenti guide a carattere informatico a cura dei macchinisti del PHC.")
|
|
|
|
return guideFeed.WriteRss(w)
|
|
}
|
|
|
|
//
|
|
// API
|
|
//
|
|
|
|
func (h *DefaultHandler) HandleCreateDispensa(template model.Dispensa, ctx Context) (string, error) {
|
|
user := ctx.getUser()
|
|
if user == nil {
|
|
return "", ErrNoUser
|
|
}
|
|
|
|
template.OwnerId = user.Username
|
|
|
|
dispensaId, err := h.Appunti.CreateDispensa(template)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return dispensaId, nil
|
|
}
|
|
|
|
func (h *DefaultHandler) HandleGetDispensa(id string) (*model.Dispensa, error) {
|
|
return h.Appunti.GetDispensa(id)
|
|
}
|