2022-04-01 20:52:56 +00:00
package categories
2022-03-20 08:21:59 +00:00
import (
2022-03-26 15:31:13 +00:00
"github.com/bouncepaw/mycorrhiza/user"
2022-03-20 08:21:59 +00:00
"github.com/bouncepaw/mycorrhiza/util"
2022-03-29 20:59:36 +00:00
"github.com/bouncepaw/mycorrhiza/viewutil"
2022-03-20 08:21:59 +00:00
"github.com/gorilla/mux"
2022-03-26 15:31:13 +00:00
"io"
2022-03-29 16:41:12 +00:00
"log"
2022-03-20 08:21:59 +00:00
"net/http"
2022-03-29 16:41:12 +00:00
"strings"
2022-03-20 08:21:59 +00:00
)
2022-04-01 22:01:54 +00:00
// InitHandlers initializes HTTP handlers for the given router. Call somewhere in package web.
func InitHandlers ( r * mux . Router ) {
2022-03-20 08:21:59 +00:00
r . PathPrefix ( "/add-to-category" ) . HandlerFunc ( handlerAddToCategory ) . Methods ( "POST" )
r . PathPrefix ( "/remove-from-category" ) . HandlerFunc ( handlerRemoveFromCategory ) . Methods ( "POST" )
r . PathPrefix ( "/category/" ) . HandlerFunc ( handlerCategory ) . Methods ( "GET" )
2022-07-24 11:41:16 +00:00
r . PathPrefix ( "/edit-category/" ) . HandlerFunc ( handlerEditCategory ) . Methods ( "GET" )
2022-03-20 18:24:54 +00:00
r . PathPrefix ( "/category" ) . HandlerFunc ( handlerListCategory ) . Methods ( "GET" )
2022-04-01 20:52:56 +00:00
prepareViews ( )
2022-03-20 18:24:54 +00:00
}
2022-07-24 11:41:16 +00:00
func handlerEditCategory ( w http . ResponseWriter , rq * http . Request ) {
util . PrepareRq ( rq )
catName := util . CanonicalName ( strings . TrimPrefix ( strings . TrimPrefix ( rq . URL . Path , "/edit-category" ) , "/" ) )
if catName == "" {
http . Error ( w , "No category name" , http . StatusBadRequest )
return
}
log . Println ( "Editing category" , catName )
categoryEdit ( viewutil . MetaFrom ( w , rq ) , catName )
}
2022-03-20 18:24:54 +00:00
func handlerListCategory ( w http . ResponseWriter , rq * http . Request ) {
2022-03-29 16:41:12 +00:00
log . Println ( "Viewing list of categories" )
2022-04-01 20:52:56 +00:00
categoryList ( viewutil . MetaFrom ( w , rq ) )
2022-03-20 08:21:59 +00:00
}
func handlerCategory ( w http . ResponseWriter , rq * http . Request ) {
util . PrepareRq ( rq )
2022-03-29 16:41:12 +00:00
catName := util . CanonicalName ( strings . TrimPrefix ( strings . TrimPrefix ( rq . URL . Path , "/category" ) , "/" ) )
if catName == "" {
handlerListCategory ( w , rq )
return
}
log . Println ( "Viewing category" , catName )
2022-04-01 20:52:56 +00:00
categoryPage ( viewutil . MetaFrom ( w , rq ) , catName )
2022-03-20 08:21:59 +00:00
}
2022-07-24 11:41:16 +00: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 {
log . Println ( err )
}
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 08:21:59 +00:00
func handlerRemoveFromCategory ( w http . ResponseWriter , rq * http . Request ) {
2022-03-20 09:28:51 +00:00
util . PrepareRq ( rq )
var (
2022-07-24 11:41:16 +00:00
u = user . FromRequest ( rq )
hyphaNames = hyphaeFromRequest ( rq )
2022-03-20 11:50:18 +00:00
catName = util . CanonicalName ( rq . PostFormValue ( "cat" ) )
2022-03-20 09:28:51 +00:00
redirectTo = rq . PostFormValue ( "redirect-to" )
)
2022-07-24 11:41:16 +00:00
if ! u . CanProceed ( "remove-from-category" ) {
2022-03-26 15:31:13 +00:00
w . WriteHeader ( http . StatusForbidden )
_ , _ = io . WriteString ( w , "403 Forbidden" )
return
}
2022-07-24 11:41:16 +00:00
if len ( hyphaNames ) == 0 || catName == "" {
log . Printf ( "%s passed no data for removal of hyphae from a category\n" , u . Name )
2022-03-29 16:46:29 +00:00
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
return
}
2022-07-24 11:41:16 +00:00
for _ , hyphaName := range hyphaNames {
// TODO: Make it more effective.
removeHyphaFromCategory ( hyphaName , catName )
}
log . Printf ( "%s removed %q from category %s\n" , u . Name , hyphaNames , catName )
2022-03-20 09:28:51 +00:00
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
2022-03-20 08:21:59 +00:00
}
func handlerAddToCategory ( w http . ResponseWriter , rq * http . Request ) {
2022-03-20 09:28:51 +00:00
util . PrepareRq ( rq )
var (
2022-03-20 11:50:18 +00:00
hyphaName = util . CanonicalName ( rq . PostFormValue ( "hypha" ) )
catName = util . CanonicalName ( rq . PostFormValue ( "cat" ) )
2022-03-20 09:28:51 +00:00
redirectTo = rq . PostFormValue ( "redirect-to" )
)
2022-03-26 15:31:13 +00:00
if ! user . FromRequest ( rq ) . CanProceed ( "add-to-category" ) {
w . WriteHeader ( http . StatusForbidden )
_ , _ = io . WriteString ( w , "403 Forbidden" )
return
}
2022-03-29 16:46:29 +00:00
if hyphaName == "" || catName == "" {
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
return
}
2022-04-01 21:45:58 +00:00
log . Println ( user . FromRequest ( rq ) . Name , "added" , hyphaName , "to" , catName )
2022-07-01 15:51:22 +00:00
AddHyphaToCategory ( hyphaName , catName )
2022-03-20 09:28:51 +00:00
http . Redirect ( w , rq , redirectTo , http . StatusSeeOther )
2022-03-20 08:21:59 +00:00
}