implemented the /go shortcut processing
This commit is contained in:
+78
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Amsterdam Web Communities System
|
* Amsterdam Web Communities System
|
||||||
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
* Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -92,6 +92,83 @@ func (d *PostLinkData) AsString() string {
|
|||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Classify tells us what kind of post link this is and where we should interpret it from.
|
||||||
|
* Returns:
|
||||||
|
* String value indicating the scope of the link:
|
||||||
|
* "global" - Scope across the entire site.
|
||||||
|
* "community" - Scope within a community.
|
||||||
|
* "conference" - Scope within a conference.
|
||||||
|
* "topic" - Scope within a specific topic.
|
||||||
|
* Empty string - Null link.
|
||||||
|
* String value indicating what the link points to:
|
||||||
|
* "community" - Points to a community.
|
||||||
|
* "conference" - Points to a conference.
|
||||||
|
* "topic" - Points to a topic.
|
||||||
|
* "post" - Points to a single post within the topic.
|
||||||
|
* "postrange" - Points to a range of posts within the topic.
|
||||||
|
* "postopenrange" - Points to an open-ended range of posts within the topic.
|
||||||
|
* Empty string - Null link.
|
||||||
|
*/
|
||||||
|
func (d *PostLinkData) Classify() (string, string) {
|
||||||
|
if d.Community == "" {
|
||||||
|
if d.Conference == "" {
|
||||||
|
if d.Topic == -1 {
|
||||||
|
if d.FirstPost == -1 {
|
||||||
|
return "", ""
|
||||||
|
} else if d.LastPost == -1 {
|
||||||
|
return "topic", "postopenrange"
|
||||||
|
} else if d.LastPost == d.FirstPost {
|
||||||
|
return "topic", "post"
|
||||||
|
} else {
|
||||||
|
return "topic", "postrange"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if d.FirstPost == -1 {
|
||||||
|
return "conference", "topic"
|
||||||
|
} else if d.LastPost == -1 {
|
||||||
|
return "conference", "postopenrange"
|
||||||
|
} else if d.LastPost == d.FirstPost {
|
||||||
|
return "conference", "post"
|
||||||
|
} else {
|
||||||
|
return "conference", "postrange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if d.Topic == -1 {
|
||||||
|
return "community", "conference"
|
||||||
|
} else {
|
||||||
|
if d.FirstPost == -1 {
|
||||||
|
return "community", "topic"
|
||||||
|
} else if d.LastPost == -1 {
|
||||||
|
return "community", "postopenrange"
|
||||||
|
} else if d.LastPost == d.FirstPost {
|
||||||
|
return "community", "post"
|
||||||
|
} else {
|
||||||
|
return "community", "postrange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if d.Conference == "" {
|
||||||
|
return "global", "community"
|
||||||
|
} else {
|
||||||
|
if d.Topic == -1 {
|
||||||
|
return "global", "conference"
|
||||||
|
} else {
|
||||||
|
if d.FirstPost == -1 {
|
||||||
|
return "global", "topic"
|
||||||
|
} else if d.LastPost == -1 {
|
||||||
|
return "global", "postopenrange"
|
||||||
|
} else if d.LastPost == d.FirstPost {
|
||||||
|
return "global", "post"
|
||||||
|
} else {
|
||||||
|
return "global", "postrange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Maximum lengths of the components.
|
// Maximum lengths of the components.
|
||||||
const (
|
const (
|
||||||
maxLinkLength = 130
|
maxLinkLength = 130
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func setupEcho() *echo.Echo {
|
|||||||
e.POST("/TODO/*", fn)
|
e.POST("/TODO/*", fn)
|
||||||
e.GET("/img/*", ui.AmServeImage)
|
e.GET("/img/*", ui.AmServeImage)
|
||||||
e.GET("/static/*", ui.AmStaticFileHandler())
|
e.GET("/static/*", ui.AmStaticFileHandler())
|
||||||
e.GET("/go/:postlink", fn)
|
e.GET("/go/:postlink", ui.AmWrap(JumpToShortcut))
|
||||||
|
|
||||||
e.GET("/", ui.AmWrap(TopPage))
|
e.GET("/", ui.AmWrap(TopPage))
|
||||||
e.GET("/about", ui.AmWrap(AboutPage))
|
e.GET("/about", ui.AmWrap(AboutPage))
|
||||||
@@ -79,7 +79,9 @@ func setupEcho() *echo.Echo {
|
|||||||
|
|
||||||
// community group
|
// community group
|
||||||
commGroup := e.Group("/comm/:cid", ui.SetCommunity)
|
commGroup := e.Group("/comm/:cid", ui.SetCommunity)
|
||||||
commGroup.GET("/profile", ui.AmWrap(ShowCommunity))
|
fn1 := ui.AmWrap(ShowCommunity)
|
||||||
|
commGroup.GET("", fn1)
|
||||||
|
commGroup.GET("/profile", fn1)
|
||||||
commGroup.GET("/join", ui.AmWrap(JoinCommunity))
|
commGroup.GET("/join", ui.AmWrap(JoinCommunity))
|
||||||
commGroup.POST("/join", ui.AmWrap(JoinCommunityWithKey))
|
commGroup.POST("/join", ui.AmWrap(JoinCommunityWithKey))
|
||||||
commGroup.GET("/unjoin", ui.AmWrap(UnjoinCommunity))
|
commGroup.GET("/unjoin", ui.AmWrap(UnjoinCommunity))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Amsterdam Web Communities System
|
* Amsterdam Web Communities System
|
||||||
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
* Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -11,6 +11,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"git.erbosoft.com/amy/amsterdam/database"
|
"git.erbosoft.com/amy/amsterdam/database"
|
||||||
"git.erbosoft.com/amy/amsterdam/ui"
|
"git.erbosoft.com/amy/amsterdam/ui"
|
||||||
@@ -210,3 +211,42 @@ func AboutPage(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().Set("amsterdam_pageTitle", "About Amsterdam")
|
ctxt.VarMap().Set("amsterdam_pageTitle", "About Amsterdam")
|
||||||
return "framed_template", "about.jet", nil
|
return "framed_template", "about.jet", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* JumpToShortcut resolves "/go" links by redirecting them to the appropriate page.
|
||||||
|
* Parameters:
|
||||||
|
* ctxt - The AmContext for the request.
|
||||||
|
* Returns:
|
||||||
|
* Command string dictating what to be rendered.
|
||||||
|
* Data as a parameter for the command string.
|
||||||
|
* Standard Go error status.
|
||||||
|
*/
|
||||||
|
func JumpToShortcut(ctxt ui.AmContext) (string, any, error) {
|
||||||
|
link, err := database.AmDecodePostLink(ctxt.URLParam("postlink"))
|
||||||
|
if err != nil {
|
||||||
|
ctxt.SetRC(http.StatusNotFound)
|
||||||
|
return ui.ErrorPage(ctxt, fmt.Errorf("not found: %s (%v)", ctxt.URLParam("postlink"), err))
|
||||||
|
}
|
||||||
|
scope, target := link.Classify()
|
||||||
|
if scope != "global" {
|
||||||
|
ctxt.SetRC(http.StatusNotFound)
|
||||||
|
return ui.ErrorPage(ctxt, fmt.Errorf("not found: %s", ctxt.URLParam("postlink")))
|
||||||
|
}
|
||||||
|
if err = link.VerifyNames(ctxt.Ctx()); err != nil {
|
||||||
|
ctxt.SetRC(http.StatusNotFound)
|
||||||
|
return ui.ErrorPage(ctxt, fmt.Errorf("not found: %s (%v)", ctxt.URLParam("postlink"), err))
|
||||||
|
}
|
||||||
|
targetURL := ""
|
||||||
|
switch target {
|
||||||
|
case "community":
|
||||||
|
targetURL = fmt.Sprintf("/comm/%s", link.Community)
|
||||||
|
case "conference":
|
||||||
|
targetURL = fmt.Sprintf("/comm/%s/conf/%s", link.Community, link.Conference)
|
||||||
|
case "topic":
|
||||||
|
targetURL = fmt.Sprintf("/comm/%s/conf/%s/r/%d", link.Community, link.Conference, link.Topic)
|
||||||
|
case "post", "postrange", "postopenrange":
|
||||||
|
targetURL = fmt.Sprintf("/comm/%s/conf/%s/r/%d?r=%d,%d", link.Community, link.Conference, link.Topic, link.FirstPost, link.LastPost)
|
||||||
|
default:
|
||||||
|
return ui.ErrorPage(ctxt, fmt.Errorf("invalid target '%s' for link: %s", target, ctxt.URLParam("postlink")))
|
||||||
|
}
|
||||||
|
return "redirect", targetURL, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user