James Tombleson
713205bb03
* basic routes are working with db context * swagger is working along with swag gen * cron was updated with a class and better db context, untested though * sourcelist command added * lost the pg package but added it back * Updated the api startup for cron and api * updated source routes and started to add article routes * Updated cron add func calls * updated swagger * keeping articles basic for now as I dont need to pull them in yet * swagger update * added getarticlesbysourceid call * adding the subscriptions table to track who to send notifications and where * removed legacy columns from discordwebhooks that are no longer needed. * added discord webhook routes * updated routes * Minor change to schema * Updated routes to support subscriptions * ignore .vscode
184 lines
4.1 KiB
Go
184 lines
4.1 KiB
Go
package cron
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
_ "github.com/lib/pq"
|
|
"github.com/robfig/cron/v3"
|
|
|
|
"github.com/jtom38/newsbot/collector/database"
|
|
"github.com/jtom38/newsbot/collector/services"
|
|
"github.com/jtom38/newsbot/collector/services/config"
|
|
)
|
|
|
|
type Cron struct {
|
|
Db *database.Queries
|
|
ctx *context.Context
|
|
timer *cron.Cron
|
|
}
|
|
|
|
func openDatabase() (*database.Queries, error) {
|
|
_env := config.New()
|
|
connString := _env.GetConfig(config.Sql_Connection_String)
|
|
db, err := sql.Open("postgres", connString)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
queries := database.New(db)
|
|
return queries, err
|
|
}
|
|
|
|
func New(ctx context.Context) *Cron {
|
|
c := &Cron{
|
|
ctx: &ctx,
|
|
}
|
|
|
|
timer := cron.New()
|
|
queries, err := openDatabase()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
c.Db = queries
|
|
|
|
//timer.AddFunc("*/5 * * * *", func() { go CheckCache() })
|
|
//timer.AddFunc("* */30 * * *", func() { go c.CheckReddit(ctx) })
|
|
//timer.AddFunc("* */1 * * *", func() { go CheckYoutube() })
|
|
//timer.AddFunc("* */1 * * *", func() { go CheckFfxiv() })
|
|
//timer.AddFunc("* */1 * * *", func() { go CheckTwitch() })
|
|
c.timer = timer
|
|
return c
|
|
}
|
|
|
|
func (c *Cron) Start() {
|
|
c.timer.Start()
|
|
}
|
|
|
|
func (c *Cron) Stop() {
|
|
c.timer.Stop()
|
|
}
|
|
|
|
// This is the main entry point to query all the reddit services
|
|
func (c *Cron) CheckReddit(ctx context.Context) {
|
|
sources, err := c.Db.ListSourcesBySource(*c.ctx, "reddit")
|
|
if err != nil {
|
|
log.Printf("No defines sources for reddit to query - %v\r", err)
|
|
}
|
|
|
|
for _, source := range sources {
|
|
if !source.Enabled {
|
|
continue
|
|
}
|
|
rc := services.NewRedditClient(source)
|
|
raw, err := rc.GetContent()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
redditArticles := rc.ConvertToArticles(raw)
|
|
c.checkPosts(*c.ctx, redditArticles)
|
|
}
|
|
}
|
|
|
|
func (c *Cron) CheckYoutube(ctx context.Context) {
|
|
// Add call to the db to request youtube sources.
|
|
sources, err := c.Db.ListSourcesBySource(*c.ctx, "youtube")
|
|
if err != nil {
|
|
log.Printf("Youtube - No sources found to query - %v\r", err)
|
|
}
|
|
|
|
for _, source := range sources {
|
|
if !source.Enabled {
|
|
continue
|
|
}
|
|
yc := services.NewYoutubeClient(source)
|
|
raw, err := yc.GetContent()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
c.checkPosts(*c.ctx, raw)
|
|
}
|
|
}
|
|
|
|
func (c *Cron) CheckFfxiv(ctx context.Context) {
|
|
sources, err := c.Db.ListSourcesBySource(*c.ctx, "ffxiv")
|
|
if err != nil {
|
|
log.Printf("Final Fantasy XIV - No sources found to query - %v\r", err)
|
|
}
|
|
|
|
for _, source := range sources {
|
|
if !source.Enabled {
|
|
continue
|
|
}
|
|
fc := services.NewFFXIVClient(source)
|
|
items, err := fc.CheckSource()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
c.checkPosts(*c.ctx, items)
|
|
}
|
|
}
|
|
|
|
func (c *Cron) CheckTwitch(ctx context.Context) error {
|
|
sources, err := c.Db.ListSourcesBySource(*c.ctx, "twitch")
|
|
if err != nil {
|
|
log.Printf("Twitch - No sources found to query - %v\r", err)
|
|
}
|
|
|
|
tc, err := services.NewTwitchClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, source := range sources {
|
|
if !source.Enabled {
|
|
continue
|
|
}
|
|
tc.ReplaceSourceRecord(source)
|
|
items, err := tc.GetContent()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
c.checkPosts(*c.ctx, items)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Cron) checkPosts(ctx context.Context, posts []database.Article) {
|
|
for _, item := range posts {
|
|
_, err := c.Db.GetArticleByUrl(*c.ctx, item.Url)
|
|
if err != nil {
|
|
err = c.postArticle(ctx, item)
|
|
if err != nil {
|
|
log.Printf("Reddit - Failed to post article - %v - %v.\r", item.Url, err)
|
|
} else {
|
|
log.Printf("Reddit - Posted article - %v\r", item.Url)
|
|
}
|
|
}
|
|
}
|
|
time.Sleep(30 * time.Second)
|
|
}
|
|
|
|
func (c *Cron) postArticle(ctx context.Context, item database.Article) error {
|
|
err := c.Db.CreateArticle(*c.ctx, database.CreateArticleParams{
|
|
ID: uuid.New(),
|
|
Sourceid: item.Sourceid,
|
|
Tags: item.Tags,
|
|
Title: item.Title,
|
|
Url: item.Url,
|
|
Pubdate: item.Pubdate,
|
|
Video: item.Video,
|
|
Videoheight: item.Videoheight,
|
|
Videowidth: item.Videowidth,
|
|
Thumbnail: item.Thumbnail,
|
|
Description: item.Description,
|
|
Authorname: item.Authorname,
|
|
Authorimage: item.Authorimage,
|
|
})
|
|
return err
|
|
}
|