Skip to content

Commit

Permalink
plugin: add golang_news plugin
Browse files Browse the repository at this point in the history
This is a rather big deal.
  • Loading branch information
haarts committed Mar 3, 2017
1 parent 8901af4 commit 3641016
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 51 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
settings.json
golang_news
!plugins/*
*.so
100 changes: 49 additions & 51 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,82 +1,80 @@
package main

import (
"fmt"
"log"
"os"
"regexp"
"plugin"
"reflect"

"github.com/SlyMarbo/rss"
)

type Feed struct {
URL string
ItemHandler func(*rss.Item) string
}

func main() {
log.SetOutput(os.Stdout)
log.Println("Starting")

feeds, err := feeds()
if err != nil {
return
}
tweets := make(chan string)

go pollFeeds(tweets)
go pollFeeds(tweets, feeds)
postTweets(tweets)
}

func pollFeeds(publishTweet chan string) {
// variable number of select/case: https://play.golang.org/p/8zwvSk4kjx
blogItems := make(chan *rss.Item)
hnItems := make(chan *rss.Item)
redditItems := make(chan *rss.Item)
func feeds() ([]Feed, error) {
p, err := plugin.Open(os.Args[1])
if err != nil {
log.Printf("Error reading plugin: %s", err)
return nil, err
}
listFunc, err := p.Lookup("List")
if err != nil {
log.Printf("Error looking up 'List': %s", err)
return nil, err
}

go poller("https://blog.golang.org/feed.atom", blogItems)
go poller("https://news.ycombinator.com/rss", hnItems)
go poller("https://www.reddit.com/r/golang.rss", redditItems)
return listFunc.(func() []Feed)(), nil
}

for {
select {
case item := <-blogItems:
publishTweet <- blogItem(item)
case item := <-hnItems:
publishTweet <- hnItem(item)
case item := <-redditItems:
publishTweet <- redditItem(item)
}
func pollFeeds(publishTweet chan string, feeds []Feed) {
itemProducers := []chan *rss.Item{}
for _, feed := range feeds {
itemProducer := make(chan *rss.Item)
itemProducers = append(itemProducers, itemProducer)
go poller(feed.URL, itemProducer)
}
}

func postTweets(tweets chan string) {
for tweet := range tweets {
if tweet != "" {
PostTweet(tweet)
}
cases := make([]reflect.SelectCase, len(itemProducers))
for i, ch := range itemProducers {
cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
}
}

func hnItem(item *rss.Item) string {
if match, _ := regexp.MatchString(`\w Go( |$|\.)`, item.Title); match {
short_title := item.Title
if len(short_title) > 100 {
short_title = short_title[:99] + "…"
activeItemProducers := len(cases)
for activeItemProducers > 0 {
chosen, value, ok := reflect.Select(cases)
if !ok {
// The chosen channel has been closed, so zero out the channel to disable the case
cases[chosen].Chan = reflect.ValueOf(nil)
activeItemProducers -= 1
continue
}
return short_title + " " + item.Link + " #hackernews"
} else {
log.Printf("Ignoring Hackernews item: %s", item.Title)
return ""
}
}

func blogItem(item *rss.Item) string {
short_title := item.Title
if len(short_title) > 100 {
short_title = short_title[:99] + "…"
fmt.Printf("Read from channel %#v and received %s\n", itemProducers[chosen], value.String())
}
return short_title + " " + "https:" + item.Link + " #go_blog"
}

func redditItem(item *rss.Item) string {
re := regexp.MustCompile(`([^"]+)">\[link\]`)
matches := re.FindStringSubmatch(item.Content)
if len(matches) == 2 {
short_title := item.Title
if len(short_title) > 100 {
short_title = short_title[:99] + "…"
func postTweets(tweets chan string) {
for tweet := range tweets {
if tweet != "" {
PostTweet(tweet)
}
return short_title + " " + matches[1] + " #reddit"
}
return ""
}
66 changes: 66 additions & 0 deletions plugins/golang_news/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"log"
"regexp"

"C"

"github.com/SlyMarbo/rss"
)

type Feed struct {
URL string
ItemHandler func(*rss.Item) string
}

func List() []Feed {
return []Feed{
Feed{
URL: "https://blog.golang.org/feed.atom",
ItemHandler: blogItem,
},
Feed{
URL: "https://news.ycombinator.com/rss",
ItemHandler: hnItem,
},
Feed{
URL: "https://www.reddit.com/r/golang.rss",
ItemHandler: redditItem,
},
}
}

func hnItem(item *rss.Item) string {
if match, _ := regexp.MatchString(`\w Go( |$|\.)`, item.Title); match {
short_title := item.Title
if len(short_title) > 100 {
short_title = short_title[:99] + "…"
}
return short_title + " " + item.Link + " #hackernews"
} else {
log.Printf("Ignoring Hackernews item: %s", item.Title)
return ""
}
}

func blogItem(item *rss.Item) string {
short_title := item.Title
if len(short_title) > 100 {
short_title = short_title[:99] + "…"
}
return short_title + " " + "https:" + item.Link + " #go_blog"
}

func redditItem(item *rss.Item) string {
re := regexp.MustCompile(`([^"]+)">\[link\]`)
matches := re.FindStringSubmatch(item.Content)
if len(matches) == 2 {
short_title := item.Title
if len(short_title) > 100 {
short_title = short_title[:99] + "…"
}
return short_title + " " + matches[1] + " #reddit"
}
return ""
}

0 comments on commit 3641016

Please sign in to comment.