AnP/Go/Managers/RoutesManager.go

208 lines
5.3 KiB
Go

package Managers
import (
"AnP/Drivers"
"AnP/Models"
"AnP/Modules"
"AnP/Utils"
"maps"
"slices"
"time"
)
type RoutesManager struct {
anp Models.AnPModel
domains []string
routes []Models.RoutesModel
indexes []string
wmarkdown_html_file string
}
var default_indexes []string = []string{"index.w.md", "index.md", "index.html", "index.htm"}
var default_wmarkdown_html string = "/HTML/AnP.wmarkdown.html"
func GetDefaultHTTPResponse() map[string]any {
return map[string]any{
"ok": false,
"code": 502,
}
}
func NewRoutesManager(anp Models.AnPModel, inputs any) RoutesManager {
var manager RoutesManager = RoutesManager{
anp: anp,
domains: Utils.GetStrings(anp.Settings.Get([]string{
"default_routes_domains", "default_routes_domain",
"default_domains", "default_domain",
"domains", "domain",
}, inputs, nil)),
routes: []Models.RoutesModel{},
indexes: Utils.GetStrings(anp.Settings.Get([]string{}, inputs, Utils.GetPointer[any](default_indexes))),
wmarkdown_html_file: Utils.Get(anp.Settings.Get("wmarkdown_html", inputs, Utils.GetPointer[any](default_wmarkdown_html)), &default_wmarkdown_html),
}
for _, key := range []string{"default_routes_files", "default_routes", "routes_files", "routes"} {
manager.Add(anp.Settings.Get(key, inputs, nil), true)
}
return manager
}
func (_self *RoutesManager) Add(inputs any, overwrite bool) {
switch group := inputs.(type) {
case string:
var route Models.RoutesModel = Models.NewRoutesModel(group)
if route.Ok {
var i int = -1
var exists bool = false
for _, current := range _self.routes {
if current.IsSame(route) {
i = current.I
exists = true
break
}
}
if overwrite || !exists {
if exists {
_self.routes[i] = route
route.I = i
} else {
route.I = len(_self.routes)
_self.routes = append(_self.routes, route)
}
}
} else {
_self.anp.Request.LoadJSON(group, func(data any) {
_self.Add(data, overwrite)
}, false)
}
case []any:
for _, subinputs := range group {
_self.Add(subinputs, overwrite)
}
}
}
func (_self RoutesManager) StringVariables(_string string, inputs any) string {
var dictionary map[string]any = Utils.GetDictionary(inputs, false)
return Utils.Patterns.Replace(_string, Utils.Patterns.RE_VIEWS_STRING_VARIABLES, func(matches Utils.PatternMatch) string {
if matches.Groups[1] != "" {
if value, exists := dictionary[matches.Groups[1]]; exists {
return Utils.ToString(value)
}
} else if matches.Groups[2] != "" {
return _self.anp.I18N.Get(Utils.StringVariables(matches.Groups[2], inputs, nil), inputs, matches.Groups[0])
}
return matches.Groups[0]
})
}
func (_self RoutesManager) Go(domain string, method string, url string, settings map[string]any) (map[string]any, bool) {
var response map[string]any = GetDefaultHTTPResponse()
var done bool = false
if slices.Contains(_self.domains, domain) || slices.Contains(_self.domains, "") {
response["code"] = 404
done = true
for _, route := range _self.routes {
var matches Utils.PatternMatch = Utils.Patterns.Match(url, route.URL)
if matches.Ok {
var variables map[string]any = route.GetVariables(matches)
if route.Type == Models.RouteTypePath {
switch subpath := variables["path"].(type) {
case string:
var slash string = _self.anp.Request.GetSlash()
subpath = route.Path + slash + subpath
var full_path string = _self.anp.Request.GetAbsolutePath(subpath)
var ok bool = Drivers.FileExists(full_path)
if !ok {
for _, index := range _self.indexes {
var temporary_path string = _self.anp.Request.GetAbsolutePath(subpath + slash + index)
ok = Drivers.FileExists(temporary_path)
if ok {
full_path = temporary_path
break
}
}
}
if ok {
if full_path[len(full_path)-3:] == ".md" {
html, subvariables := _self.anp.WMarkDown.Process(_self.anp.Request.LoadFile(full_path), Modules.WMD.HTML, full_path)
var last_date_modified time.Time = *Drivers.LastDateModified(full_path)
variables["contents"] = html
variables["version"] = last_date_modified.Format("20060102")
maps.Copy(variables, settings)
for key, value := range subvariables {
variables[key] = value
}
response["ok"] = true
response["code"] = 200
response["mime"] = "text/html;charset=" + variables["charset"].(string)
response["response"] = _self.StringVariables(_self.anp.Request.LoadFile(_self.wmarkdown_html_file), variables)
} else {
var mime_type string = Drivers.GetMime(full_path)
var data []byte = _self.anp.Request.LoadBinaryFile(full_path)
response["ok"] = true
response["code"] = 200
response["mime"] = mime_type
if mime_type[:5] == "text/" {
response["response"] = string(data)
} else {
response["response"] = data
}
}
}
default:
response["code"] = 501
}
} else if route.Type == Models.RouteTypeView {
response["code"] = 503
} else if route.Type == Models.RouteTypeController {
response["code"] = 503
} else {
response["code"] = 500
}
}
}
}
return response, done
}