add page for single micro-blog posts

", p.ID, p.Source, p.ID))
posted: %s
", p.Timestamp.Format("2006-01-02 15:04")))

")

", post.Title))

",

")

---

")
")
")

", post.Title))
")
")
This commit is contained in:
Travis Shears 2025-10-18 21:17:34 +02:00
parent a88994add4
commit d6d00f6dc9
Signed by: travisshears
GPG key ID: CB9BF1910F3F7469
3 changed files with 76 additions and 25 deletions

View file

@ -162,6 +162,30 @@ func transformMastodonPost(p pbPost) post {
}
}
// GetRecentPosts returns the most recent posts
func (mb *MicroBlog) GetPost(id string) (post, error) {
res, err := mb.pbClient.GetRecord("micro_blog_posts", id)
if err != nil {
return post{}, fmt.Errorf("failed to fetch post from pocketbase: %w", err)
}
var remotePost pbPost
if err := json.Unmarshal(*res, &remotePost); err != nil {
return post{}, fmt.Errorf("failed to decode response: %w", err)
}
slog.Info("post from pocketbase", "remotePost", remotePost)
switch remotePost.Source {
case SourceMastodon:
return transformMastodonPost(remotePost), nil
case SourceNostr:
return transformNostrPost(remotePost), nil
case SourceBlueSky:
return transformBlueSkyPost(remotePost), nil
}
return post{},
fmt.Errorf("Don't know how to transform a post with that source")
}
// GetRecentPosts returns the most recent posts
func (mb *MicroBlog) GetRecentPosts(limit int, page int) ([]post, error) {
res, err := mb.pbClient.GetList("micro_blog_posts", page, limit, "-posted")
@ -173,7 +197,7 @@ func (mb *MicroBlog) GetRecentPosts(limit int, page int) ([]post, error) {
if err := json.Unmarshal(res.Items, &rawPosts); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}
slog.Info("Posts from pocketbase", "rawPosts", rawPosts)
slog.Info("Posts from pocketbase", "count", len(rawPosts))
var filteredPosts []post
for _, p := range rawPosts {
@ -221,16 +245,16 @@ func (mb *MicroBlog) HandleBlogRequest(w gemini.ResponseWriter, req *gemini.Requ
return
}
mb.serveIndex(w, req, num)
// case strings.HasPrefix(path, "/microblog/post/"):
// postID := strings.TrimPrefix(path, "/microblog/post/")
// mb.servePost(w, req, postID)
case strings.HasPrefix(path, "/microblog/post/"):
postID := strings.TrimPrefix(path, "/microblog/post/")
mb.servePost(w, req, postID)
default:
w.WriteStatusMsg(gemini.StatusNotFound, "Page not found")
}
}
func drawPost(builder *strings.Builder, p post) {
builder.WriteString(fmt.Sprintf("=> / 🖋️ %s post: %s \n", p.Source, p.ID))
builder.WriteString(fmt.Sprintf("=> /microblog/post/%s 🖋️ %s post: %s \n", p.ID, p.Source, p.ID))
builder.WriteString(formatContent(p.Content))
builder.WriteString(fmt.Sprintf("\nposted: %s\n", p.Timestamp.Format("2006-01-02 15:04")))
builder.WriteString("\n\n")
@ -274,26 +298,22 @@ func (mb *MicroBlog) serveIndex(w gemini.ResponseWriter, req *gemini.Request, pa
w.WriteBody([]byte(content.String()))
}
// servePost serves a single blog post
// func (mb *MicroBlog) servePost(w gemini.ResponseWriter, req *gemini.Request, postID string) {
// post, found := mb.GetPost(postID)
// if !found {
// w.WriteStatusMsg(gemini.StatusNotFound, "Post not found")
// return
// }
// // servePost serves a single blog post
func (mb *MicroBlog) servePost(w gemini.ResponseWriter, req *gemini.Request, postID string) {
post, err := mb.GetPost(postID)
if err != nil {
slog.Error("Problem getting post", "error", err)
w.WriteStatusMsg(gemini.StatusNotFound, "Problem getting post")
return
}
// w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
// var content strings.Builder
// content.WriteString(fmt.Sprintf("# %s\n\n", post.Title))
// content.WriteString(fmt.Sprintf("By %s on %s\n\n",
// post.Author,
// post.Timestamp.Format("2006-01-02 15:04")))
// content.WriteString("---\n\n")
// content.WriteString(post.Content)
// content.WriteString("\n\n---\n\n")
// content.WriteString("=> /blog Back to blog\n")
// content.WriteString("=> / Back to home\n")
var content strings.Builder
// content.WriteString(fmt.Sprintf("# %s\n\n", post.Title))
drawPost(&content, post)
content.WriteString("=> /microblog Back to posts\n")
content.WriteString("=> / Back to home\n")
// w.WriteBody([]byte(content.String()))
// }
w.WriteBody([]byte(content.String()))
}

View file

@ -195,3 +195,33 @@ func (c *PocketBaseClient) GetList(
}
return &res, nil
}
func (c *PocketBaseClient) GetRecord(
collection string,
id string,
) (*[]byte, error) {
slog.Info(
"Getting single record from pocketbase",
"recordId", id)
apiURL := fmt.Sprintf("%s/api/collections/%s/records/%s", c.host, collection, id)
resp, err := c.makeAuthenticatedRequest("GET", apiURL, nil)
if err != nil {
return nil, fmt.Errorf("failed to make request: %w", err)
}
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
defer resp.Body.Close()
var res pbRes
if err := json.Unmarshal(body, &res); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}
return &body, nil
}

View file

@ -1,4 +1,5 @@
-----------DONE LINE-----------
DONE task: make page for single micro blog posts
DONE task: rework the micro-blog to be more like station
DONE task: add mastodon and bluysky to microblog
DONE task: implement dir codeview pages