2024-09-07 21:22:41 +03:00
package web
2022-03-20 11:21:59 +03:00
import (
2022-03-26 18:31:13 +03:00
"io"
2024-09-07 21:22:41 +03:00
"log/slog"
2022-03-20 11:21:59 +03:00
"net/http"
2024-09-07 21:22:41 +03:00
"sort"
2022-03-29 19:41:12 +03:00
"strings"
2022-03-20 11:21:59 +03:00
2024-09-07 23:55:39 +03:00
"github.com/bouncepaw/mycorrhiza/internal/categories"
2024-09-07 21:22:41 +03:00
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/web/viewutil"
)
2022-03-20 21:24:54 +03:00
2022-07-24 16:41:16 +05:00
func handlerEditCategory ( w http . ResponseWriter , rq * http . Request ) {
util . PrepareRq ( rq )
2024-09-07 21:22:41 +03:00
meta := viewutil . MetaFrom ( w , rq )
2022-07-24 16:41:16 +05:00
catName := util . CanonicalName ( strings . TrimPrefix ( strings . TrimPrefix ( rq . URL . Path , "/edit-category" ) , "/" ) )
if catName == "" {
2024-09-07 21:22:41 +03:00
viewutil . HandlerNotFound ( w , rq )
2022-07-24 16:41:16 +05:00
return
}
2024-09-07 21:22:41 +03:00
slog . Info ( "Editing category" , "name" , catName )
_ = pageCatEdit . RenderTo ( meta , map [ string ] any {
"Addr" : "/edit-category/" + catName ,
"CatName" : catName ,
"Hyphae" : categories . HyphaeInCategory ( catName ) ,
"GivenPermissionToModify" : meta . U . CanProceed ( "add-to-category" ) ,
} )
2022-07-24 16:41:16 +05:00
}
2022-03-20 21:24:54 +03:00
func handlerListCategory ( w http . ResponseWriter , rq * http . Request ) {
2024-09-07 21:22:41 +03:00
slog . Info ( "Viewing list of categories" )
cats := categories . ListOfCategories ( )
sort . Strings ( cats )
_ = pageCatList . RenderTo ( viewutil . MetaFrom ( w , rq ) , map [ string ] any {
"Addr" : "/category" ,
"Categories" : cats ,
} )
2022-03-20 11:21:59 +03:00
}
func handlerCategory ( w http . ResponseWriter , rq * http . Request ) {
util . PrepareRq ( rq )
2022-03-29 19:41:12 +03:00
catName := util . CanonicalName ( strings . TrimPrefix ( strings . TrimPrefix ( rq . URL . Path , "/category" ) , "/" ) )
if catName == "" {
handlerListCategory ( w , rq )
return
}
2024-09-07 21:22:41 +03:00
meta := viewutil . MetaFrom ( w , rq )
slog . Info ( "Viewing category" , "name" , catName )
_ = pageCatPage . RenderTo ( meta , map [ string ] any {
"Addr" : "/category/" + catName ,
"CatName" : catName ,
"Hyphae" : categories . HyphaeInCategory ( catName ) ,
"GivenPermissionToModify" : meta . U . CanProceed ( "add-to-category" ) ,
} )
2022-03-20 11:21:59 +03:00
}
2022-07-24 16:41:16 +05:00
// A request for removal of hyphae can either remove one hypha (used in the card on /hypha) or many hyphae (used in /edit-category). Both approaches are handled by /remove-from-category. This function finds all passed hyphae.
//
// There is one hypha from the hypha field. Then there are n hyphae in fields prefixed by _. It seems like I have to do it myself. Compare with PHP which handles it for you. I hope I am doing this wrong.
func hyphaeFromRequest ( rq * http . Request ) ( canonicalNames [ ] string ) {
if err := rq . ParseForm ( ) ; err != nil {
2024-09-07 23:55:39 +03:00
slog . Info ( "Failed to parse form" , "err" , err )
2022-07-24 16:41:16 +05:00
}
if hyphaName := util . CanonicalName ( rq . PostFormValue ( "hypha" ) ) ; hyphaName != "" {
canonicalNames = append ( canonicalNames , hyphaName )
}
// According to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox,
//
// > If a checkbox is unchecked when its form is submitted, there is no value submitted to the server to represent its unchecked state
//
// It means, that if there is a value, it is checked. And we can ignore values altogether.
for key , _ := range rq . PostForm {
// No prefix or "_":
if ! strings . HasPrefix ( key , "_" ) || len ( key ) == 1 {
continue
}
canonicalNames = append ( canonicalNames , util . CanonicalName ( key [ 1 : ] ) )
}
return
}
2022-03-20 11:21:59 +03:00
func handlerRemoveFromCategory ( w http . ResponseWriter , rq * http . Request ) {
2022-03-20 12:28:51 +03:00
util . PrepareRq ( rq )
var (
2022-07-24 16:41:16 +05:00
u = user . FromRequest ( rq )
hyphaNames = hyphaeFromRequest ( rq )
2022-03-20 14:50:18 +03:00
catName = util . CanonicalName ( rq . PostFormValue ( "cat" ) )
2022-03-20 12:28:51 +03:00
redirectTo = rq . PostFormValue ( "redirect-to" )
)
2022-07-24 16:41:16 +05:00
if ! u . CanProceed ( "remove-from-category" ) {
2022-03-26 18:31:13 +03:00
w . WriteHeader ( http . StatusForbidden )
_ , _ = io . WriteString ( w , "403 Forbidden" )
return
}
2022-07-24 16:41:16 +05:00
if len ( hyphaNames ) == 0 || catName == "" {
2024-09-07 23:55:39 +03:00
slog . Info ( "No data for removal of hyphae from category passed" ,
"username" , u . Name , "catName" , catName )
2022-03-29 19:46:29 +03:00
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
return
}
2022-07-24 16:41:16 +05:00
for _ , hyphaName := range hyphaNames {
// TODO: Make it more effective.
2024-09-07 21:22:41 +03:00
categories . RemoveHyphaFromCategory ( hyphaName , catName )
2022-07-24 16:41:16 +05:00
}
2024-09-07 23:55:39 +03:00
slog . Info ( "Remove hyphae from category" ,
"username" , u . Name , "catName" , catName , "hyphaNames" , hyphaNames )
2022-03-20 12:28:51 +03:00
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
2022-03-20 11:21:59 +03:00
}
func handlerAddToCategory ( w http . ResponseWriter , rq * http . Request ) {
2022-03-20 12:28:51 +03:00
util . PrepareRq ( rq )
var (
2022-03-20 14:50:18 +03:00
hyphaName = util . CanonicalName ( rq . PostFormValue ( "hypha" ) )
catName = util . CanonicalName ( rq . PostFormValue ( "cat" ) )
2022-03-20 12:28:51 +03:00
redirectTo = rq . PostFormValue ( "redirect-to" )
)
2022-03-26 18:31:13 +03:00
if ! user . FromRequest ( rq ) . CanProceed ( "add-to-category" ) {
w . WriteHeader ( http . StatusForbidden )
_ , _ = io . WriteString ( w , "403 Forbidden" )
return
}
2022-03-29 19:46:29 +03:00
if hyphaName == "" || catName == "" {
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
return
}
2024-09-07 21:22:41 +03:00
slog . Info ( user . FromRequest ( rq ) . Name , "added" , hyphaName , "to" , catName )
categories . AddHyphaToCategory ( hyphaName , catName )
2022-03-20 12:28:51 +03:00
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
2022-03-20 11:21:59 +03:00
}