hmn/src/hmnurl/hmnurl.go

109 lines
2.5 KiB
Go

package hmnurl
import (
"fmt"
"net/url"
"regexp"
"time"
"git.handmade.network/hmn/hmn/src/models"
"git.handmade.network/hmn/hmn/src/config"
"git.handmade.network/hmn/hmn/src/oops"
)
type Q struct {
Name string
Value string
}
func QFromURL(u *url.URL) []Q {
var result []Q
for key, values := range u.Query() {
for _, v := range values {
result = append(result, Q{Name: key, Value: v})
}
}
return result
}
var baseUrlParsed url.URL
var cacheBustVersion string
var S3BaseUrl string
var isTest bool
func init() {
SetGlobalBaseUrl(config.Config.BaseUrl)
SetCacheBustVersion(fmt.Sprint(time.Now().Unix()))
SetS3BaseUrl(config.Config.DigitalOcean.AssetsPublicUrlRoot)
}
func SetGlobalBaseUrl(fullBaseUrl string) {
parsed, err := url.Parse(fullBaseUrl)
if err != nil {
panic(oops.New(err, "could not parse base URL"))
}
if parsed.Scheme == "" || parsed.Host == "" {
panic(oops.New(nil, "Website is misconfigured. Config should include a full BaseUrl (e.g. \"http://handmade.local:9001\")"))
}
baseUrlParsed = *parsed
}
func SetCacheBustVersion(newCacheBustVersion string) {
cacheBustVersion = newCacheBustVersion
}
func SetS3BaseUrl(base string) {
S3BaseUrl = base
RegexS3Asset = regexp.MustCompile(fmt.Sprintf("%s(?P<key>[\\w\\-./]+)", regexp.QuoteMeta(S3BaseUrl)))
}
func GetBaseHost() string {
return baseUrlParsed.Host
}
type UrlContext struct {
PersonalProject bool
ProjectID int
ProjectSlug string
ProjectName string
}
var HMNProjectContext = UrlContext{
PersonalProject: false,
ProjectID: models.HMNProjectID,
ProjectSlug: models.HMNProjectSlug,
}
func Url(path string, query []Q) string {
return UrlWithFragment(path, query, "")
}
func UrlWithFragment(path string, query []Q, fragment string) string {
return HMNProjectContext.UrlWithFragment(path, query, fragment)
}
// Takes a project URL and rewrites it using the current URL context. This can be used
// to convert a personal project URL to official and vice versa.
func (c *UrlContext) RewriteProjectUrl(u *url.URL) string {
// we need to strip anything matching the personal project regex to get the base path
match := RegexPersonalProject.FindString(u.Path)
return c.Url(u.Path[len(match):], QFromURL(u))
}
func trim(path string) string {
if len(path) > 0 && path[0] == '/' {
return path[1:]
}
return path
}
func encodeQuery(query []Q) string {
result := url.Values{}
for _, q := range query {
result.Set(q.Name, q.Value)
}
return result.Encode()
}