2020-08-09 19:33:47 +00:00
package util
import (
2020-11-14 10:39:18 +00:00
"crypto/rand"
"encoding/hex"
2021-06-19 04:51:10 +00:00
"github.com/bouncepaw/mycorrhiza/files"
2021-05-09 10:42:12 +00:00
"log"
2020-08-31 17:52:26 +00:00
"net/http"
2020-08-09 19:33:47 +00:00
"strings"
2021-06-16 12:27:28 +00:00
2021-10-05 20:10:28 +00:00
"github.com/bouncepaw/mycomarkup/v3/util"
2021-06-16 12:27:28 +00:00
"github.com/bouncepaw/mycorrhiza/cfg"
2020-08-09 19:33:47 +00:00
)
2021-06-14 21:07:31 +00:00
// PrepareRq strips the trailing / in rq.URL.Path. In the future it might do more stuff for making all request structs uniform.
2021-05-09 10:42:12 +00:00
func PrepareRq ( rq * http . Request ) {
rq . URL . Path = strings . TrimSuffix ( rq . URL . Path , "/" )
}
2021-06-19 04:51:10 +00:00
// ShorterPath is used by handlerList to display shorter path to the files. It
// simply strips the hyphae directory name.
2020-08-09 19:33:47 +00:00
func ShorterPath ( path string ) string {
2021-06-19 04:51:10 +00:00
if strings . HasPrefix ( path , files . HyphaeDir ( ) ) {
tmp := strings . TrimPrefix ( path , files . HyphaeDir ( ) )
2020-08-09 19:33:47 +00:00
if tmp == "" {
return ""
}
return tmp [ 1 : ]
}
return path
}
2020-08-31 17:52:26 +00:00
2021-03-05 12:20:51 +00:00
// HTTP404Page writes a 404 error in the status, needed when no content is found on the page.
func HTTP404Page ( w http . ResponseWriter , page string ) {
w . Header ( ) . Set ( "Content-Type" , "text/html;charset=utf-8" )
w . WriteHeader ( http . StatusNotFound )
2021-06-14 21:07:31 +00:00
_ , _ = w . Write ( [ ] byte ( page ) )
2021-03-05 12:20:51 +00:00
}
2020-08-31 17:52:26 +00:00
// HTTP200Page wraps some frequently used things for successful 200 responses.
func HTTP200Page ( w http . ResponseWriter , page string ) {
w . Header ( ) . Set ( "Content-Type" , "text/html;charset=utf-8" )
w . WriteHeader ( http . StatusOK )
2021-06-14 21:07:31 +00:00
_ , _ = w . Write ( [ ] byte ( page ) )
2020-08-31 17:52:26 +00:00
}
2020-10-03 16:56:56 +00:00
2021-06-14 21:07:31 +00:00
// RandomString generates a random string of the given length. It is cryptographically secure to some extent.
2020-11-14 10:39:18 +00:00
func RandomString ( n int ) ( string , error ) {
bytes := make ( [ ] byte , n )
if _ , err := rand . Read ( bytes ) ; err != nil {
return "" , err
}
return hex . EncodeToString ( bytes ) , nil
}
2021-01-10 11:58:02 +00:00
2021-06-14 21:07:31 +00:00
// BeautifulName makes the ugly name beautiful by replacing _ with spaces and using title case.
2021-01-10 11:58:02 +00:00
func BeautifulName ( uglyName string ) string {
2021-06-14 21:07:31 +00:00
// Why not reuse
return util . BeautifulName ( uglyName )
2021-01-10 11:58:02 +00:00
}
2021-01-28 19:07:21 +00:00
// CanonicalName makes sure the `name` is canonical. A name is canonical if it is lowercase and all spaces are replaced with underscores.
func CanonicalName ( name string ) string {
2021-06-14 21:07:31 +00:00
return util . CanonicalName ( name )
2021-01-28 19:07:21 +00:00
}
2022-01-02 18:21:08 +00:00
// IsProfileName if the given hypha name is a profile name. It takes configuration into consideration.
//
// With default configuration, u/ is the prefix such names have. For example, u/wikimind matches. Note that u/wikimind/sub does not.
func IsProfileName ( hyphaName string ) bool {
return strings . HasPrefix ( hyphaName , cfg . UserHypha + "/" ) && strings . Count ( hyphaName , "/" ) == 1
}
2021-05-09 10:42:12 +00:00
// HyphaNameFromRq extracts hypha name from http request. You have to also pass the action which is embedded in the url or several actions. For url /hypha/hypha, the action would be "hypha".
func HyphaNameFromRq ( rq * http . Request , actions ... string ) string {
p := rq . URL . Path
for _ , action := range actions {
if strings . HasPrefix ( p , "/" + action + "/" ) {
return CanonicalName ( strings . TrimPrefix ( p , "/" + action + "/" ) )
}
}
2021-06-14 21:07:31 +00:00
log . Println ( "HyphaNameFromRq: this request is invalid, fall back to home hypha" )
2021-05-09 10:42:12 +00:00
return cfg . HomeHypha
}
2021-07-02 12:02:42 +00:00
// FormData is a convenient struct for passing user input and errors to HTML
// forms and showing to the user.
type FormData struct {
err error
fields map [ string ] string
}
2021-10-01 17:12:16 +00:00
// NewFormData constructs empty form data instance.
2021-07-02 12:02:42 +00:00
func NewFormData ( ) FormData {
return FormData {
err : nil ,
fields : map [ string ] string { } ,
}
}
2021-10-01 17:12:16 +00:00
// FormDataFromRequest extracts a form data from request, using a set of keys.
2021-07-02 12:02:42 +00:00
func FormDataFromRequest ( r * http . Request , keys [ ] string ) FormData {
formData := NewFormData ( )
for _ , key := range keys {
formData . Put ( key , r . FormValue ( key ) )
}
return formData
}
2021-10-01 17:12:16 +00:00
// HasError is true if there is indeed an error.
2021-07-02 12:02:42 +00:00
func ( f FormData ) HasError ( ) bool {
return f . err != nil
}
2021-10-01 17:12:16 +00:00
// Error returns an error text or empty string, if there are no errors in form data.
2021-07-02 12:02:42 +00:00
func ( f FormData ) Error ( ) string {
if f . err == nil {
return ""
}
return f . err . Error ( )
}
2021-10-01 17:12:16 +00:00
// WithError puts an error into form data and returns itself.
2021-07-02 12:02:42 +00:00
func ( f FormData ) WithError ( err error ) FormData {
f . err = err
return f
}
2021-10-01 17:12:16 +00:00
// Get accesses form data with a key
2021-07-02 12:02:42 +00:00
func ( f FormData ) Get ( key string ) string {
return f . fields [ key ]
}
2021-10-01 17:34:56 +00:00
// Put writes a form value for provided key
2021-07-02 12:02:42 +00:00
func ( f FormData ) Put ( key , value string ) {
f . fields [ key ] = value
}