mastodon-markdown-archive/client/client.go

124 lines
2.3 KiB
Go
Raw Normal View History

2024-05-13 08:47:26 +00:00
package client
import (
"fmt"
"net/url"
"strings"
)
type Client struct {
handle string
baseURL string
filters PostsFilter
account Account
posts []Post
2024-05-18 13:22:23 +00:00
replies map[string]string
2024-05-13 08:47:26 +00:00
orphans []string
2024-05-18 13:22:23 +00:00
postIdMap map[string]int
output []int
2024-05-13 08:47:26 +00:00
}
type PostsFilter struct {
ExcludeReplies bool
ExcludeReblogs bool
Limit int
SinceId string
MinId string
MaxId string
}
func New(userURL string, filters PostsFilter, threaded bool) (Client, error) {
var client Client
parsedURL, err := url.Parse(userURL)
if err != nil {
return client, fmt.Errorf("error parsing user url: %w", err)
}
baseURL := fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host)
acc := strings.TrimPrefix(parsedURL.Path, "/")
handle := strings.TrimPrefix(acc, "@")
2024-05-18 14:08:07 +00:00
account, err := FetchAccount(baseURL, handle)
2024-05-13 08:47:26 +00:00
if err != nil {
return client, err
}
2024-05-18 14:08:07 +00:00
posts, err := FetchPosts(baseURL, account.Id, filters)
2024-05-13 08:47:26 +00:00
if err != nil {
return client, err
}
var orphans []string
client = Client{
2024-05-18 13:22:23 +00:00
baseURL: baseURL,
handle: handle,
filters: filters,
account: account,
posts: posts,
postIdMap: make(map[string]int),
replies: make(map[string]string),
orphans: orphans,
2024-05-13 08:47:26 +00:00
}
client.populateIdMap()
if threaded {
client.generateReplies()
2024-05-18 13:22:23 +00:00
} else {
for i := range client.posts {
2024-05-18 14:08:07 +00:00
client.output = append(client.output, i)
2024-05-18 13:22:23 +00:00
}
2024-05-13 08:47:26 +00:00
}
return client, nil
}
func (c Client) Account() Account {
return c.account
}
2024-05-18 13:22:23 +00:00
func (c Client) Posts() []*Post {
var p []*Post
for _, i := range c.output {
p = append(p, &c.posts[i])
}
return p
2024-05-13 08:47:26 +00:00
}
2024-05-18 13:22:23 +00:00
func (c *Client) populateIdMap() {
for i, post := range c.posts {
c.postIdMap[post.Id] = i
2024-05-13 08:47:26 +00:00
}
}
2024-05-18 13:22:23 +00:00
func (c *Client) flushReplies(post *Post, descendants *[]*Post) {
if pid, ok := c.replies[post.Id]; ok {
reply := c.posts[c.postIdMap[pid]]
*descendants = append(*descendants, &reply)
c.flushReplies(&reply, descendants)
2024-05-13 08:47:26 +00:00
}
}
2024-05-18 13:22:23 +00:00
func (c *Client) generateReplies() {
for i := range c.posts {
post := &c.posts[i]
2024-05-13 08:47:26 +00:00
if post.InReplyToId == "" {
c.flushReplies(post, &post.descendants)
2024-05-18 13:22:23 +00:00
c.output = append(c.output, i)
2024-05-13 08:47:26 +00:00
continue
}
2024-05-18 13:22:23 +00:00
if _, ok := c.postIdMap[post.InReplyToId]; ok {
// TODO: Exclude from list of posts that gets rendered to disc
c.replies[post.InReplyToId] = post.Id
2024-05-13 08:47:26 +00:00
} else {
c.orphans = append(c.orphans, post.Id)
}
}
}