all repos — flounder @ 031adfa17fdf386a44b9756dc845345672cfcadc

A small site builder for the Gemini protocol

feed.go (view raw)

  1package main
  2
  3import (
  4	"bufio"
  5	"fmt"
  6	"github.com/mmcdole/gofeed"
  7	"log"
  8	"os"
  9	"path"
 10	"sort"
 11	"time"
 12)
 13
 14const followingPath = "following.txt"
 15const followingFile = "following.gmi"
 16
 17// TODO also get gemini, gemfeed
 18
 19func feedsWorker() {
 20	log.Println("Starting feeds worker")
 21	for {
 22		users, err := getActiveUserNames()
 23		if err != nil {
 24			// Handle error somehow
 25			fmt.Println(err)
 26			continue
 27		}
 28		for _, user := range users {
 29			writeAllFeeds(user)
 30		}
 31		time.Sleep(time.Hour * 1)
 32	}
 33}
 34
 35func writeAllFeeds(user string) error {
 36	// Open file
 37	file, err := os.Open(path.Join(getUserDirectory(user), followingPath))
 38	if err != nil {
 39		if os.IsNotExist(err) {
 40			// TODO
 41			return nil
 42		}
 43		return err
 44	}
 45	log.Println("Writing feeds for user " + user)
 46	defer file.Close()
 47
 48	feedData := []*gofeed.Feed{}
 49	scanner := bufio.NewScanner(file)
 50	for scanner.Scan() {
 51		feedURL := scanner.Text()
 52		// TODO if scheme is gemini and filetype is gemini... gemtext
 53		// TODO if scheme is gemini and filetype is xml/rss... fetch data  and parse
 54		// TODO rate limit etc
 55		fp := gofeed.NewParser()
 56		feed, err := fp.ParseURL(feedURL)
 57		if err != nil {
 58			log.Println("Error getting feed " + feedURL)
 59		} else {
 60			log.Println("Got feed data from " + feedURL)
 61			feedData = append(feedData, feed)
 62		}
 63	}
 64	if err := scanner.Err(); err != nil {
 65		return err
 66	}
 67	// Aggregate and sort by date
 68	type feedPlusItem struct {
 69		Feed     *gofeed.Feed
 70		FeedItem *gofeed.Item
 71		Date     string
 72	}
 73	data := struct {
 74		User      string
 75		FeedItems []feedPlusItem
 76	}{}
 77	data.User = user
 78	for _, feed := range feedData {
 79		for _, item := range feed.Items {
 80			if item.UpdatedParsed == nil {
 81				item.UpdatedParsed = item.PublishedParsed
 82			}
 83			if item.UpdatedParsed != nil {
 84				date := item.UpdatedParsed.Format("2006-01-02")
 85				data.FeedItems = append(data.FeedItems, feedPlusItem{feed, item, date})
 86			}
 87		}
 88	}
 89	sort.Slice(data.FeedItems, func(i, j int) bool {
 90		return data.FeedItems[i].FeedItem.UpdatedParsed.After(*data.FeedItems[j].FeedItem.UpdatedParsed)
 91	})
 92
 93	outputf, err := os.OpenFile(path.Join(getUserDirectory(user), followingFile), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
 94	if err != nil {
 95		return err
 96	}
 97	err = gt.ExecuteTemplate(outputf, "following.gmi", data)
 98	if err != nil {
 99		return err
100	}
101	defer outputf.Close()
102	// convert to gemini template
103	// write template to file
104	return nil
105}