Skip to content

Commit

Permalink
Refactor to add providers
Browse files Browse the repository at this point in the history
  • Loading branch information
ezeoleaf committed May 13, 2021
1 parent 23bea56 commit 39cb2f2
Show file tree
Hide file tree
Showing 15 changed files with 467 additions and 409 deletions.
5 changes: 4 additions & 1 deletion cache.go → cache/cache.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package main
package cache

import (
"context"
"time"

"github.com/go-redis/redis/v8"
)

var ctx = context.Background()

// Repository represent the repositories
type Repository interface {
Set(key string, value interface{}, exp time.Duration) error
Expand Down
2 changes: 1 addition & 1 deletion cache_test.go → cache/cache_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package cache

import (
"testing"
Expand Down
4 changes: 2 additions & 2 deletions config.go → config/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package config

import (
"context"
Expand All @@ -24,6 +24,7 @@ type Config struct {
CacheSize int
TweetLanguage bool
SafeMode bool
Provider string
}

// AccessConfig is a struct that contains configuration for the clients
Expand All @@ -33,7 +34,6 @@ type AccessConfig struct {
TwitterConsumerSecret string `json:"twitter_consumer_secret"`
TwitterAccessToken string `json:"twitter_access_token"`
TwitterAccessSecret string `json:"twitter_access_secret"`
DevMode bool `json:"dev_mode"` //If DevMode is true then it wont post any tweet //TODO: Move to arg as safe mode
}

// SetConfigAccess reads a configuration file and unmarshall to struct
Expand Down
4 changes: 2 additions & 2 deletions config_test.go → config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package config

import (
"testing"
Expand All @@ -13,7 +13,7 @@ func TestSetConfigAccessNoFile(t *testing.T) {
}

func TestSetConfigAccessValidFile(t *testing.T) {
mockConfig := Config{ConfigFile: "./config.example.json"}
mockConfig := Config{ConfigFile: "../config.example.json"}
e := mockConfig.SetConfigAccess()
if e != nil {
t.Errorf("Expected nil, got %s", e)
Expand Down
14 changes: 12 additions & 2 deletions flags.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package main

import "github.com/urfave/cli/v2"
import (
"github.com/ezeoleaf/GobotTweet/config"
"github.com/urfave/cli/v2"
)

func getFlags(c *Config) []cli.Flag {
func getFlags(c *config.Config) []cli.Flag {
return []cli.Flag{
&cli.StringFlag{
Name: "topic",
Expand Down Expand Up @@ -60,5 +63,12 @@ func getFlags(c *Config) []cli.Flag {
Usage: "bool for safe mode. If safe mode is enabled, no repository is published",
Destination: &cfg.SafeMode,
},
&cli.StringFlag{
Name: "provider",
Aliases: []string{"pr"},
Value: "github",
Usage: "Provider where tweetable content comes from",
Destination: &cfg.Provider,
},
}
}
4 changes: 3 additions & 1 deletion flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package main

import (
"testing"

"github.com/ezeoleaf/GobotTweet/config"
)

func TestGetFlags(t *testing.T) {
mockConfig := Config{}
mockConfig := config.Config{}
flags := getFlags(&mockConfig)
if flags == nil {
t.Errorf("Expected flags, got %s", flags)
Expand Down
38 changes: 19 additions & 19 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
package main

import (
"context"
"log"
"os"
"time"

"github.com/go-redis/redis/v8"
"github.com/ezeoleaf/GobotTweet/config"
"github.com/ezeoleaf/GobotTweet/providers"
"github.com/ezeoleaf/GobotTweet/providers/github"
"github.com/urfave/cli/v2"
)

var rdb Repository
var ctx = context.Background()
var cfg Config
var cfg config.Config

func init() {
ro := &redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
}

rdb = NewRedisRepository(ro)

cfg = Config{}
cfg = config.Config{}
}

func main() {
app := &cli.App{
Name: "GobotTweet",
Usage: "Twitter bot that tweets random repositories",
Flags: getFlags(&cfg),
Name: "GobotTweet",
Usage: "Twitter bot that tweets random repositories",
Flags: getFlags(&cfg),
Authors: []*cli.Author{{Name: "Ezequiel Olea figueroa", Email: "[email protected]"}},
Action: func(c *cli.Context) error {
e := cfg.SetConfigAccess()
if e != nil {
panic(e)
}
for {
r := getRepo(cfg)
tweetRepo(cfg, r)
var provider providers.IContent
if cfg.Provider == providers.Github {
provider = github.NewGithubRepository(cfg)
}

if provider != nil {
content := provider.GetContentToPublish()
tweetContent(cfg, content)
}

time.Sleep(time.Duration(cfg.Periodicity) * time.Minute)
}
},
Expand Down
26 changes: 26 additions & 0 deletions providers/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package providers

type IContent interface {
GetContentToPublish() string
}

// Github is the value of the valid provider
const Github = "github"

var ValidProviders = []string{
Github,
}

func GetValidProvidersToString() string {
p := ""

for _, v := range ValidProviders {
if p != "" {
p += ", "
}

p += v
}

return "The valid providers are: " + p
}
18 changes: 18 additions & 0 deletions providers/const_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package providers

import "testing"

func TestConsts(t *testing.T) {
if Github != "github" {
t.Errorf("The github provider is wrong. Expected github got %s", Github)
}
}

func TestGetValidProvidersToString(t *testing.T) {
r := GetValidProvidersToString()
expected := "The valid providers are: " + Github

if r != expected {
t.Errorf("The provides are wrong. Expected: %s got %s", expected, r)
}
}
180 changes: 180 additions & 0 deletions providers/github/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package github

import (
"fmt"
"log"
"math/rand"
"strconv"
"time"

"github.com/ezeoleaf/GobotTweet/cache"
"github.com/ezeoleaf/GobotTweet/config"
"github.com/ezeoleaf/GobotTweet/providers"
"github.com/go-redis/redis/v8"
"github.com/google/go-github/github"
)

var repositories *github.RepositoriesSearchResult
var rdb cache.Repository
var cfg config.Config

// repository represent the repository model
type githubProvider struct {
Provider interface{}
}

func NewGithubRepository(config config.Config) providers.IContent {
cfg = config
ro := &redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
}

rdb = cache.NewRedisRepository(ro)

return &githubProvider{}
}

func (g *githubProvider) GetContentToPublish() string {
r := getRepo()
return getContent(r)
}

func getContent(repo *github.Repository) string {
hashtags, title, stargazers := "", "", ""

hs := cfg.GetHashtags()

if len(hs) == 0 {
if cfg.Topic != "" {
hashtags += "#" + cfg.Topic + " "
} else if cfg.Language != "" {
hashtags += "#" + cfg.Language + " "
} else if repo.Language != nil {
hashtags += "#" + *repo.Language + " "
}

hashtags += "#github" + "\n"
} else {
for _, h := range hs {
if hashtags != "" {
hashtags += " "
}
hashtags += h
}
hashtags += "\n"
}

if repo.Name != nil {
title += *repo.Name + ": "
}

if repo.Description != nil {
title += *repo.Description + "\n"
}

if cfg.TweetLanguage {
if repo.Language != nil {
title += "Lang: " + *repo.Language + "\n"
}
}

if repo.StargazersCount != nil {
stargazers += "⭐️ " + strconv.Itoa(*repo.StargazersCount) + "\n"
}

return title + stargazers + hashtags + *repo.HTMLURL
}

func getRepositories() ([]github.Repository, int) {
if repositories == nil {
ctx, client := cfg.AccessCfg.GetGithubClient()

var e error
var qs string

if cfg.Topic != "" {
qs = fmt.Sprintf("topic:%s", cfg.Topic)
} else {
qs = fmt.Sprintf("language:%s", cfg.Language)
}

so := github.SearchOptions{ListOptions: github.ListOptions{PerPage: 1}}

repositories, _, e = client.Search.Repositories(ctx, qs, &so)

if e != nil {
panic(e)
}
}

return repositories.Repositories, *repositories.Total
}

func getSpecificRepo(pos int) *github.Repository {
ctx, client := cfg.AccessCfg.GetGithubClient()

var e error
var qs string

if cfg.Topic != "" {
qs = fmt.Sprintf("topic:%s", cfg.Topic)
} else {
qs = fmt.Sprintf("language:%s", cfg.Language)
}

so := github.SearchOptions{ListOptions: github.ListOptions{PerPage: 1, Page: pos}}

repositories, _, e = client.Search.Repositories(ctx, qs, &so)

if e != nil {
return nil
}

return &repositories.Repositories[0]
}

func getRepo() *github.Repository {
_, total := getRepositories()

var repo *github.Repository

var found bool

for !found {
rand.Seed(time.Now().UTC().UnixNano())
randPos := rand.Intn(total / 100)

repo = getSpecificRepo(randPos)

found = repo != nil && isRepoNotInRedis(repo, cfg.CacheSize*cfg.Periodicity, cfg.Topic)

if found && *repo.Archived {
found = false
log.Print("Repository archived")
log.Print(*repo.ID)
}
}

return repo
}

func isRepoNotInRedis(r *github.Repository, t int, topic string) bool {
k := topic + "-" + strconv.FormatInt(*r.ID, 10)
_, err := rdb.Get(k)

switch {
case err == redis.Nil:
err := rdb.Set(k, true, time.Duration(t)*time.Minute)
if err != nil {
panic(err)
}

return true
case err != nil:
fmt.Println("Get failed", err)
}

return false
}
Loading

0 comments on commit 39cb2f2

Please sign in to comment.