Support visibility filtering using flag

This commit is contained in:
Gabriel Garrido 2024-05-19 21:29:36 +02:00
parent 47faaf7a27
commit 24627da0d2
4 changed files with 25 additions and 13 deletions

View file

@ -45,7 +45,8 @@ Usage of mastodon-markdown-archive:
Thread replies for a post in a single file Thread replies for a post in a single file
-user string -user string
URL of Mastodon account whose toots will be fetched URL of Mastodon account whose toots will be fetched
-visibility string
Filter out posts whose visibility does not match the passed visibility value
``` ```
## Example ## Example

View file

@ -6,6 +6,11 @@ import (
"strings" "strings"
) )
type ClientOptions struct {
Visibility string
Threaded bool
}
type Client struct { type Client struct {
handle string handle string
baseURL string baseURL string
@ -19,7 +24,8 @@ type Client struct {
// Map of Post.Id:*Post. // Map of Post.Id:*Post.
postIdMap map[string]*Post postIdMap map[string]*Post
// List of Post.Id. Tracks the posts which will be written as individual files. // List of Post.Id. Tracks the posts which will be written as individual files.
output []string output []string
options ClientOptions
} }
type PostsFilter struct { type PostsFilter struct {
@ -31,7 +37,7 @@ type PostsFilter struct {
MaxId string MaxId string
} }
func New(userURL string, filters PostsFilter, threaded bool) (Client, error) { func New(userURL string, filters PostsFilter, opts ClientOptions) (Client, error) {
var client Client var client Client
parsedURL, err := url.Parse(userURL) parsedURL, err := url.Parse(userURL)
@ -63,7 +69,7 @@ func New(userURL string, filters PostsFilter, threaded bool) (Client, error) {
for i := range posts { for i := range posts {
post := posts[i] post := posts[i]
postIdMap[post.Id] = &post postIdMap[post.Id] = &post
if !threaded { if !opts.Threaded && !post.ShouldSkip(opts.Visibility) {
output = append(output, post.Id) output = append(output, post.Id)
} }
} }
@ -77,9 +83,10 @@ func New(userURL string, filters PostsFilter, threaded bool) (Client, error) {
replies: replies, replies: replies,
orphans: orphans, orphans: orphans,
output: output, output: output,
options: opts,
} }
if threaded { if opts.Threaded {
for _, post := range posts { for _, post := range posts {
client.threadPost(post.Id) client.threadPost(post.Id)
} }
@ -154,7 +161,7 @@ func (c *Client) flushReplies(post *Post, descendants *[]*Post) {
func (c *Client) threadPost(postId string) { func (c *Client) threadPost(postId string) {
post := c.postIdMap[postId] post := c.postIdMap[postId]
if post.InReplyToId == "" { if post.InReplyToId == "" && !post.ShouldSkip(c.options.Visibility) {
c.flushReplies(post, &post.descendants) c.flushReplies(post, &post.descendants)
c.output = append(c.output, post.Id) c.output = append(c.output, post.Id)
return return

View file

@ -57,8 +57,12 @@ type Post struct {
descendants []*Post descendants []*Post
} }
func (p Post) ShouldSkip() bool { func (p Post) ShouldSkip(visibility string) bool {
return p.Visibility != "public" if visibility == "" {
return false
}
return p.Visibility != visibility
} }
func (p Post) Descendants() []*Post { func (p Post) Descendants() []*Post {

10
main.go
View file

@ -27,6 +27,7 @@ func main() {
filenameTemplate := flag.String("filename", "", "Template for post filename") filenameTemplate := flag.String("filename", "", "Template for post filename")
porcelain := flag.Bool("porcelain", false, "Prints the amount of fetched posts to stdout in a parsable manner") porcelain := flag.Bool("porcelain", false, "Prints the amount of fetched posts to stdout in a parsable manner")
downloadMedia := flag.String("download-media", "", "Download media in a post. Omit or pass an empty string to not download media. Pass 'bundle' to download the media inline in a single directory with its original post. Pass a path to a directory to download all media there.") downloadMedia := flag.String("download-media", "", "Download media in a post. Omit or pass an empty string to not download media. Pass 'bundle' to download the media inline in a single directory with its original post. Pass a path to a directory to download all media there.")
visibility := flag.String("visibility", "", "Filter out posts whose visibility does not match the passed visibility value")
flag.Parse() flag.Parse()
@ -37,7 +38,10 @@ func main() {
SinceId: *sinceId, SinceId: *sinceId,
MaxId: *maxId, MaxId: *maxId,
MinId: *minId, MinId: *minId,
}, *threaded) }, client.ClientOptions{
Threaded: *threaded,
Visibility: *visibility,
})
if err != nil { if err != nil {
log.Panicln(err) log.Panicln(err)
@ -58,10 +62,6 @@ func main() {
} }
for _, post := range posts { for _, post := range posts {
if post.ShouldSkip() {
continue
}
if err := fileWriter.Write(post); err != nil { if err := fileWriter.Write(post); err != nil {
log.Panicln("error writing post to file: %w", err) log.Panicln("error writing post to file: %w", err)
} }