Prevent URL construction from crashing in prod
This commit is contained in:
parent
e3257bb383
commit
48dfb61997
|
@ -20,6 +20,7 @@ type Q struct {
|
||||||
|
|
||||||
var baseUrlParsed url.URL
|
var baseUrlParsed url.URL
|
||||||
var cacheBust string
|
var cacheBust string
|
||||||
|
var isTest bool
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
SetGlobalBaseUrl(config.Config.BaseUrl)
|
SetGlobalBaseUrl(config.Config.BaseUrl)
|
||||||
|
|
|
@ -14,6 +14,7 @@ func TestUrl(t *testing.T) {
|
||||||
SetGlobalBaseUrl(config.Config.BaseUrl)
|
SetGlobalBaseUrl(config.Config.BaseUrl)
|
||||||
}()
|
}()
|
||||||
SetGlobalBaseUrl("http://handmade.test")
|
SetGlobalBaseUrl("http://handmade.test")
|
||||||
|
isTest = true
|
||||||
|
|
||||||
t.Run("no query", func(t *testing.T) {
|
t.Run("no query", func(t *testing.T) {
|
||||||
result := Url("/test/foo", nil)
|
result := Url("/test/foo", nil)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.handmade.network/hmn/hmn/src/logging"
|
||||||
"git.handmade.network/hmn/hmn/src/oops"
|
"git.handmade.network/hmn/hmn/src/oops"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,36 +25,42 @@ func BuildHomepage() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildProjectHomepage(projectSlug string) string {
|
func BuildProjectHomepage(projectSlug string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return ProjectUrl("/", nil, projectSlug)
|
return ProjectUrl("/", nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexProjectIndex = regexp.MustCompile("^/projects$")
|
var RegexProjectIndex = regexp.MustCompile("^/projects$")
|
||||||
|
|
||||||
func BuildProjectIndex() string {
|
func BuildProjectIndex() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/projects", nil)
|
return Url("/projects", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexShowcase = regexp.MustCompile("^/showcase$")
|
var RegexShowcase = regexp.MustCompile("^/showcase$")
|
||||||
|
|
||||||
func BuildShowcase() string {
|
func BuildShowcase() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/showcase", nil)
|
return Url("/showcase", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexStreams = regexp.MustCompile("^/streams$")
|
var RegexStreams = regexp.MustCompile("^/streams$")
|
||||||
|
|
||||||
func BuildStreams() string {
|
func BuildStreams() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/streams", nil)
|
return Url("/streams", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexSiteMap = regexp.MustCompile("^/sitemap$")
|
var RegexSiteMap = regexp.MustCompile("^/sitemap$")
|
||||||
|
|
||||||
func BuildSiteMap() string {
|
func BuildSiteMap() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/sitemap", nil)
|
return Url("/sitemap", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexAtomFeed = regexp.MustCompile("^/atom$")
|
var RegexAtomFeed = regexp.MustCompile("^/atom$")
|
||||||
|
|
||||||
func BuildAtomFeed() string {
|
func BuildAtomFeed() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/atom", nil)
|
return Url("/atom", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,18 +69,21 @@ func BuildAtomFeed() string {
|
||||||
var RegexLoginAction = regexp.MustCompile("^/login$")
|
var RegexLoginAction = regexp.MustCompile("^/login$")
|
||||||
|
|
||||||
func BuildLoginAction(redirectTo string) string {
|
func BuildLoginAction(redirectTo string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/login", []Q{{Name: "redirect", Value: redirectTo}})
|
return Url("/login", []Q{{Name: "redirect", Value: redirectTo}})
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexLoginPage = regexp.MustCompile("^/_login$")
|
var RegexLoginPage = regexp.MustCompile("^/_login$")
|
||||||
|
|
||||||
func BuildLoginPage(redirectTo string) string {
|
func BuildLoginPage(redirectTo string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/_login", []Q{{Name: "redirect", Value: redirectTo}})
|
return Url("/_login", []Q{{Name: "redirect", Value: redirectTo}})
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexLogoutAction = regexp.MustCompile("^/logout$")
|
var RegexLogoutAction = regexp.MustCompile("^/logout$")
|
||||||
|
|
||||||
func BuildLogoutAction() string {
|
func BuildLogoutAction() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/logout", nil)
|
return Url("/logout", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,42 +94,49 @@ func BuildLogoutAction() string {
|
||||||
var RegexManifesto = regexp.MustCompile("^/manifesto$")
|
var RegexManifesto = regexp.MustCompile("^/manifesto$")
|
||||||
|
|
||||||
func BuildManifesto() string {
|
func BuildManifesto() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/manifesto", nil)
|
return Url("/manifesto", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexAbout = regexp.MustCompile("^/about$")
|
var RegexAbout = regexp.MustCompile("^/about$")
|
||||||
|
|
||||||
func BuildAbout() string {
|
func BuildAbout() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/about", nil)
|
return Url("/about", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexCodeOfConduct = regexp.MustCompile("^/code-of-conduct$")
|
var RegexCodeOfConduct = regexp.MustCompile("^/code-of-conduct$")
|
||||||
|
|
||||||
func BuildCodeOfConduct() string {
|
func BuildCodeOfConduct() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/code-of-conduct", nil)
|
return Url("/code-of-conduct", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexCommunicationGuidelines = regexp.MustCompile("^/communication-guidelines$")
|
var RegexCommunicationGuidelines = regexp.MustCompile("^/communication-guidelines$")
|
||||||
|
|
||||||
func BuildCommunicationGuidelines() string {
|
func BuildCommunicationGuidelines() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/communication-guidelines", nil)
|
return Url("/communication-guidelines", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexContactPage = regexp.MustCompile("^/contact$")
|
var RegexContactPage = regexp.MustCompile("^/contact$")
|
||||||
|
|
||||||
func BuildContactPage() string {
|
func BuildContactPage() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/contact", nil)
|
return Url("/contact", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexMonthlyUpdatePolicy = regexp.MustCompile("^/monthly-update-policy$")
|
var RegexMonthlyUpdatePolicy = regexp.MustCompile("^/monthly-update-policy$")
|
||||||
|
|
||||||
func BuildMonthlyUpdatePolicy() string {
|
func BuildMonthlyUpdatePolicy() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/monthly-update-policy", nil)
|
return Url("/monthly-update-policy", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexProjectSubmissionGuidelines = regexp.MustCompile("^/project-guidelines$")
|
var RegexProjectSubmissionGuidelines = regexp.MustCompile("^/project-guidelines$")
|
||||||
|
|
||||||
func BuildProjectSubmissionGuidelines() string {
|
func BuildProjectSubmissionGuidelines() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/project-guidelines", nil)
|
return Url("/project-guidelines", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +147,7 @@ func BuildProjectSubmissionGuidelines() string {
|
||||||
var RegexMember = regexp.MustCompile(`^/m/(?P<member>[^/]+)$`)
|
var RegexMember = regexp.MustCompile(`^/m/(?P<member>[^/]+)$`)
|
||||||
|
|
||||||
func BuildMember(username string) string {
|
func BuildMember(username string) string {
|
||||||
|
defer CatchPanic()
|
||||||
if len(username) == 0 {
|
if len(username) == 0 {
|
||||||
panic(oops.New(nil, "Username must not be blank"))
|
panic(oops.New(nil, "Username must not be blank"))
|
||||||
}
|
}
|
||||||
|
@ -143,10 +161,12 @@ func BuildMember(username string) string {
|
||||||
var RegexFeed = regexp.MustCompile(`^/feed(/(?P<page>.+)?)?$`)
|
var RegexFeed = regexp.MustCompile(`^/feed(/(?P<page>.+)?)?$`)
|
||||||
|
|
||||||
func BuildFeed() string {
|
func BuildFeed() string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/feed", nil)
|
return Url("/feed", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildFeedWithPage(page int) string {
|
func BuildFeedWithPage(page int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
panic(oops.New(nil, "Invalid feed page (%d), must be >= 1", page))
|
panic(oops.New(nil, "Invalid feed page (%d), must be >= 1", page))
|
||||||
}
|
}
|
||||||
|
@ -163,6 +183,7 @@ func BuildFeedWithPage(page int) string {
|
||||||
var RegexPodcast = regexp.MustCompile(`^/podcast$`)
|
var RegexPodcast = regexp.MustCompile(`^/podcast$`)
|
||||||
|
|
||||||
func BuildPodcast(projectSlug string) string {
|
func BuildPodcast(projectSlug string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return ProjectUrl("/podcast", nil, projectSlug)
|
return ProjectUrl("/podcast", nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +196,7 @@ func BuildPodcast(projectSlug string) string {
|
||||||
var RegexForumCategory = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?(/(?P<page>\d+))?$`)
|
var RegexForumCategory = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?(/(?P<page>\d+))?$`)
|
||||||
|
|
||||||
func BuildForumCategory(projectSlug string, subforums []string, page int) string {
|
func BuildForumCategory(projectSlug string, subforums []string, page int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
panic(oops.New(nil, "Invalid forum thread page (%d), must be >= 1", page))
|
panic(oops.New(nil, "Invalid forum thread page (%d), must be >= 1", page))
|
||||||
}
|
}
|
||||||
|
@ -192,6 +214,7 @@ func BuildForumCategory(projectSlug string, subforums []string, page int) string
|
||||||
var RegexForumNewThread = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/new?$`)
|
var RegexForumNewThread = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/new?$`)
|
||||||
|
|
||||||
func BuildForumNewThread(projectSlug string, subforums []string) string {
|
func BuildForumNewThread(projectSlug string, subforums []string) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumCategoryPath(subforums)
|
builder := buildForumCategoryPath(subforums)
|
||||||
builder.WriteString("/new")
|
builder.WriteString("/new")
|
||||||
|
|
||||||
|
@ -201,12 +224,14 @@ func BuildForumNewThread(projectSlug string, subforums []string) string {
|
||||||
var RegexForumThread = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)(-([^/]+))?(/(?P<page>\d+))?$`)
|
var RegexForumThread = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)(-([^/]+))?(/(?P<page>\d+))?$`)
|
||||||
|
|
||||||
func BuildForumThread(projectSlug string, subforums []string, threadId int, title string, page int) string {
|
func BuildForumThread(projectSlug string, subforums []string, threadId int, title string, page int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumThreadPath(subforums, threadId, title, page)
|
builder := buildForumThreadPath(subforums, threadId, title, page)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildForumThreadWithPostHash(projectSlug string, subforums []string, threadId int, title string, page int, postId int) string {
|
func BuildForumThreadWithPostHash(projectSlug string, subforums []string, threadId int, title string, page int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumThreadPath(subforums, threadId, title, page)
|
builder := buildForumThreadPath(subforums, threadId, title, page)
|
||||||
|
|
||||||
return ProjectUrlWithFragment(builder.String(), nil, projectSlug, strconv.Itoa(postId))
|
return ProjectUrlWithFragment(builder.String(), nil, projectSlug, strconv.Itoa(postId))
|
||||||
|
@ -215,6 +240,7 @@ func BuildForumThreadWithPostHash(projectSlug string, subforums []string, thread
|
||||||
var RegexForumPost = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)$`)
|
var RegexForumPost = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)$`)
|
||||||
|
|
||||||
func BuildForumPost(projectSlug string, subforums []string, threadId int, postId int) string {
|
func BuildForumPost(projectSlug string, subforums []string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumPostPath(subforums, threadId, postId)
|
builder := buildForumPostPath(subforums, threadId, postId)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -223,6 +249,7 @@ func BuildForumPost(projectSlug string, subforums []string, threadId int, postId
|
||||||
var RegexForumPostDelete = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)/delete$`)
|
var RegexForumPostDelete = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)/delete$`)
|
||||||
|
|
||||||
func BuildForumPostDelete(projectSlug string, subforums []string, threadId int, postId int) string {
|
func BuildForumPostDelete(projectSlug string, subforums []string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumPostPath(subforums, threadId, postId)
|
builder := buildForumPostPath(subforums, threadId, postId)
|
||||||
builder.WriteString("/delete")
|
builder.WriteString("/delete")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -231,6 +258,7 @@ func BuildForumPostDelete(projectSlug string, subforums []string, threadId int,
|
||||||
var RegexForumPostEdit = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)/edit$`)
|
var RegexForumPostEdit = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)/edit$`)
|
||||||
|
|
||||||
func BuildForumPostEdit(projectSlug string, subforums []string, threadId int, postId int) string {
|
func BuildForumPostEdit(projectSlug string, subforums []string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumPostPath(subforums, threadId, postId)
|
builder := buildForumPostPath(subforums, threadId, postId)
|
||||||
builder.WriteString("/edit")
|
builder.WriteString("/edit")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -240,6 +268,7 @@ var RegexForumPostReply = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+
|
||||||
|
|
||||||
// TODO: It's kinda weird that we have "replies" to a specific post. That's not how the data works. I guess this just affects what you see as the "post you're replying to" on the post composer page?
|
// TODO: It's kinda weird that we have "replies" to a specific post. That's not how the data works. I guess this just affects what you see as the "post you're replying to" on the post composer page?
|
||||||
func BuildForumPostReply(projectSlug string, subforums []string, threadId int, postId int) string {
|
func BuildForumPostReply(projectSlug string, subforums []string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumPostPath(subforums, threadId, postId)
|
builder := buildForumPostPath(subforums, threadId, postId)
|
||||||
builder.WriteString("/reply")
|
builder.WriteString("/reply")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -248,6 +277,7 @@ func BuildForumPostReply(projectSlug string, subforums []string, threadId int, p
|
||||||
var RegexForumPostQuote = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)/quote$`)
|
var RegexForumPostQuote = regexp.MustCompile(`^/forums(/(?P<cats>[^\d/]+(/[^\d]+)*))?/t/(?P<threadid>\d+)/p/(?P<postid>\d+)/quote$`)
|
||||||
|
|
||||||
func BuildForumPostQuote(projectSlug string, subforums []string, threadId int, postId int) string {
|
func BuildForumPostQuote(projectSlug string, subforums []string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildForumPostPath(subforums, threadId, postId)
|
builder := buildForumPostPath(subforums, threadId, postId)
|
||||||
builder.WriteString("/quote")
|
builder.WriteString("/quote")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -262,6 +292,7 @@ var RegexBlogsRedirect = regexp.MustCompile(`^/blogs`)
|
||||||
var RegexBlog = regexp.MustCompile(`^/blog(/(?P<page>\d+))?$`)
|
var RegexBlog = regexp.MustCompile(`^/blog(/(?P<page>\d+))?$`)
|
||||||
|
|
||||||
func BuildBlog(projectSlug string, page int) string {
|
func BuildBlog(projectSlug string, page int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if page < 1 {
|
if page < 1 {
|
||||||
panic(oops.New(nil, "Invalid blog page (%d), must be >= 1", page))
|
panic(oops.New(nil, "Invalid blog page (%d), must be >= 1", page))
|
||||||
}
|
}
|
||||||
|
@ -277,11 +308,13 @@ func BuildBlog(projectSlug string, page int) string {
|
||||||
var RegexBlogThread = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)(-([^/]+))?(/(?P<page>\d+))?$`)
|
var RegexBlogThread = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)(-([^/]+))?(/(?P<page>\d+))?$`)
|
||||||
|
|
||||||
func BuildBlogThread(projectSlug string, threadId int, title string, page int) string {
|
func BuildBlogThread(projectSlug string, threadId int, title string, page int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogThreadPath(threadId, title, page)
|
builder := buildBlogThreadPath(threadId, title, page)
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildBlogThreadWithPostHash(projectSlug string, threadId int, title string, page int, postId int) string {
|
func BuildBlogThreadWithPostHash(projectSlug string, threadId int, title string, page int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogThreadPath(threadId, title, page)
|
builder := buildBlogThreadPath(threadId, title, page)
|
||||||
return ProjectUrlWithFragment(builder.String(), nil, projectSlug, strconv.Itoa(postId))
|
return ProjectUrlWithFragment(builder.String(), nil, projectSlug, strconv.Itoa(postId))
|
||||||
}
|
}
|
||||||
|
@ -289,6 +322,7 @@ func BuildBlogThreadWithPostHash(projectSlug string, threadId int, title string,
|
||||||
var RegexBlogPost = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)$`)
|
var RegexBlogPost = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)$`)
|
||||||
|
|
||||||
func BuildBlogPost(projectSlug string, threadId int, postId int) string {
|
func BuildBlogPost(projectSlug string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogPostPath(threadId, postId)
|
builder := buildBlogPostPath(threadId, postId)
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
@ -296,6 +330,7 @@ func BuildBlogPost(projectSlug string, threadId int, postId int) string {
|
||||||
var RegexBlogPostDelete = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/delete$`)
|
var RegexBlogPostDelete = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/delete$`)
|
||||||
|
|
||||||
func BuildBlogPostDelete(projectSlug string, threadId int, postId int) string {
|
func BuildBlogPostDelete(projectSlug string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogPostPath(threadId, postId)
|
builder := buildBlogPostPath(threadId, postId)
|
||||||
builder.WriteString("/delete")
|
builder.WriteString("/delete")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -304,6 +339,7 @@ func BuildBlogPostDelete(projectSlug string, threadId int, postId int) string {
|
||||||
var RegexBlogPostEdit = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/edit$`)
|
var RegexBlogPostEdit = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/edit$`)
|
||||||
|
|
||||||
func BuildBlogPostEdit(projectSlug string, threadId int, postId int) string {
|
func BuildBlogPostEdit(projectSlug string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogPostPath(threadId, postId)
|
builder := buildBlogPostPath(threadId, postId)
|
||||||
builder.WriteString("/edit")
|
builder.WriteString("/edit")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -312,6 +348,7 @@ func BuildBlogPostEdit(projectSlug string, threadId int, postId int) string {
|
||||||
var RegexBlogPostReply = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/reply$`)
|
var RegexBlogPostReply = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/reply$`)
|
||||||
|
|
||||||
func BuildBlogPostReply(projectSlug string, threadId int, postId int) string {
|
func BuildBlogPostReply(projectSlug string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogPostPath(threadId, postId)
|
builder := buildBlogPostPath(threadId, postId)
|
||||||
builder.WriteString("/reply")
|
builder.WriteString("/reply")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -320,6 +357,7 @@ func BuildBlogPostReply(projectSlug string, threadId int, postId int) string {
|
||||||
var RegexBlogPostQuote = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/quote$`)
|
var RegexBlogPostQuote = regexp.MustCompile(`^/blog/p/(?P<threadid>\d+)/e/(?P<postid>\d+)/quote$`)
|
||||||
|
|
||||||
func BuildBlogPostQuote(projectSlug string, threadId int, postId int) string {
|
func BuildBlogPostQuote(projectSlug string, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildBlogPostPath(threadId, postId)
|
builder := buildBlogPostPath(threadId, postId)
|
||||||
builder.WriteString("/quote")
|
builder.WriteString("/quote")
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -332,24 +370,28 @@ func BuildBlogPostQuote(projectSlug string, threadId int, postId int) string {
|
||||||
var RegexWiki = regexp.MustCompile(`^/wiki$`)
|
var RegexWiki = regexp.MustCompile(`^/wiki$`)
|
||||||
|
|
||||||
func BuildWiki(projectSlug string) string {
|
func BuildWiki(projectSlug string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return ProjectUrl("/wiki", nil, projectSlug)
|
return ProjectUrl("/wiki", nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexWikiIndex = regexp.MustCompile(`^/wiki/index$`)
|
var RegexWikiIndex = regexp.MustCompile(`^/wiki/index$`)
|
||||||
|
|
||||||
func BuildWikiIndex(projectSlug string) string {
|
func BuildWikiIndex(projectSlug string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return ProjectUrl("/wiki/index", nil, projectSlug)
|
return ProjectUrl("/wiki/index", nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexWikiArticle = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?$`)
|
var RegexWikiArticle = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?$`)
|
||||||
|
|
||||||
func BuildWikiArticle(projectSlug string, articleId int, title string) string {
|
func BuildWikiArticle(projectSlug string, articleId int, title string) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiArticlePath(articleId, title)
|
builder := buildWikiArticlePath(articleId, title)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildWikiArticleWithSectionName(projectSlug string, articleId int, title string, sectionName string) string {
|
func BuildWikiArticleWithSectionName(projectSlug string, articleId int, title string, sectionName string) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiArticlePath(articleId, title)
|
builder := buildWikiArticlePath(articleId, title)
|
||||||
|
|
||||||
return ProjectUrlWithFragment(builder.String(), nil, projectSlug, sectionName)
|
return ProjectUrlWithFragment(builder.String(), nil, projectSlug, sectionName)
|
||||||
|
@ -358,6 +400,7 @@ func BuildWikiArticleWithSectionName(projectSlug string, articleId int, title st
|
||||||
var RegexWikiArticleEdit = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/edit$`)
|
var RegexWikiArticleEdit = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/edit$`)
|
||||||
|
|
||||||
func BuildWikiArticleEdit(projectSlug string, articleId int) string {
|
func BuildWikiArticleEdit(projectSlug string, articleId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiArticlePath(articleId, "")
|
builder := buildWikiArticlePath(articleId, "")
|
||||||
builder.WriteString("/edit")
|
builder.WriteString("/edit")
|
||||||
|
|
||||||
|
@ -367,6 +410,7 @@ func BuildWikiArticleEdit(projectSlug string, articleId int) string {
|
||||||
var RegexWikiArticleDelete = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/delete$`)
|
var RegexWikiArticleDelete = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/delete$`)
|
||||||
|
|
||||||
func BuildWikiArticleDelete(projectSlug string, articleId int) string {
|
func BuildWikiArticleDelete(projectSlug string, articleId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiArticlePath(articleId, "")
|
builder := buildWikiArticlePath(articleId, "")
|
||||||
builder.WriteString("/delete")
|
builder.WriteString("/delete")
|
||||||
|
|
||||||
|
@ -376,6 +420,7 @@ func BuildWikiArticleDelete(projectSlug string, articleId int) string {
|
||||||
var RegexWikiArticleHistory = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/history$`)
|
var RegexWikiArticleHistory = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/history$`)
|
||||||
|
|
||||||
func BuildWikiArticleHistory(projectSlug string, articleId int, title string) string {
|
func BuildWikiArticleHistory(projectSlug string, articleId int, title string) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiArticlePath(articleId, title)
|
builder := buildWikiArticlePath(articleId, title)
|
||||||
builder.WriteString("/history")
|
builder.WriteString("/history")
|
||||||
|
|
||||||
|
@ -385,6 +430,7 @@ func BuildWikiArticleHistory(projectSlug string, articleId int, title string) st
|
||||||
var RegexWikiTalk = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/talk$`)
|
var RegexWikiTalk = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/talk$`)
|
||||||
|
|
||||||
func BuildWikiTalk(projectSlug string, articleId int, title string) string {
|
func BuildWikiTalk(projectSlug string, articleId int, title string) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiArticlePath(articleId, title)
|
builder := buildWikiArticlePath(articleId, title)
|
||||||
builder.WriteString("/talk")
|
builder.WriteString("/talk")
|
||||||
|
|
||||||
|
@ -394,6 +440,7 @@ func BuildWikiTalk(projectSlug string, articleId int, title string) string {
|
||||||
var RegexWikiRevision = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/(?P<revisionid>\d+)$`)
|
var RegexWikiRevision = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/(?P<revisionid>\d+)$`)
|
||||||
|
|
||||||
func BuildWikiRevision(projectSlug string, articleId int, title string, revisionId int) string {
|
func BuildWikiRevision(projectSlug string, articleId int, title string, revisionId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if revisionId < 1 {
|
if revisionId < 1 {
|
||||||
panic(oops.New(nil, "Invalid wiki revision id (%d), must be >= 1", revisionId))
|
panic(oops.New(nil, "Invalid wiki revision id (%d), must be >= 1", revisionId))
|
||||||
}
|
}
|
||||||
|
@ -407,6 +454,7 @@ func BuildWikiRevision(projectSlug string, articleId int, title string, revision
|
||||||
var RegexWikiDiff = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/diff/(?P<revisionidold>\d+)/(?P<revisionidnew>\d+)$`)
|
var RegexWikiDiff = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)(-([^/])+)?/diff/(?P<revisionidold>\d+)/(?P<revisionidnew>\d+)$`)
|
||||||
|
|
||||||
func BuildWikiDiff(projectSlug string, articleId int, title string, revisionIdOld int, revisionIdNew int) string {
|
func BuildWikiDiff(projectSlug string, articleId int, title string, revisionIdOld int, revisionIdNew int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if revisionIdOld < 1 {
|
if revisionIdOld < 1 {
|
||||||
panic(oops.New(nil, "Invalid wiki revision id (%d), must be >= 1", revisionIdOld))
|
panic(oops.New(nil, "Invalid wiki revision id (%d), must be >= 1", revisionIdOld))
|
||||||
}
|
}
|
||||||
|
@ -426,6 +474,7 @@ func BuildWikiDiff(projectSlug string, articleId int, title string, revisionIdOl
|
||||||
var RegexWikiTalkPost = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)$`)
|
var RegexWikiTalkPost = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)$`)
|
||||||
|
|
||||||
func BuildWikiTalkPost(projectSlug string, articleId int, postId int) string {
|
func BuildWikiTalkPost(projectSlug string, articleId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiTalkPath(articleId, postId)
|
builder := buildWikiTalkPath(articleId, postId)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -434,6 +483,7 @@ func BuildWikiTalkPost(projectSlug string, articleId int, postId int) string {
|
||||||
var RegexWikiTalkPostDelete = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/delete$`)
|
var RegexWikiTalkPostDelete = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/delete$`)
|
||||||
|
|
||||||
func BuildWikiTalkPostDelete(projectSlug string, articleId int, postId int) string {
|
func BuildWikiTalkPostDelete(projectSlug string, articleId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiTalkPath(articleId, postId)
|
builder := buildWikiTalkPath(articleId, postId)
|
||||||
builder.WriteString("/delete")
|
builder.WriteString("/delete")
|
||||||
|
|
||||||
|
@ -443,6 +493,7 @@ func BuildWikiTalkPostDelete(projectSlug string, articleId int, postId int) stri
|
||||||
var RegexWikiTalkPostEdit = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/edit$`)
|
var RegexWikiTalkPostEdit = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/edit$`)
|
||||||
|
|
||||||
func BuildWikiTalkPostEdit(projectSlug string, articleId int, postId int) string {
|
func BuildWikiTalkPostEdit(projectSlug string, articleId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiTalkPath(articleId, postId)
|
builder := buildWikiTalkPath(articleId, postId)
|
||||||
builder.WriteString("/edit")
|
builder.WriteString("/edit")
|
||||||
|
|
||||||
|
@ -452,6 +503,7 @@ func BuildWikiTalkPostEdit(projectSlug string, articleId int, postId int) string
|
||||||
var RegexWikiTalkPostReply = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/reply$`)
|
var RegexWikiTalkPostReply = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/reply$`)
|
||||||
|
|
||||||
func BuildWikiTalkPostReply(projectSlug string, articleId int, postId int) string {
|
func BuildWikiTalkPostReply(projectSlug string, articleId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiTalkPath(articleId, postId)
|
builder := buildWikiTalkPath(articleId, postId)
|
||||||
builder.WriteString("/reply")
|
builder.WriteString("/reply")
|
||||||
|
|
||||||
|
@ -461,6 +513,7 @@ func BuildWikiTalkPostReply(projectSlug string, articleId int, postId int) strin
|
||||||
var RegexWikiTalkPostQuote = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/quote$`)
|
var RegexWikiTalkPostQuote = regexp.MustCompile(`^/wiki/(?P<articleid>\d+)/talk/(?P<postid>\d+)/quote$`)
|
||||||
|
|
||||||
func BuildWikiTalkPostQuote(projectSlug string, articleId int, postId int) string {
|
func BuildWikiTalkPostQuote(projectSlug string, articleId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildWikiTalkPath(articleId, postId)
|
builder := buildWikiTalkPath(articleId, postId)
|
||||||
builder.WriteString("/quote")
|
builder.WriteString("/quote")
|
||||||
|
|
||||||
|
@ -474,18 +527,21 @@ func BuildWikiTalkPostQuote(projectSlug string, articleId int, postId int) strin
|
||||||
var RegexLibrary = regexp.MustCompile(`^/library$`)
|
var RegexLibrary = regexp.MustCompile(`^/library$`)
|
||||||
|
|
||||||
func BuildLibrary(projectSlug string) string {
|
func BuildLibrary(projectSlug string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return ProjectUrl("/library", nil, projectSlug)
|
return ProjectUrl("/library", nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexLibraryAll = regexp.MustCompile(`^/library/all$`)
|
var RegexLibraryAll = regexp.MustCompile(`^/library/all$`)
|
||||||
|
|
||||||
func BuildLibraryAll(projectSlug string) string {
|
func BuildLibraryAll(projectSlug string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return ProjectUrl("/library/all", nil, projectSlug)
|
return ProjectUrl("/library/all", nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexLibraryTopic = regexp.MustCompile(`^/library/topic/(?P<topicid>\d+)$`)
|
var RegexLibraryTopic = regexp.MustCompile(`^/library/topic/(?P<topicid>\d+)$`)
|
||||||
|
|
||||||
func BuildLibraryTopic(projectSlug string, topicId int) string {
|
func BuildLibraryTopic(projectSlug string, topicId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if topicId < 1 {
|
if topicId < 1 {
|
||||||
panic(oops.New(nil, "Invalid library topic ID (%d), must be >= 1", topicId))
|
panic(oops.New(nil, "Invalid library topic ID (%d), must be >= 1", topicId))
|
||||||
}
|
}
|
||||||
|
@ -500,6 +556,7 @@ func BuildLibraryTopic(projectSlug string, topicId int) string {
|
||||||
var RegexLibraryResource = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)$`)
|
var RegexLibraryResource = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)$`)
|
||||||
|
|
||||||
func BuildLibraryResource(projectSlug string, resourceId int) string {
|
func BuildLibraryResource(projectSlug string, resourceId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryResourcePath(resourceId)
|
builder := buildLibraryResourcePath(resourceId)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -508,12 +565,14 @@ func BuildLibraryResource(projectSlug string, resourceId int) string {
|
||||||
var RegexLibraryDiscussion = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)(/(?P<page>\d+))?$`)
|
var RegexLibraryDiscussion = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)(/(?P<page>\d+))?$`)
|
||||||
|
|
||||||
func BuildLibraryDiscussion(projectSlug string, resourceId int, threadId int, page int) string {
|
func BuildLibraryDiscussion(projectSlug string, resourceId int, threadId int, page int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryDiscussionPath(resourceId, threadId, page)
|
builder := buildLibraryDiscussionPath(resourceId, threadId, page)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildLibraryDiscussionWithPostHash(projectSlug string, resourceId int, threadId int, page int, postId int) string {
|
func BuildLibraryDiscussionWithPostHash(projectSlug string, resourceId int, threadId int, page int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if postId < 1 {
|
if postId < 1 {
|
||||||
panic(oops.New(nil, "Invalid library post ID (%d), must be >= 1", postId))
|
panic(oops.New(nil, "Invalid library post ID (%d), must be >= 1", postId))
|
||||||
}
|
}
|
||||||
|
@ -525,6 +584,7 @@ func BuildLibraryDiscussionWithPostHash(projectSlug string, resourceId int, thre
|
||||||
var RegexLibraryPost = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)$`)
|
var RegexLibraryPost = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)$`)
|
||||||
|
|
||||||
func BuildLibraryPost(projectSlug string, resourceId int, threadId int, postId int) string {
|
func BuildLibraryPost(projectSlug string, resourceId int, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
||||||
|
|
||||||
return ProjectUrl(builder.String(), nil, projectSlug)
|
return ProjectUrl(builder.String(), nil, projectSlug)
|
||||||
|
@ -533,6 +593,7 @@ func BuildLibraryPost(projectSlug string, resourceId int, threadId int, postId i
|
||||||
var RegexLibraryPostDelete = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/delete$`)
|
var RegexLibraryPostDelete = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/delete$`)
|
||||||
|
|
||||||
func BuildLibraryPostDelete(projectSlug string, resourceId int, threadId int, postId int) string {
|
func BuildLibraryPostDelete(projectSlug string, resourceId int, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
||||||
builder.WriteString("/delete")
|
builder.WriteString("/delete")
|
||||||
|
|
||||||
|
@ -542,6 +603,7 @@ func BuildLibraryPostDelete(projectSlug string, resourceId int, threadId int, po
|
||||||
var RegexLibraryPostEdit = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/edit$`)
|
var RegexLibraryPostEdit = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/edit$`)
|
||||||
|
|
||||||
func BuildLibraryPostEdit(projectSlug string, resourceId int, threadId int, postId int) string {
|
func BuildLibraryPostEdit(projectSlug string, resourceId int, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
||||||
builder.WriteString("/edit")
|
builder.WriteString("/edit")
|
||||||
|
|
||||||
|
@ -551,6 +613,7 @@ func BuildLibraryPostEdit(projectSlug string, resourceId int, threadId int, post
|
||||||
var RegexLibraryPostReply = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/reply$`)
|
var RegexLibraryPostReply = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/reply$`)
|
||||||
|
|
||||||
func BuildLibraryPostReply(projectSlug string, resourceId int, threadId int, postId int) string {
|
func BuildLibraryPostReply(projectSlug string, resourceId int, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
||||||
builder.WriteString("/reply")
|
builder.WriteString("/reply")
|
||||||
|
|
||||||
|
@ -560,6 +623,7 @@ func BuildLibraryPostReply(projectSlug string, resourceId int, threadId int, pos
|
||||||
var RegexLibraryPostQuote = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/quote$`)
|
var RegexLibraryPostQuote = regexp.MustCompile(`^/library/resource/(?P<resourceid>\d+)/d/(?P<threadid>\d+)/p/(?P<postid>\d+)/quote$`)
|
||||||
|
|
||||||
func BuildLibraryPostQuote(projectSlug string, resourceId int, threadId int, postId int) string {
|
func BuildLibraryPostQuote(projectSlug string, resourceId int, threadId int, postId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
builder := buildLibraryPostPath(resourceId, threadId, postId)
|
||||||
builder.WriteString("/quote")
|
builder.WriteString("/quote")
|
||||||
|
|
||||||
|
@ -573,12 +637,14 @@ func BuildLibraryPostQuote(projectSlug string, resourceId int, threadId int, pos
|
||||||
var RegexProjectCSS = regexp.MustCompile("^/assets/project.css$")
|
var RegexProjectCSS = regexp.MustCompile("^/assets/project.css$")
|
||||||
|
|
||||||
func BuildProjectCSS(color string) string {
|
func BuildProjectCSS(color string) string {
|
||||||
|
defer CatchPanic()
|
||||||
return Url("/assets/project.css", []Q{{"color", color}})
|
return Url("/assets/project.css", []Q{{"color", color}})
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegexPublic = regexp.MustCompile("^/public/.+$")
|
var RegexPublic = regexp.MustCompile("^/public/.+$")
|
||||||
|
|
||||||
func BuildPublic(filepath string, cachebust bool) string {
|
func BuildPublic(filepath string, cachebust bool) string {
|
||||||
|
defer CatchPanic()
|
||||||
filepath = strings.Trim(filepath, "/")
|
filepath = strings.Trim(filepath, "/")
|
||||||
if len(strings.TrimSpace(filepath)) == 0 {
|
if len(strings.TrimSpace(filepath)) == 0 {
|
||||||
panic(oops.New(nil, "Attempted to build a /public url with no path"))
|
panic(oops.New(nil, "Attempted to build a /public url with no path"))
|
||||||
|
@ -605,6 +671,7 @@ func BuildPublic(filepath string, cachebust bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildTheme(filepath string, theme string, cachebust bool) string {
|
func BuildTheme(filepath string, theme string, cachebust bool) string {
|
||||||
|
defer CatchPanic()
|
||||||
if len(theme) == 0 {
|
if len(theme) == 0 {
|
||||||
panic(oops.New(nil, "Theme can't be blank"))
|
panic(oops.New(nil, "Theme can't be blank"))
|
||||||
}
|
}
|
||||||
|
@ -619,6 +686,7 @@ var RegexMarkRead = regexp.MustCompile(`^/_markread/(?P<catid>\d+)$`)
|
||||||
|
|
||||||
// NOTE(asaf): categoryId == 0 means ALL CATEGORIES
|
// NOTE(asaf): categoryId == 0 means ALL CATEGORIES
|
||||||
func BuildMarkRead(categoryId int) string {
|
func BuildMarkRead(categoryId int) string {
|
||||||
|
defer CatchPanic()
|
||||||
if categoryId < 0 {
|
if categoryId < 0 {
|
||||||
panic(oops.New(nil, "Invalid category ID (%d), must be >= 0", categoryId))
|
panic(oops.New(nil, "Invalid category ID (%d), must be >= 0", categoryId))
|
||||||
}
|
}
|
||||||
|
@ -827,3 +895,11 @@ func PathSafeTitle(title string) string {
|
||||||
title = url.PathEscape(title)
|
title = url.PathEscape(title)
|
||||||
return title
|
return title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CatchPanic() {
|
||||||
|
if !isTest {
|
||||||
|
if recovered := recover(); recovered != nil {
|
||||||
|
logging.LogPanicValue(nil, recovered, "Url construction failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -195,11 +195,7 @@ func LogPanicValue(logger *zerolog.Logger, val interface{}, msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err, ok := val.(error); ok {
|
if err, ok := val.(error); ok {
|
||||||
l := logger.Error().Err(err)
|
logger.Error().Stack().Err(err).Msg(msg)
|
||||||
if _, ok := err.(*oops.Error); !ok {
|
|
||||||
l = l.Interface(zerolog.ErrorStackFieldName, oops.Trace())
|
|
||||||
}
|
|
||||||
l.Msg(msg)
|
|
||||||
} else {
|
} else {
|
||||||
logger.Error().
|
logger.Error().
|
||||||
Interface("recovered", val).
|
Interface("recovered", val).
|
||||||
|
|
Loading…
Reference in New Issue