2022-04-01 23:52:56 +03:00
package categories
2022-03-20 11:21:59 +03:00
import (
2022-03-26 18:31:13 +03:00
"github.com/bouncepaw/mycorrhiza/user"
2022-03-20 11:21:59 +03:00
"github.com/bouncepaw/mycorrhiza/util"
2022-03-29 23:59:36 +03:00
"github.com/bouncepaw/mycorrhiza/viewutil"
2022-03-20 11:21:59 +03:00
"github.com/gorilla/mux"
2022-03-26 18:31:13 +03:00
"io"
2022-03-29 19:41:12 +03:00
"log"
2022-03-20 11:21:59 +03:00
"net/http"
2022-03-29 19:41:12 +03:00
"strings"
2022-03-20 11:21:59 +03:00
)
2022-04-02 01:01:54 +03:00
// InitHandlers initializes HTTP handlers for the given router. Call somewhere in package web.
func InitHandlers ( r * mux . Router ) {
2022-03-20 11:21:59 +03: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 16:41:16 +05:00
r . PathPrefix ( "/edit-category/" ) . HandlerFunc ( handlerEditCategory ) . Methods ( "GET" )
2022-03-20 21:24:54 +03:00
r . PathPrefix ( "/category" ) . HandlerFunc ( handlerListCategory ) . Methods ( "GET" )
2022-04-01 23:52:56 +03:00
prepareViews ( )
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 )
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 21:24:54 +03:00
func handlerListCategory ( w http . ResponseWriter , rq * http . Request ) {
2022-03-29 19:41:12 +03:00
log . Println ( "Viewing list of categories" )
2022-04-01 23:52:56 +03:00
categoryList ( viewutil . MetaFrom ( w , rq ) )
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
}
log . Println ( "Viewing category" , catName )
2022-04-01 23:52:56 +03:00
categoryPage ( viewutil . MetaFrom ( w , rq ) , catName )
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 {
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 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 == "" {
log . Printf ( "%s passed no data for removal of hyphae from a category\n" , u . Name )
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.
removeHyphaFromCategory ( hyphaName , catName )
}
log . Printf ( "%s removed %q from category %s\n" , u . Name , hyphaNames , catName )
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
}
2022-04-02 00:45:58 +03:00
log . Println ( user . FromRequest ( rq ) . Name , "added" , hyphaName , "to" , catName )
2022-07-01 20:51:22 +05:00
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
}