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" )
excludeReplies := flag . Bool ( "exclude-replies" , false , "Exclude replies to other users" )
excludeReblogs := flag . Bool ( "exclude-reblogs" , false , "Exclude reblogs" )
2024-04-21 17:15:36 +00:00
limit := flag . Int ( "limit" , 40 , "Maximum number of posts to fetch" )
2024-04-21 18:10:25 +00:00
sinceId := flag . String ( "since-id" , "" , "Fetch posts greater than this id" )
2024-05-19 16:09:28 +00:00
maxId := flag . String ( "max-id" , "" , "Fetch posts older than this id" )
minId := flag . String ( "min-id" , "" , "Fetch posts newer than this id" )
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 17:05:39 +00:00
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." )
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 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
}