add skipping posted posts

Amolith created

Change summary

main.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 68 insertions(+), 15 deletions(-)

Detailed changes

main.go 🔗

@@ -27,6 +27,8 @@ var (
 	flagAuthenticate *bool   = flag.BoolP("authenticate", "a", false, "Authenticate with the server")
 	flagInstance     *string = flag.StringP("instance", "i", "", "Instance to post to (required)")
 	flagTagsSkip     *string = flag.StringP("tagsskip", "T", "", "Particular tags to skip (optional)")
+	flagPostIDs      *bool   = flag.BoolP("postids", "p", false, "Print all post IDs, necessary for skipping old posts (optional)")
+	flagSkip         *string = flag.StringP("skipids", "I", "ids.txt", "Path to file containing post IDs to skip (optional)")
 )
 
 type post struct {
@@ -47,25 +49,47 @@ func main() {
 	fp := gofeed.NewParser()
 	feed, _ := fp.ParseURL(*flagFeed)
 
+	if *flagPostIDs {
+		for i := range feed.Items {
+			fmt.Println(feed.Items[i].GUID)
+		}
+		os.Exit(0)
+	}
+
+	// If *flagSkip doesn't exist, create it
+	if _, err := os.Stat(*flagSkip); os.IsNotExist(err) {
+		f, err := os.Create(*flagSkip)
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+		f.Close()
+	}
+
+	f, err := os.ReadFile(*flagSkip)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
 	skippedTags := strings.Split(*flagTagsSkip, ",")
 	skippedTagsMap := make(map[string]int)
 	for i := range skippedTags {
 		skippedTagsMap[skippedTags[i]] = 0
 	}
 
-	// TODO: Add feed.Title to categories so there's always at least one
-
 	i := 0
+	c := false
 	if feed.Items[i].Categories != nil {
 		for i = range feed.Items {
 			if feed.Items[i].Categories == nil {
 				feed.Items[i].Categories = []string{feed.Title}
-				break
 			}
-			c := false
+			c = false
 			tags := strings.Split(feed.Items[i].Categories[0], "/")
 			for _, tag := range tags {
-				if _, ok := skippedTagsMap[tag]; ok {
+				_, ok := skippedTagsMap[tag]
+				if ok || bytes.Contains(f, []byte(feed.Items[i].GUID)) {
 					c = true
 					break
 				}
@@ -79,6 +103,11 @@ func main() {
 		feed.Items[i].Categories = []string{feed.Title}
 	}
 
+	if c {
+		fmt.Println("No new posts")
+		os.Exit(0)
+	}
+
 	post := post{}
 
 	tags := strings.Split(feed.Items[i].Categories[0], "/")
@@ -151,7 +180,24 @@ func main() {
 	}
 	respMap := make(map[string]string)
 	err = json.Unmarshal(respData, &respMap)
-	fmt.Println(respMap["url"])
+	url, ok := respMap["url"]
+	if ok {
+		// Write the post ID to the skip file
+		f, err := os.OpenFile(*flagSkip, os.O_APPEND|os.O_WRONLY, 0o644)
+		if err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+		defer f.Close()
+
+		if _, err := f.WriteString(feed.Items[i].GUID + "\n"); err != nil {
+			fmt.Println(err)
+			os.Exit(1)
+		}
+		fmt.Println("Posted to", url)
+	} else {
+		fmt.Println(string(respData))
+	}
 }
 
 func extractText(node *html.Node) string {
@@ -243,29 +289,36 @@ func validateFlags() {
 	if *flagAuthenticate {
 		authenticate()
 	}
-	// Ensure the token is set
+	if *flagFeed == "" {
+		flag.Usage()
+		fmt.Println("No feed URL specified")
+		os.Exit(1)
+	}
+	if *flagPostIDs {
+		return
+	}
 	if os.Getenv("RSS2FEDI_TOKEN") == "" {
 		fmt.Println("No token set! Please run with the -a/--authenticate flag to obtain one.")
 		os.Exit(1)
 	}
-	if *flagFeed == "" {
-		flag.Usage()
-		panic("No feed URL specified")
-	}
 	if *flagTemplate == "" {
 		flag.Usage()
-		panic("No template file specified")
+		fmt.Println("No template file specified")
+		os.Exit(1)
 	}
 	if *flagVisibility == "" {
 		flag.Usage()
-		panic("No visibility specified")
+		fmt.Println("No visibility specified")
+		os.Exit(1)
 	}
 	if *flagInstance == "" {
 		flag.Usage()
-		panic("No instance specified")
+		fmt.Println("No instance specified")
+		os.Exit(1)
 	}
 	if *flagVisibility != "public" && *flagVisibility != "unlisted" && *flagVisibility != "private" && *flagVisibility != "direct" {
 		flag.Usage()
-		panic("Invalid visibility specified")
+		fmt.Println("Invalid visibility specified")
+		os.Exit(1)
 	}
 }