Adding config and support for twitter
This commit is contained in:
parent
52940c7c92
commit
9101453bb7
32
cmd/db640bot/main.go
Normal file
32
cmd/db640bot/main.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/config"
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/twitter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := flag.String("c", "", "Config file")
|
||||
flag.Parse()
|
||||
if *cfg == "" {
|
||||
log.Fatalf("Config file must not be empty!")
|
||||
}
|
||||
|
||||
log.Println("Hello World!")
|
||||
|
||||
config.LoadConfig(*cfg)
|
||||
twitter.Init()
|
||||
stream, err := twitter.GetStreamForTag("#NationalPuppyDay")
|
||||
if err != nil {
|
||||
log.Fatalf("Could not establish twitter stream: %+v", err)
|
||||
}
|
||||
|
||||
twitter.StreamDemux(stream, showTweet)
|
||||
}
|
||||
|
||||
func showTweet(tweet *twitter.Tweet) {
|
||||
log.Printf("%s\n", tweet.Text)
|
||||
}
|
7
go.mod
7
go.mod
|
@ -2,4 +2,9 @@ module git.1750studios.com/ToddShepard/DB640
|
|||
|
||||
go 1.14
|
||||
|
||||
require github.com/jinzhu/gorm v1.9.12
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/dghubble/go-twitter v0.0.0-20190719072343-39e5462e111f
|
||||
github.com/dghubble/oauth1 v0.6.0
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
)
|
||||
|
|
19
go.sum
19
go.sum
|
@ -1,5 +1,17 @@
|
|||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dghubble/go-twitter v0.0.0-20190719072343-39e5462e111f h1:M2wB039zeS1/LZtN/3A7tWyfctiOBL4ty5PURBmDdWU=
|
||||
github.com/dghubble/go-twitter v0.0.0-20190719072343-39e5462e111f/go.mod h1:xfg4uS5LEzOj8PgZV7SQYRHbG7jPUnelEiaAVJxmhJE=
|
||||
github.com/dghubble/oauth1 v0.6.0 h1:m1yC01Ohc/eF38jwZ8JUjL1a+XHHXtGQgK+MxQbmSx0=
|
||||
github.com/dghubble/oauth1 v0.6.0/go.mod h1:8pFdfPkv/jr8mkChVbNVuJ0suiHe278BtWI4Tk1ujxk=
|
||||
github.com/dghubble/sling v1.3.0 h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=
|
||||
github.com/dghubble/sling v1.3.0/go.mod h1:XXShWaBWKzNLhu2OxikSNFrlsvowtz4kyRuXUG7oQKY=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
|
@ -7,6 +19,8 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
|
|||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
|
@ -17,6 +31,11 @@ github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
|||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
|
||||
|
|
58
internal/config/config.go
Normal file
58
internal/config/config.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
// Config main type
|
||||
type Config struct {
|
||||
Twitter Twitter
|
||||
}
|
||||
|
||||
// Twitter related config
|
||||
type Twitter struct {
|
||||
ConsumerKey string
|
||||
ConsumerSecret string
|
||||
AccessKey string
|
||||
AccessSecret string
|
||||
}
|
||||
|
||||
// C holds the loaded configuration
|
||||
var C Config
|
||||
|
||||
// LoadDefaults puts default values into C
|
||||
func LoadDefaults() {
|
||||
C.Twitter.AccessKey = "ACCESSKEY"
|
||||
C.Twitter.AccessSecret = "ACCESSSECRET"
|
||||
C.Twitter.ConsumerKey = "CONSUMERKEY"
|
||||
C.Twitter.ConsumerSecret = "CONSUMERSECRET"
|
||||
}
|
||||
|
||||
// LoadConfig loads the configuration from given path
|
||||
func LoadConfig(path string) error {
|
||||
_, err := toml.DecodeFile(path, &C)
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
log.Printf("Could not find file \"%s\", using defaults!", path)
|
||||
LoadDefaults()
|
||||
err = WriteConfig(path)
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteConfig writes the configuration to the given path
|
||||
func WriteConfig(path string) error {
|
||||
buf := new(bytes.Buffer)
|
||||
err := toml.NewEncoder(buf).Encode(C)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(path, buf.Bytes(), 0644)
|
||||
return err
|
||||
}
|
41
internal/config/config_test.go
Normal file
41
internal/config/config_test.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadConfigNonExistent(t *testing.T) {
|
||||
err := LoadConfig(filepath.Join("..", "..", "test", "data", "doesnotexist.toml"))
|
||||
if err != nil {
|
||||
t.Errorf("Cannot write defaults, error: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteConfig(t *testing.T) {
|
||||
C.Twitter.AccessKey = "§OneNiceKey"
|
||||
C.Twitter.AccessSecret = "SuperNiceSecret"
|
||||
C.Twitter.ConsumerKey = "ConsumeMe"
|
||||
C.Twitter.ConsumerSecret = "EatASecret"
|
||||
err := WriteConfig(filepath.Join("..", "..", "test", "data", "doesnotexist.toml"))
|
||||
if err != nil {
|
||||
t.Errorf("Could not write config, got error: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfig(t *testing.T) {
|
||||
C = Config{}
|
||||
err := LoadConfig(filepath.Join("..", "..", "test", "data", "doesnotexist.toml"))
|
||||
if err != nil {
|
||||
t.Errorf("Cannot read config, error: %+v", err)
|
||||
}
|
||||
if C.Twitter.AccessKey != "§OneNiceKey" || C.Twitter.AccessSecret != "SuperNiceSecret" || C.Twitter.ConsumerKey != "ConsumeMe" || C.Twitter.ConsumerSecret != "EatASecret" {
|
||||
t.Errorf("Could not read config, entries wrong")
|
||||
}
|
||||
t.Cleanup(CleanupConfigTest)
|
||||
}
|
||||
|
||||
func CleanupConfigTest() {
|
||||
os.Remove(filepath.Join("..", "..", "test", "data", "doesnotexist.toml"))
|
||||
}
|
38
internal/twitter/twitter.go
Normal file
38
internal/twitter/twitter.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package twitter
|
||||
|
||||
import (
|
||||
"git.1750studios.com/ToddShepard/DB640/internal/config"
|
||||
"github.com/dghubble/go-twitter/twitter"
|
||||
"github.com/dghubble/oauth1"
|
||||
)
|
||||
|
||||
// Client holds the authenticated twitter client
|
||||
var Client *twitter.Client
|
||||
|
||||
// Tweet as in twitter.Tweet
|
||||
type Tweet = twitter.Tweet
|
||||
|
||||
// Init initzializes the twitter client
|
||||
func Init() {
|
||||
conf := oauth1.NewConfig(config.C.Twitter.ConsumerKey, config.C.Twitter.ConsumerSecret)
|
||||
token := oauth1.NewToken(config.C.Twitter.AccessKey, config.C.Twitter.AccessSecret)
|
||||
httpClient := conf.Client(oauth1.NoContext, token)
|
||||
|
||||
Client = twitter.NewClient(httpClient)
|
||||
}
|
||||
|
||||
// GetStreamForTag returns a stream object for a specified hashtag
|
||||
func GetStreamForTag(hashtag string) (*twitter.Stream, error) {
|
||||
params := &twitter.StreamFilterParams{
|
||||
Track: []string{hashtag},
|
||||
StallWarnings: twitter.Bool(true),
|
||||
}
|
||||
return Client.Streams.Filter(params)
|
||||
}
|
||||
|
||||
// StreamDemux sets callback for incoming messages
|
||||
func StreamDemux(stream *twitter.Stream, cb func(*Tweet)) {
|
||||
demux := twitter.NewSwitchDemux()
|
||||
demux.Tweet = cb
|
||||
demux.HandleChan(stream.Messages)
|
||||
}
|
Loading…
Reference in a new issue