2024-04-21 13:08:09 +00:00
package main
import (
"flag"
"fmt"
"log"
2024-04-21 17:51:55 +00:00
"os"
2024-05-11 16:03:35 +00:00
"path/filepath"
"git.garrido.io/gabriel/mastodon-markdown-archive/client"
"git.garrido.io/gabriel/mastodon-markdown-archive/files"
2024-04-21 13:08:09 +00:00
)
func main ( ) {
2024-04-21 18:10:25 +00:00
dist := flag . String ( "dist" , "./posts" , "Path to directory where files will be written" )
2024-05-19 16:09:28 +00:00
user := flag . String ( "user" , "" , "URL of Mastodon account whose toots will be fetched" )
2024-05-19 20:17:10 +00:00
excludeReplies := flag . Bool ( "exclude-replies" , false , "Mastodon API parameter: Filter out statuses in reply to a different account" )
excludeReblogs := flag . Bool ( "exclude-reblogs" , false , "Mastodon API parameter: Filter out boosts from the response" )
limit := flag . Int ( "limit" , 40 , "Mastodon API parameter: Maximum number of results to return. Defaults to 20 statuses. Max 40 statuses" )
onlyMedia := flag . Bool ( "only-media" , false , "Mastodon API parameter: Filter out status without attachments" )
pinned := flag . Bool ( "pinned" , false , "Mastodon API parameter: Filter for pinned statuses only" )
sinceId := flag . String ( "since-id" , "" , "Mastodon API parameter: All results returned will be greater than this ID. In effect, sets a lower bound on results." )
maxId := flag . String ( "max-id" , "" , "Mastodon API parameter: All results returned will be lesser than this ID. In effect, sets an upper bound on results." )
minId := flag . String ( "min-id" , "" , "Mastodon API parameter: Returns results immediately newer than this ID. In effect, sets a cursor at this ID and paginates forward." )
tagged := flag . String ( "tagged" , "" , "Mastodon API parameter: Filter for statuses using a specific hashtag" )
2024-05-11 16:03:35 +00:00
persistFirst := flag . String ( "persist-first" , "" , "Location to persist the post id of the first post returned" )
persistLast := flag . String ( "persist-last" , "" , "Location to persist the post id of the last post returned" )
2024-05-11 17:34:57 +00:00
templateFile := flag . String ( "template" , "" , "Template to use for post rendering, if passed" )
2024-05-19 15:46:14 +00:00
threaded := flag . Bool ( "threaded" , false , "Thread replies for a post in a single file" )
2024-05-19 13:00:55 +00:00
filenameTemplate := flag . String ( "filename" , "" , "Template for post filename" )
2024-05-19 14:02:51 +00:00
porcelain := flag . Bool ( "porcelain" , false , "Prints the amount of fetched posts to stdout in a parsable manner" )
2024-05-19 20:17:10 +00:00
downloadMedia := flag . String ( "download-media" , "" , "Path where post attachments will be downloaded. Omit to skip downloading attachments." )
2024-05-19 19:29:36 +00:00
visibility := flag . String ( "visibility" , "" , "Filter out posts whose visibility does not match the passed visibility value" )
2024-04-21 13:08:09 +00:00
flag . Parse ( )
2024-05-18 13:22:23 +00:00
c , err := client . New ( * user , client . PostsFilter {
2024-04-21 17:15:36 +00:00
ExcludeReplies : * excludeReplies ,
ExcludeReblogs : * excludeReblogs ,
Limit : * limit ,
SinceId : * sinceId ,
2024-04-21 18:10:25 +00:00
MaxId : * maxId ,
MinId : * minId ,
2024-05-19 20:17:10 +00:00
OnlyMedia : * onlyMedia ,
Pinned : * pinned ,
2024-08-03 06:33:33 +00:00
Tagged : * tagged ,
2024-05-19 19:29:36 +00:00
} , client . ClientOptions {
Threaded : * threaded ,
Visibility : * visibility ,
} )
2024-04-21 13:08:09 +00:00
if err != nil {
log . Panicln ( err )
}
2024-05-19 17:05:39 +00:00
fileWriter , err := files . New ( * dist , * templateFile , * filenameTemplate , * downloadMedia )
2024-05-18 13:22:23 +00:00
posts := c . Posts ( )
postsCount := len ( posts )
2024-04-21 16:12:13 +00:00
2024-05-19 14:02:51 +00:00
if * porcelain {
fmt . Println ( postsCount )
} else {
log . Println ( fmt . Sprintf ( "Fetched %d posts" , postsCount ) )
}
if postsCount == 0 {
return
}
2024-04-21 17:51:55 +00:00
2024-04-21 13:08:09 +00:00
for _ , post := range posts {
2024-05-19 13:11:53 +00:00
if err := fileWriter . Write ( post ) ; err != nil {
2024-04-21 17:15:36 +00:00
log . Panicln ( "error writing post to file: %w" , err )
}
2024-04-21 13:08:09 +00:00
}
2024-04-21 17:51:55 +00:00
2024-05-19 14:02:51 +00:00
if * persistFirst != "" {
firstPost := posts [ 0 ]
err := persistId ( firstPost . Id , * persistFirst )
2024-05-11 16:03:35 +00:00
2024-05-19 14:02:51 +00:00
if err != nil {
log . Panicln ( err )
2024-05-11 16:03:35 +00:00
}
2024-05-19 14:02:51 +00:00
}
2024-05-11 16:03:35 +00:00
2024-05-19 14:02:51 +00:00
if * persistLast != "" {
lastPost := posts [ postsCount - 1 ]
err := persistId ( lastPost . Id , * persistLast )
2024-05-11 16:03:35 +00:00
2024-05-19 14:02:51 +00:00
if err != nil {
log . Panicln ( err )
2024-05-11 16:03:35 +00:00
}
}
}
func persistId ( postId string , path string ) error {
persistPath , err := filepath . Abs ( path )
2024-04-21 17:51:55 +00:00
2024-05-11 16:03:35 +00:00
if err != nil {
return err
}
if err := os . WriteFile ( persistPath , [ ] byte ( postId ) , 0644 ) ; err != nil {
return err
2024-04-21 17:51:55 +00:00
}
2024-05-11 16:03:35 +00:00
return nil
2024-04-21 13:08:09 +00:00
}