Bläddra i källkod

Add multiple account support

Matthew Jorgensen 5 år sedan
förälder
incheckning
6f0f4b1bf1
2 ändrade filer med 116 tillägg och 62 borttagningar
  1. 6 1
      config.go
  2. 110 61
      gof.go

+ 6 - 1
config.go

@@ -19,13 +19,18 @@ type feed struct {
 }
 
 type config struct {
+	Accounts    []Account
+	LastUpdated time.Time
+}
+
+// An Account holds the information required to use that account.
+type Account struct {
 	ClientID     string
 	ClientSecret string
 	AccessToken  string
 	Name         string
 	InstanceURL  string
 	Feeds        []feed
-	LastUpdated  time.Time
 }
 
 func readConfig() *config {

+ 110 - 61
gof.go

@@ -2,97 +2,146 @@ package main
 
 import (
 	"bytes"
+	"io"
 	"log"
+	"net/http"
 	"net/url"
+	"strings"
 	"text/template"
+	"time"
 
 	"github.com/SlyMarbo/rss"
 )
 
+var (
+	conf *config
+)
+
 type article struct {
 	Title, URL, Summary string
 }
 
 func main() {
 	log.Println("gof starting up...")
-	config := readConfig()
+	conf = readConfig()
+	log.Print(conf.Accounts)
 
 	var tpls = make(map[string]*template.Template)
-	for _, f := range config.Feeds {
-		tmpl, err := template.New(f.URL).Parse(f.Template)
-		if err != nil {
-			log.Fatalf("Failed to parse template [%s]. Error: %s", f.Template, err.Error())
-		}
-		tpls[f.URL] = tmpl
-	}
-
-	// Get feeds
-	log.Println("Fetching feeds...")
-	var feeds []*rss.Feed
-	for _, source := range config.Feeds {
-		feed, err := rss.Fetch(source.URL)
-		if err != nil {
-			log.Printf("Error fetching %s: %s", source.URL, err.Error())
-			continue
+	for _, a := range conf.Accounts {
+		for _, f := range a.Feeds {
+			tmpl, err := template.New(f.URL).Parse(f.Template)
+			if err != nil {
+				log.Fatalf("Failed to parse template [%s]. Error: %s", f.Template, err.Error())
+			}
+			tpls[f.URL] = tmpl
 		}
-		feeds = append(feeds, feed)
-		log.Printf("Fetched %s", feed.Title)
-	}
-	if len(feeds) == 0 {
-		log.Fatal("Expected at least one feed to successfully fetch.")
 	}
 
-	// Loop through feeds
-	for _, feed := range feeds {
-		// Get feed items
-		if len(feed.Items) == 0 {
-			log.Printf("Warning: feed %s has no items.", feed.Title)
-			continue
-		}
-		items := feed.Items
-		if len(items) > 1 {
-			items = items[:1]
-		}
-		base, err := url.Parse(feed.UpdateURL)
-		if err != nil {
-			log.Fatal("failed parsing update URL of the feed")
+	for _, account := range conf.Accounts {
+		// Get feeds
+		log.Println("Fetching feeds...")
+		var feeds []*rss.Feed
+		for _, source := range account.Feeds {
+			feed, err := rss.Fetch(source.URL)
+			if err != nil {
+				log.Printf("Error fetching %s: %s", source.URL, err.Error())
+				continue
+			}
+			feeds = append(feeds, feed)
+			log.Printf("Fetched %s", feed.Title)
 		}
-		feedLink, _ := url.Parse(feed.Link)
-		if err != nil {
-			log.Fatal("failed parsing canonical feed URL of the feed")
+		if len(feeds) == 0 {
+			log.Fatal("Expected at least one feed to successfully fetch.")
 		}
 
-		// Loop through items
-		for _, item := range items {
-			if item.Date.Before(config.LastUpdated) {
-				log.Println("No new items. Skipping.")
+		// Loop through feeds
+		for _, feed := range feeds {
+			// Get feed items
+			if len(feed.Items) == 0 {
+				log.Printf("Warning: feed %s has no items.", feed.Title)
 				continue
 			}
-			itemLink, err := url.Parse(item.Link)
-			if err != nil {
-				log.Fatal("failed parsing article URL of the feed item")
+			items := feed.Items
+			if len(items) > 1 {
+				items = items[:1]
 			}
-
-			// Make sure data looks OK
-			// TODO: remove before release
-			log.Printf("Item Data:\n\tTimestamp: %s\n\tSite URL: %s\n\tFeed Title: %s\n\tItem Title: %s\n\tItem URL: %s\n",
-				item.Date, base.ResolveReference(feedLink).String(),
-				feed.Title, item.Title, base.ResolveReference(itemLink).String())
-			i := article{
-				Title: item.Title,
-				URL:   base.ResolveReference(itemLink).String(),
+			base, err := url.Parse(feed.UpdateURL)
+			if err != nil {
+				log.Fatal("failed parsing update URL of the feed")
 			}
-			buf := new(bytes.Buffer)
-			err = tpls[base.String()].Execute(buf, i)
+			feedLink, _ := url.Parse(feed.Link)
 			if err != nil {
-				log.Fatalf("Error executing template [%s]. Error: %s", tpls[base.String()], err.Error())
+				log.Fatal("failed parsing canonical feed URL of the feed")
+			}
+
+			// Loop through items
+			for _, item := range items {
+				if item.Date.Before(conf.LastUpdated) {
+					log.Println("No new items. Skipping.")
+					continue
+				}
+				itemLink, err := url.Parse(item.Link)
+				if err != nil {
+					log.Fatal("failed parsing article URL of the feed item")
+				}
+
+				// Make sure data looks OK
+				// TODO: remove before release
+				log.Printf("Item Data:\n\tTimestamp: %s\n\tSite URL: %s\n\tFeed Title: %s\n\tItem Title: %s\n\tItem URL: %s\n",
+					item.Date, base.ResolveReference(feedLink).String(),
+					feed.Title, item.Title, base.ResolveReference(itemLink).String())
+				i := article{
+					Title: item.Title,
+					URL:   base.ResolveReference(itemLink).String(),
+				}
+				buf := new(bytes.Buffer)
+				err = tpls[base.String()].Execute(buf, i)
+				if err != nil {
+					log.Fatalf("Error executing template [%s]. Error: %s", tpls[base.String()], err.Error())
+				}
+				if err = postMessage(account, buf.String()); err != nil {
+					log.Fatalf("Failed to post message \"%s\". Error: %s", buf.String(), err.Error())
+				}
+
 			}
-			log.Println("Message: ", buf.String())
 		}
 	}
 
 	// update timestamp in config
-	config.updateLastUpdated()
+	conf.updateLastUpdated()
 	// save config
-	config.Save()
+	conf.Save()
+}
+
+func postMessage(account Account, message string) error {
+	apiURL := account.InstanceURL + "/api/v1/statuses"
+
+	data := url.Values{}
+	data.Set("status", message)
+	data.Set("visibility", "unlisted")
+
+	var req *http.Request
+	var body io.Reader
+	body = strings.NewReader(data.Encode())
+
+	req, err := http.NewRequest("POST", apiURL, body)
+	if err != nil {
+		return err
+	}
+
+	// Set Headers
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+	req.Header.Set("Authorization", "Bearer "+account.AccessToken)
+
+	c := &http.Client{Timeout: time.Second * 10}
+
+	resp, err := c.Do(req)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+
+	log.Println("response Status: ", resp.Status)
+
+	return nil
 }