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[\\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() }