Basic routes have been added (#10)
* 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
This commit is contained in:
parent
77d4fdf01a
commit
713205bb03
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,8 @@
|
||||
.env
|
||||
dev.session.sql
|
||||
|
||||
.vscode
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
|
@ -33,7 +33,7 @@ INSERT INTO sources VALUES
|
||||
|
||||
-- Twitch Entries
|
||||
INSERT INTO sources VALUES
|
||||
(uuid_generate_v4(), 'twitch', 'Nintendo', 'twitch', 'api', 'a', TRUE, 'https://store.steampowered.com/feeds/news/app/1675200/?cc=US&l=english&snr=1_2108_9__2107', 'rss, steampowered, steam, deck, steam deck');
|
||||
(uuid_generate_v4(), 'twitch', 'Nintendo', 'twitch', 'api', 'a', TRUE, 'https://twitch.tv/nintendo', 'twitch, nintendo');
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
|
21
database/migrations/20220619085634_subscriptions.sql
Normal file
21
database/migrations/20220619085634_subscriptions.sql
Normal file
@ -0,0 +1,21 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
SELECT 'up SQL query';
|
||||
Create TABLE Subscriptions (
|
||||
ID uuid Primary Key,
|
||||
DiscordWebHookID uuid Not Null,
|
||||
SourceID uuid Not Null
|
||||
);
|
||||
|
||||
ALTER TABLE discordwebhooks drop COLUMN Name;
|
||||
ALTER TABLE discordwebhooks drop COLUMN Key;
|
||||
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
SELECT 'down SQL query';
|
||||
Drop Table Subscriptions;
|
||||
ALTER TABLE discordwebhooks Add COLUMN Name TEXT;
|
||||
--ALTER TABLE discordwebhooks Add COLUMN Key TEXT;
|
||||
-- +goose StatementEnd
|
@ -34,8 +34,6 @@ type Discordqueue struct {
|
||||
|
||||
type Discordwebhook struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
Key sql.NullString
|
||||
Url string
|
||||
Server string
|
||||
Channel string
|
||||
@ -66,3 +64,9 @@ type Source struct {
|
||||
Url string
|
||||
Tags string
|
||||
}
|
||||
|
||||
type Subscription struct {
|
||||
ID uuid.UUID
|
||||
Discordwebhookid uuid.UUID
|
||||
Sourceid uuid.UUID
|
||||
}
|
||||
|
@ -75,15 +75,13 @@ func (q *Queries) CreateDiscordQueue(ctx context.Context, arg CreateDiscordQueue
|
||||
|
||||
const createDiscordWebHook = `-- name: CreateDiscordWebHook :exec
|
||||
Insert Into DiscordWebHooks
|
||||
(ID, Name, Key, Url, Server, Channel, Enabled)
|
||||
(ID, Url, Server, Channel, Enabled)
|
||||
Values
|
||||
($1, $2, $3, $4, $5, $6, $7)
|
||||
($1, $2, $3, $4, $5)
|
||||
`
|
||||
|
||||
type CreateDiscordWebHookParams struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
Key sql.NullString
|
||||
Url string
|
||||
Server string
|
||||
Channel string
|
||||
@ -94,8 +92,6 @@ type CreateDiscordWebHookParams struct {
|
||||
func (q *Queries) CreateDiscordWebHook(ctx context.Context, arg CreateDiscordWebHookParams) error {
|
||||
_, err := q.db.ExecContext(ctx, createDiscordWebHook,
|
||||
arg.ID,
|
||||
arg.Name,
|
||||
arg.Key,
|
||||
arg.Url,
|
||||
arg.Server,
|
||||
arg.Channel,
|
||||
@ -194,6 +190,23 @@ func (q *Queries) CreateSource(ctx context.Context, arg CreateSourceParams) erro
|
||||
return err
|
||||
}
|
||||
|
||||
const createSubscription = `-- name: CreateSubscription :exec
|
||||
|
||||
Insert Into subscriptions (ID, DiscordWebHookId, SourceId) Values ($1, $2, $3)
|
||||
`
|
||||
|
||||
type CreateSubscriptionParams struct {
|
||||
ID uuid.UUID
|
||||
Discordwebhookid uuid.UUID
|
||||
Sourceid uuid.UUID
|
||||
}
|
||||
|
||||
// Subscriptions
|
||||
func (q *Queries) CreateSubscription(ctx context.Context, arg CreateSubscriptionParams) error {
|
||||
_, err := q.db.ExecContext(ctx, createSubscription, arg.ID, arg.Discordwebhookid, arg.Sourceid)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteDiscordQueueItem = `-- name: DeleteDiscordQueueItem :exec
|
||||
Delete From DiscordQueue Where ID = $1
|
||||
`
|
||||
@ -239,6 +252,38 @@ func (q *Queries) DeleteSource(ctx context.Context, id uuid.UUID) error {
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteSubscription = `-- name: DeleteSubscription :exec
|
||||
Delete From subscriptions Where discordwebhookid = $1 and sourceid = $2
|
||||
`
|
||||
|
||||
type DeleteSubscriptionParams struct {
|
||||
Discordwebhookid uuid.UUID
|
||||
Sourceid uuid.UUID
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteSubscription(ctx context.Context, arg DeleteSubscriptionParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteSubscription, arg.Discordwebhookid, arg.Sourceid)
|
||||
return err
|
||||
}
|
||||
|
||||
const disableSource = `-- name: DisableSource :exec
|
||||
Update Sources Set Enabled = FALSE where ID = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DisableSource(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, disableSource, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const enableSource = `-- name: EnableSource :exec
|
||||
Update Sources Set Enabled = TRUE where ID = $1
|
||||
`
|
||||
|
||||
func (q *Queries) EnableSource(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, enableSource, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const getArticleByID = `-- name: GetArticleByID :one
|
||||
Select id, sourceid, tags, title, url, pubdate, video, videoheight, videowidth, thumbnail, description, authorname, authorimage from Articles
|
||||
WHERE ID = $1 LIMIT 1
|
||||
@ -292,6 +337,191 @@ func (q *Queries) GetArticleByUrl(ctx context.Context, url string) (Article, err
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getArticlesBySource = `-- name: GetArticlesBySource :many
|
||||
select articles.id, sourceid, articles.tags, title, articles.url, pubdate, video, videoheight, videowidth, thumbnail, description, authorname, authorimage, sources.id, site, name, source, type, value, enabled, sources.url, sources.tags from articles
|
||||
INNER join sources on articles.sourceid=Sources.ID
|
||||
where site = $1
|
||||
`
|
||||
|
||||
type GetArticlesBySourceRow struct {
|
||||
ID uuid.UUID
|
||||
Sourceid uuid.UUID
|
||||
Tags string
|
||||
Title string
|
||||
Url string
|
||||
Pubdate time.Time
|
||||
Video sql.NullString
|
||||
Videoheight int32
|
||||
Videowidth int32
|
||||
Thumbnail string
|
||||
Description string
|
||||
Authorname sql.NullString
|
||||
Authorimage sql.NullString
|
||||
ID_2 uuid.UUID
|
||||
Site string
|
||||
Name string
|
||||
Source string
|
||||
Type string
|
||||
Value sql.NullString
|
||||
Enabled bool
|
||||
Url_2 string
|
||||
Tags_2 string
|
||||
}
|
||||
|
||||
func (q *Queries) GetArticlesBySource(ctx context.Context, site string) ([]GetArticlesBySourceRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getArticlesBySource, site)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetArticlesBySourceRow
|
||||
for rows.Next() {
|
||||
var i GetArticlesBySourceRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Sourceid,
|
||||
&i.Tags,
|
||||
&i.Title,
|
||||
&i.Url,
|
||||
&i.Pubdate,
|
||||
&i.Video,
|
||||
&i.Videoheight,
|
||||
&i.Videowidth,
|
||||
&i.Thumbnail,
|
||||
&i.Description,
|
||||
&i.Authorname,
|
||||
&i.Authorimage,
|
||||
&i.ID_2,
|
||||
&i.Site,
|
||||
&i.Name,
|
||||
&i.Source,
|
||||
&i.Type,
|
||||
&i.Value,
|
||||
&i.Enabled,
|
||||
&i.Url_2,
|
||||
&i.Tags_2,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getArticlesBySourceId = `-- name: GetArticlesBySourceId :many
|
||||
Select id, sourceid, tags, title, url, pubdate, video, videoheight, videowidth, thumbnail, description, authorname, authorimage From articles
|
||||
Where sourceid = $1 Limit 50
|
||||
`
|
||||
|
||||
func (q *Queries) GetArticlesBySourceId(ctx context.Context, sourceid uuid.UUID) ([]Article, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getArticlesBySourceId, sourceid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Article
|
||||
for rows.Next() {
|
||||
var i Article
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Sourceid,
|
||||
&i.Tags,
|
||||
&i.Title,
|
||||
&i.Url,
|
||||
&i.Pubdate,
|
||||
&i.Video,
|
||||
&i.Videoheight,
|
||||
&i.Videowidth,
|
||||
&i.Thumbnail,
|
||||
&i.Description,
|
||||
&i.Authorname,
|
||||
&i.Authorimage,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getArticlesBySourceName = `-- name: GetArticlesBySourceName :many
|
||||
select
|
||||
articles.ID, articles.SourceId, articles.Tags, articles.Title, articles.Url, articles.PubDate, articles.Video, articles.VideoHeight, articles.VideoWidth, articles.Thumbnail, articles.Description, articles.AuthorName, articles.AuthorImage, sources.source, sources.name
|
||||
From articles
|
||||
Left Join sources
|
||||
On articles.sourceid = sources.id
|
||||
Where name = $1
|
||||
`
|
||||
|
||||
type GetArticlesBySourceNameRow struct {
|
||||
ID uuid.UUID
|
||||
Sourceid uuid.UUID
|
||||
Tags string
|
||||
Title string
|
||||
Url string
|
||||
Pubdate time.Time
|
||||
Video sql.NullString
|
||||
Videoheight int32
|
||||
Videowidth int32
|
||||
Thumbnail string
|
||||
Description string
|
||||
Authorname sql.NullString
|
||||
Authorimage sql.NullString
|
||||
Source sql.NullString
|
||||
Name sql.NullString
|
||||
}
|
||||
|
||||
func (q *Queries) GetArticlesBySourceName(ctx context.Context, name string) ([]GetArticlesBySourceNameRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getArticlesBySourceName, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetArticlesBySourceNameRow
|
||||
for rows.Next() {
|
||||
var i GetArticlesBySourceNameRow
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Sourceid,
|
||||
&i.Tags,
|
||||
&i.Title,
|
||||
&i.Url,
|
||||
&i.Pubdate,
|
||||
&i.Video,
|
||||
&i.Videoheight,
|
||||
&i.Videowidth,
|
||||
&i.Thumbnail,
|
||||
&i.Description,
|
||||
&i.Authorname,
|
||||
&i.Authorimage,
|
||||
&i.Source,
|
||||
&i.Name,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getDiscordQueueByID = `-- name: GetDiscordQueueByID :one
|
||||
Select id, articleid from DiscordQueue
|
||||
Where ID = $1 LIMIT 1
|
||||
@ -332,7 +562,7 @@ func (q *Queries) GetDiscordQueueItems(ctx context.Context, limit int32) ([]Disc
|
||||
}
|
||||
|
||||
const getDiscordWebHooksByID = `-- name: GetDiscordWebHooksByID :one
|
||||
Select id, name, key, url, server, channel, enabled from DiscordWebHooks
|
||||
Select id, url, server, channel, enabled from DiscordWebHooks
|
||||
Where ID = $1 LIMIT 1
|
||||
`
|
||||
|
||||
@ -341,8 +571,6 @@ func (q *Queries) GetDiscordWebHooksByID(ctx context.Context, id uuid.UUID) (Dis
|
||||
var i Discordwebhook
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Key,
|
||||
&i.Url,
|
||||
&i.Server,
|
||||
&i.Channel,
|
||||
@ -447,8 +675,103 @@ func (q *Queries) GetSourceByID(ctx context.Context, id uuid.UUID) (Source, erro
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getSubscriptionsByDiscordWebHookId = `-- name: GetSubscriptionsByDiscordWebHookId :many
|
||||
Select id, discordwebhookid, sourceid from subscriptions Where discordwebhookid = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSubscriptionsByDiscordWebHookId(ctx context.Context, discordwebhookid uuid.UUID) ([]Subscription, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getSubscriptionsByDiscordWebHookId, discordwebhookid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Subscription
|
||||
for rows.Next() {
|
||||
var i Subscription
|
||||
if err := rows.Scan(&i.ID, &i.Discordwebhookid, &i.Sourceid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getSubscriptionsBySourceID = `-- name: GetSubscriptionsBySourceID :many
|
||||
Select id, discordwebhookid, sourceid From subscriptions Where sourceid = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetSubscriptionsBySourceID(ctx context.Context, sourceid uuid.UUID) ([]Subscription, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getSubscriptionsBySourceID, sourceid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Subscription
|
||||
for rows.Next() {
|
||||
var i Subscription
|
||||
if err := rows.Scan(&i.ID, &i.Discordwebhookid, &i.Sourceid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listArticles = `-- name: ListArticles :many
|
||||
Select id, sourceid, tags, title, url, pubdate, video, videoheight, videowidth, thumbnail, description, authorname, authorimage From articles Limit $1
|
||||
`
|
||||
|
||||
func (q *Queries) ListArticles(ctx context.Context, limit int32) ([]Article, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listArticles, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Article
|
||||
for rows.Next() {
|
||||
var i Article
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Sourceid,
|
||||
&i.Tags,
|
||||
&i.Title,
|
||||
&i.Url,
|
||||
&i.Pubdate,
|
||||
&i.Video,
|
||||
&i.Videoheight,
|
||||
&i.Videowidth,
|
||||
&i.Thumbnail,
|
||||
&i.Description,
|
||||
&i.Authorname,
|
||||
&i.Authorimage,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDiscordWebHooksByServer = `-- name: ListDiscordWebHooksByServer :many
|
||||
Select id, name, key, url, server, channel, enabled From DiscordWebHooks
|
||||
Select id, url, server, channel, enabled From DiscordWebHooks
|
||||
Where Server = $1
|
||||
`
|
||||
|
||||
@ -463,8 +786,6 @@ func (q *Queries) ListDiscordWebHooksByServer(ctx context.Context, server string
|
||||
var i Discordwebhook
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Name,
|
||||
&i.Key,
|
||||
&i.Url,
|
||||
&i.Server,
|
||||
&i.Channel,
|
||||
@ -483,6 +804,76 @@ func (q *Queries) ListDiscordWebHooksByServer(ctx context.Context, server string
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listDiscordWebhooks = `-- name: ListDiscordWebhooks :many
|
||||
Select id, url, server, channel, enabled From discordwebhooks LIMIT $1
|
||||
`
|
||||
|
||||
func (q *Queries) ListDiscordWebhooks(ctx context.Context, limit int32) ([]Discordwebhook, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listDiscordWebhooks, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Discordwebhook
|
||||
for rows.Next() {
|
||||
var i Discordwebhook
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Url,
|
||||
&i.Server,
|
||||
&i.Channel,
|
||||
&i.Enabled,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listSources = `-- name: ListSources :many
|
||||
Select id, site, name, source, type, value, enabled, url, tags From Sources Limit $1
|
||||
`
|
||||
|
||||
func (q *Queries) ListSources(ctx context.Context, limit int32) ([]Source, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listSources, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Source
|
||||
for rows.Next() {
|
||||
var i Source
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.Site,
|
||||
&i.Name,
|
||||
&i.Source,
|
||||
&i.Type,
|
||||
&i.Value,
|
||||
&i.Enabled,
|
||||
&i.Url,
|
||||
&i.Tags,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listSourcesBySource = `-- name: ListSourcesBySource :many
|
||||
Select id, site, name, source, type, value, enabled, url, tags From Sources where Source = $1
|
||||
`
|
||||
@ -519,3 +910,62 @@ func (q *Queries) ListSourcesBySource(ctx context.Context, source string) ([]Sou
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const listSubscriptions = `-- name: ListSubscriptions :many
|
||||
Select id, discordwebhookid, sourceid From subscriptions Limit $1
|
||||
`
|
||||
|
||||
func (q *Queries) ListSubscriptions(ctx context.Context, limit int32) ([]Subscription, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listSubscriptions, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Subscription
|
||||
for rows.Next() {
|
||||
var i Subscription
|
||||
if err := rows.Scan(&i.ID, &i.Discordwebhookid, &i.Sourceid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const querySubscriptions = `-- name: QuerySubscriptions :many
|
||||
Select id, discordwebhookid, sourceid From subscriptions Where discordwebhookid = $1 and sourceid = $2
|
||||
`
|
||||
|
||||
type QuerySubscriptionsParams struct {
|
||||
Discordwebhookid uuid.UUID
|
||||
Sourceid uuid.UUID
|
||||
}
|
||||
|
||||
func (q *Queries) QuerySubscriptions(ctx context.Context, arg QuerySubscriptionsParams) ([]Subscription, error) {
|
||||
rows, err := q.db.QueryContext(ctx, querySubscriptions, arg.Discordwebhookid, arg.Sourceid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Subscription
|
||||
for rows.Next() {
|
||||
var i Subscription
|
||||
if err := rows.Scan(&i.ID, &i.Discordwebhookid, &i.Sourceid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
@ -7,6 +7,26 @@ WHERE ID = $1 LIMIT 1;
|
||||
Select * from Articles
|
||||
Where Url = $1 LIMIT 1;
|
||||
|
||||
-- name: ListArticles :many
|
||||
Select * From articles Limit $1;
|
||||
|
||||
-- name: GetArticlesBySource :many
|
||||
select * from articles
|
||||
INNER join sources on articles.sourceid=Sources.ID
|
||||
where site = $1;
|
||||
|
||||
-- name: GetArticlesBySourceId :many
|
||||
Select * From articles
|
||||
Where sourceid = $1 Limit 50;
|
||||
|
||||
-- name: GetArticlesBySourceName :many
|
||||
select
|
||||
articles.ID, articles.SourceId, articles.Tags, articles.Title, articles.Url, articles.PubDate, articles.Video, articles.VideoHeight, articles.VideoWidth, articles.Thumbnail, articles.Description, articles.AuthorName, articles.AuthorImage, sources.source, sources.name
|
||||
From articles
|
||||
Left Join sources
|
||||
On articles.sourceid = sources.id
|
||||
Where name = $1;
|
||||
|
||||
-- name: CreateArticle :exec
|
||||
INSERT INTO Articles
|
||||
(ID, SourceId, Tags, Title, Url, PubDate, Video, VideoHeight, VideoWidth, Thumbnail, Description, AuthorName, AuthorImage)
|
||||
@ -31,13 +51,12 @@ Delete From DiscordQueue Where ID = $1;
|
||||
-- name: GetDiscordQueueItems :many
|
||||
Select * from DiscordQueue LIMIT $1;
|
||||
|
||||
|
||||
/* DiscordWebHooks */
|
||||
-- name: CreateDiscordWebHook :exec
|
||||
Insert Into DiscordWebHooks
|
||||
(ID, Name, Key, Url, Server, Channel, Enabled)
|
||||
(ID, Url, Server, Channel, Enabled)
|
||||
Values
|
||||
($1, $2, $3, $4, $5, $6, $7);
|
||||
($1, $2, $3, $4, $5);
|
||||
|
||||
-- name: GetDiscordWebHooksByID :one
|
||||
Select * from DiscordWebHooks
|
||||
@ -47,6 +66,9 @@ Where ID = $1 LIMIT 1;
|
||||
Select * From DiscordWebHooks
|
||||
Where Server = $1;
|
||||
|
||||
-- name: ListDiscordWebhooks :many
|
||||
Select * From discordwebhooks LIMIT $1;
|
||||
|
||||
-- name: DeleteDiscordWebHooks :exec
|
||||
Delete From discordwebhooks Where ID = $1;
|
||||
|
||||
@ -105,8 +127,38 @@ Values
|
||||
-- name: GetSourceByID :one
|
||||
Select * From Sources where ID = $1 Limit 1;
|
||||
|
||||
-- name: ListSources :many
|
||||
Select * From Sources Limit $1;
|
||||
|
||||
-- name: ListSourcesBySource :many
|
||||
Select * From Sources where Source = $1;
|
||||
|
||||
-- name: DeleteSource :exec
|
||||
DELETE From sources where id = $1;
|
||||
|
||||
-- name: DisableSource :exec
|
||||
Update Sources Set Enabled = FALSE where ID = $1;
|
||||
|
||||
-- name: EnableSource :exec
|
||||
Update Sources Set Enabled = TRUE where ID = $1;
|
||||
|
||||
|
||||
/* Subscriptions */
|
||||
|
||||
-- name: CreateSubscription :exec
|
||||
Insert Into subscriptions (ID, DiscordWebHookId, SourceId) Values ($1, $2, $3);
|
||||
|
||||
-- name: ListSubscriptions :many
|
||||
Select * From subscriptions Limit $1;
|
||||
|
||||
-- name: QuerySubscriptions :many
|
||||
Select * From subscriptions Where discordwebhookid = $1 and sourceid = $2;
|
||||
|
||||
-- name: GetSubscriptionsBySourceID :many
|
||||
Select * From subscriptions Where sourceid = $1;
|
||||
|
||||
-- name: GetSubscriptionsByDiscordWebHookId :many
|
||||
Select * from subscriptions Where discordwebhookid = $1;
|
||||
|
||||
-- name: DeleteSubscription :exec
|
||||
Delete From subscriptions Where discordwebhookid = $1 and sourceid = $2;
|
@ -21,8 +21,6 @@ CREATE Table DiscordQueue (
|
||||
|
||||
CREATE Table DiscordWebHooks (
|
||||
ID uuid PRIMARY KEY,
|
||||
Name TEXT NOT NULL, -- Defines webhook purpose
|
||||
Key TEXT,
|
||||
Url TEXT NOT NULL, -- Webhook Url
|
||||
Server TEXT NOT NULL, -- Defines the server its bound it. Used for refrence
|
||||
Channel TEXT NOT NULL, -- Defines the channel its bound to. Used for refrence
|
||||
@ -54,3 +52,9 @@ Create Table Sources (
|
||||
Tags TEXT NOT NULL
|
||||
);
|
||||
|
||||
/* This table is used to track what the Web Hook wants to have sent by Source */;
|
||||
Create TABLE Subscriptions (
|
||||
ID uuid Primary Key,
|
||||
DiscordWebHookID uuid Not Null,
|
||||
SourceID uuid Not Null
|
||||
);
|
||||
|
483
docs/docs.go
Normal file
483
docs/docs.go
Normal file
@ -0,0 +1,483 @@
|
||||
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
||||
// This file was generated by swaggo/swag
|
||||
package docs
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{escape .Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"contact": {},
|
||||
"version": "{{.Version}}"
|
||||
},
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/articles": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"articles"
|
||||
],
|
||||
"summary": "Lists the top 50 records",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/articles/by/sourceid/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"articles"
|
||||
],
|
||||
"summary": "Finds the articles based on the SourceID provided. Returns the top 50.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Source ID UUID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/articles/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"articles"
|
||||
],
|
||||
"summary": "Returns an article based on defined ID.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "uuid",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Lists the top 50 records",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/new/reddit": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source",
|
||||
"reddit"
|
||||
],
|
||||
"summary": "Creates a new reddit source to monitor.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name",
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/new/twitch": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source",
|
||||
"twitch"
|
||||
],
|
||||
"summary": "Creates a new twitch source to monitor.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name",
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "tags",
|
||||
"name": "tags",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/new/youtube": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source",
|
||||
"youtube"
|
||||
],
|
||||
"summary": "Creates a new youtube source to monitor.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name",
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "tags",
|
||||
"name": "tags",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Returns a single entity by ID",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "uuid",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Deletes a record by ID.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/{id}/disable": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Disables a source from processing.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/{id}/enable": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Enables a source to continue processing.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/queue": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"debug",
|
||||
"Discord",
|
||||
"Queue"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/webhooks": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Discord",
|
||||
"Webhooks"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/webhooks/byId": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Discord",
|
||||
"Webhooks"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/webhooks/new": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"Discord",
|
||||
"Webhooks"
|
||||
],
|
||||
"summary": "Creates a new record for a discord web hook to post data to.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Server name",
|
||||
"name": "server",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Channel name.",
|
||||
"name": "channel",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/hello/{who}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"debug"
|
||||
],
|
||||
"summary": "Responds back with \"Hello x\" depending on param passed in.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Who",
|
||||
"name": "who",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/helloworld": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"debug"
|
||||
],
|
||||
"summary": "Responds back with \"Hello world!\"",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/ping": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"debug"
|
||||
],
|
||||
"summary": "Sends back \"pong\". Good to test with.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/settings/{key}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"settings"
|
||||
],
|
||||
"summary": "Returns a object based on the Key that was given/",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Settings Key value",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/subscriptions": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Subscriptions"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/subscriptions/byDiscordId": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Subscriptions"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/subscriptions/bySourceId": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Subscriptions"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "0.1",
|
||||
Host: "",
|
||||
BasePath: "/api",
|
||||
Schemes: []string{},
|
||||
Title: "NewsBot collector",
|
||||
Description: "",
|
||||
InfoInstanceName: "swagger",
|
||||
SwaggerTemplate: docTemplate,
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||
}
|
458
docs/swagger.json
Normal file
458
docs/swagger.json
Normal file
@ -0,0 +1,458 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"title": "NewsBot collector",
|
||||
"contact": {},
|
||||
"version": "0.1"
|
||||
},
|
||||
"basePath": "/api",
|
||||
"paths": {
|
||||
"/articles": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"articles"
|
||||
],
|
||||
"summary": "Lists the top 50 records",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/articles/by/sourceid/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"articles"
|
||||
],
|
||||
"summary": "Finds the articles based on the SourceID provided. Returns the top 50.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Source ID UUID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/articles/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"articles"
|
||||
],
|
||||
"summary": "Returns an article based on defined ID.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "uuid",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Lists the top 50 records",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/new/reddit": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source",
|
||||
"reddit"
|
||||
],
|
||||
"summary": "Creates a new reddit source to monitor.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name",
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/new/twitch": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source",
|
||||
"twitch"
|
||||
],
|
||||
"summary": "Creates a new twitch source to monitor.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name",
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "tags",
|
||||
"name": "tags",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/new/youtube": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source",
|
||||
"youtube"
|
||||
],
|
||||
"summary": "Creates a new youtube source to monitor.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name",
|
||||
"name": "name",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "tags",
|
||||
"name": "tags",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/{id}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Returns a single entity by ID",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "uuid",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Deletes a record by ID.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/{id}/disable": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Disables a source from processing.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/config/sources/{id}/enable": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"source"
|
||||
],
|
||||
"summary": "Enables a source to continue processing.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/queue": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"debug",
|
||||
"Discord",
|
||||
"Queue"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/webhooks": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Discord",
|
||||
"Webhooks"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/webhooks/byId": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Discord",
|
||||
"Webhooks"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/discord/webhooks/new": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"config",
|
||||
"Discord",
|
||||
"Webhooks"
|
||||
],
|
||||
"summary": "Creates a new record for a discord web hook to post data to.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "url",
|
||||
"name": "url",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Server name",
|
||||
"name": "server",
|
||||
"in": "query",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Channel name.",
|
||||
"name": "channel",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/hello/{who}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"debug"
|
||||
],
|
||||
"summary": "Responds back with \"Hello x\" depending on param passed in.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Who",
|
||||
"name": "who",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/helloworld": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"debug"
|
||||
],
|
||||
"summary": "Responds back with \"Hello world!\"",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/ping": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"text/plain"
|
||||
],
|
||||
"tags": [
|
||||
"debug"
|
||||
],
|
||||
"summary": "Sends back \"pong\". Good to test with.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/settings/{key}": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"settings"
|
||||
],
|
||||
"summary": "Returns a object based on the Key that was given/",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Settings Key value",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/subscriptions": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Subscriptions"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/subscriptions/byDiscordId": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Subscriptions"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/subscriptions/bySourceId": {
|
||||
"get": {
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"config",
|
||||
"Subscriptions"
|
||||
],
|
||||
"summary": "Returns the top 100 entries from the queue to be processed.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "id",
|
||||
"name": "id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
316
docs/swagger.yaml
Normal file
316
docs/swagger.yaml
Normal file
@ -0,0 +1,316 @@
|
||||
basePath: /api
|
||||
info:
|
||||
contact: {}
|
||||
title: NewsBot collector
|
||||
version: "0.1"
|
||||
paths:
|
||||
/articles:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Lists the top 50 records
|
||||
tags:
|
||||
- articles
|
||||
/articles/{id}:
|
||||
get:
|
||||
parameters:
|
||||
- description: uuid
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns an article based on defined ID.
|
||||
tags:
|
||||
- articles
|
||||
/articles/by/sourceid/{id}:
|
||||
get:
|
||||
parameters:
|
||||
- description: Source ID UUID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Finds the articles based on the SourceID provided. Returns the top
|
||||
50.
|
||||
tags:
|
||||
- articles
|
||||
/config/sources:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Lists the top 50 records
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
/config/sources/{id}:
|
||||
delete:
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Deletes a record by ID.
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
get:
|
||||
parameters:
|
||||
- description: uuid
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns a single entity by ID
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
/config/sources/{id}/disable:
|
||||
post:
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Disables a source from processing.
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
/config/sources/{id}/enable:
|
||||
post:
|
||||
parameters:
|
||||
- description: id
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Enables a source to continue processing.
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
/config/sources/new/reddit:
|
||||
post:
|
||||
parameters:
|
||||
- description: name
|
||||
in: query
|
||||
name: name
|
||||
required: true
|
||||
type: string
|
||||
- description: url
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Creates a new reddit source to monitor.
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
- reddit
|
||||
/config/sources/new/twitch:
|
||||
post:
|
||||
parameters:
|
||||
- description: name
|
||||
in: query
|
||||
name: name
|
||||
required: true
|
||||
type: string
|
||||
- description: url
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
type: string
|
||||
- description: tags
|
||||
in: query
|
||||
name: tags
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Creates a new twitch source to monitor.
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
- twitch
|
||||
/config/sources/new/youtube:
|
||||
post:
|
||||
parameters:
|
||||
- description: name
|
||||
in: query
|
||||
name: name
|
||||
required: true
|
||||
type: string
|
||||
- description: url
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
type: string
|
||||
- description: tags
|
||||
in: query
|
||||
name: tags
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Creates a new youtube source to monitor.
|
||||
tags:
|
||||
- config
|
||||
- source
|
||||
- youtube
|
||||
/discord/queue:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns the top 100 entries from the queue to be processed.
|
||||
tags:
|
||||
- debug
|
||||
- Discord
|
||||
- Queue
|
||||
/discord/webhooks:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns the top 100 entries from the queue to be processed.
|
||||
tags:
|
||||
- config
|
||||
- Discord
|
||||
- Webhooks
|
||||
/discord/webhooks/byId:
|
||||
get:
|
||||
parameters:
|
||||
- description: id
|
||||
in: query
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns the top 100 entries from the queue to be processed.
|
||||
tags:
|
||||
- config
|
||||
- Discord
|
||||
- Webhooks
|
||||
/discord/webhooks/new:
|
||||
post:
|
||||
parameters:
|
||||
- description: url
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
type: string
|
||||
- description: Server name
|
||||
in: query
|
||||
name: server
|
||||
required: true
|
||||
type: string
|
||||
- description: Channel name.
|
||||
in: query
|
||||
name: channel
|
||||
required: true
|
||||
type: string
|
||||
responses: {}
|
||||
summary: Creates a new record for a discord web hook to post data to.
|
||||
tags:
|
||||
- config
|
||||
- Discord
|
||||
- Webhooks
|
||||
/hello/{who}:
|
||||
get:
|
||||
parameters:
|
||||
- description: Who
|
||||
in: path
|
||||
name: who
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- text/plain
|
||||
responses: {}
|
||||
summary: Responds back with "Hello x" depending on param passed in.
|
||||
tags:
|
||||
- debug
|
||||
/helloworld:
|
||||
get:
|
||||
produces:
|
||||
- text/plain
|
||||
responses: {}
|
||||
summary: Responds back with "Hello world!"
|
||||
tags:
|
||||
- debug
|
||||
/ping:
|
||||
get:
|
||||
produces:
|
||||
- text/plain
|
||||
responses: {}
|
||||
summary: Sends back "pong". Good to test with.
|
||||
tags:
|
||||
- debug
|
||||
/settings/{key}:
|
||||
get:
|
||||
parameters:
|
||||
- description: Settings Key value
|
||||
in: path
|
||||
name: key
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns a object based on the Key that was given/
|
||||
tags:
|
||||
- settings
|
||||
/subscriptions:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns the top 100 entries from the queue to be processed.
|
||||
tags:
|
||||
- config
|
||||
- Subscriptions
|
||||
/subscriptions/byDiscordId:
|
||||
get:
|
||||
parameters:
|
||||
- description: id
|
||||
in: query
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns the top 100 entries from the queue to be processed.
|
||||
tags:
|
||||
- config
|
||||
- Subscriptions
|
||||
/subscriptions/bySourceId:
|
||||
get:
|
||||
parameters:
|
||||
- description: id
|
||||
in: query
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses: {}
|
||||
summary: Returns the top 100 entries from the queue to be processed.
|
||||
tags:
|
||||
- config
|
||||
- Subscriptions
|
||||
swagger: "2.0"
|
2
go.mod
2
go.mod
@ -8,7 +8,6 @@ require (
|
||||
github.com/go-rod/rod v0.107.1
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/mmcdole/gofeed v1.1.3
|
||||
github.com/nicklaw5/helix/v2 v2.4.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
@ -26,6 +25,7 @@ require (
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mmcdole/goxpp v0.0.0-20200921145534-2f3784f67354 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
|
20
go.sum
20
go.sum
@ -25,8 +25,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
|
||||
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-rod/rod v0.105.1 h1:r0bNmO9siOe13lG6Vbkaak11u48rYmWGl/Hk4MJdOiE=
|
||||
github.com/go-rod/rod v0.105.1/go.mod h1:Wrnn6HokFHskwaIVke3ML1y/NBVp7XPIeB8eDzR9vuw=
|
||||
github.com/go-rod/rod v0.107.1 h1:wRxTTAXJ0JUnoSGcyGAOubpdrToWIKPCnLu3av8EDFY=
|
||||
github.com/go-rod/rod v0.107.1/go.mod h1:Au6ufsz7KyXUJVnw6Ljs1nFpsopy+9AJ/lBwGauYBVg=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ=
|
||||
@ -38,7 +36,6 @@ github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
@ -56,15 +53,12 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mmcdole/gofeed v1.1.3 h1:pdrvMb18jMSLidGp8j0pLvc9IGziX4vbmvVqmLH6z8o=
|
||||
github.com/mmcdole/gofeed v1.1.3/go.mod h1:QQO3maftbOu+hiVOGOZDRLymqGQCos4zxbA4j89gMrE=
|
||||
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/S/mDBM5plIU8v/Qhfz41hkDIAI=
|
||||
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
|
||||
github.com/mmcdole/goxpp v0.0.0-20200921145534-2f3784f67354 h1:Z6i7ND25ixRtXFBylIUggqpvLMV1I15yprcqMVB7WZA=
|
||||
github.com/mmcdole/goxpp v0.0.0-20200921145534-2f3784f67354/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
@ -82,12 +76,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc=
|
||||
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/http-swagger v1.2.8 h1:TVjxLU7qoqofJ9qynJazmpTGs/p4Kx9FTp7YYwOkJb0=
|
||||
github.com/swaggo/http-swagger v1.2.8/go.mod h1:FrQwV7rx+A5t11PIX8d+tFJa2GKx11RdAXQptllPQHg=
|
||||
github.com/swaggo/http-swagger v1.3.0 h1:1+6M4qRorIbdyTWTsGrwnb0r9jGK5dcWN82O6oY/yHQ=
|
||||
github.com/swaggo/http-swagger v1.3.0/go.mod h1:9glekdg40lwclrrKNRGgj/IMDxpNPZ3kzab4oPcF8EM=
|
||||
github.com/swaggo/swag v1.8.2 h1:D4aBiVS2a65zhyk3WFqOUz7Rz0sOaUcgeErcid5uGL4=
|
||||
@ -95,20 +85,17 @@ github.com/swaggo/swag v1.8.2/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBn
|
||||
github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/ysmood/goob v0.4.0 h1:HsxXhyLBeGzWXnqVKtmT9qM7EuVs/XOgkX7T6r1o1AQ=
|
||||
github.com/ysmood/goob v0.4.0/go.mod h1:u6yx7ZhS4Exf2MwciFr6nIM8knHQIE22lFpWHnfql18=
|
||||
github.com/ysmood/got v0.23.2 h1:U2U0vyQ/gDaawkKJZK/hyza8UUXbWCurbmazK7AcAfY=
|
||||
github.com/ysmood/got v0.23.2/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
|
||||
github.com/ysmood/got v0.29.5 h1:+wMnm8UjoyYFMfeAsr57a1bahWTkloysc0Hxsu2gmnM=
|
||||
github.com/ysmood/got v0.29.5/go.mod h1:pE1l4LOwOBhQg6A/8IAatkGp7uZjnalzrZolnlhhMgY=
|
||||
github.com/ysmood/gotrace v0.6.0 h1:SyI1d4jclswLhg7SWTL6os3L1WOKeNn/ZtzVQF8QmdY=
|
||||
github.com/ysmood/gotrace v0.6.0/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM=
|
||||
github.com/ysmood/gson v0.7.1 h1:zKL2MTGtynxdBdlZjyGsvEOZ7dkxaY5TH6QhAbTgz0Q=
|
||||
github.com/ysmood/gson v0.7.1/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
|
||||
github.com/ysmood/gson v0.7.2 h1:1iWUvpi5DPvd2j59W7ifRPR9DiAZ3Ga+fmMl1mJrRbM=
|
||||
github.com/ysmood/gson v0.7.2/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
|
||||
github.com/ysmood/leakless v0.7.0 h1:XCGdaPExyoreoQd+H5qgxM3ReNbSPFsEXpSKwbXbwQw=
|
||||
github.com/ysmood/leakless v0.7.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -119,8 +106,6 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68 h1:z8Hj/bl9cOV2grsOpEaQFUaly0JWN3i97mo3jXKJNp0=
|
||||
golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 h1:PgOr27OhUx2IRqGJ2RxAWI4dJQ7bi9cSrB82uzFzfUA=
|
||||
golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -130,11 +115,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
|
||||
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
|
34
main.go
34
main.go
@ -2,31 +2,29 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
|
||||
|
||||
_ "github.com/jtom38/newsbot/collector/docs"
|
||||
"github.com/jtom38/newsbot/collector/routes"
|
||||
"github.com/jtom38/newsbot/collector/services/cron"
|
||||
)
|
||||
|
||||
|
||||
|
||||
// @title NewsBot collector
|
||||
// @version 0.1
|
||||
// @BasePath /api
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
c := cron.New(ctx)
|
||||
c.Start()
|
||||
|
||||
cron.EnableScheduler(ctx)
|
||||
server := routes.NewServer(ctx)
|
||||
|
||||
app := chi.NewRouter()
|
||||
app.Use(middleware.Logger)
|
||||
app.Use(middleware.Recoverer)
|
||||
|
||||
//app.Mount("/swagger", httpSwagger.WrapHandler)
|
||||
app.Mount("/api", routes.RootRoutes())
|
||||
|
||||
log.Println("API is online and waiting for requests.")
|
||||
log.Println("API: http://localhost:8081/api")
|
||||
//log.Println("Swagger: http://localhost:8080/swagger/index.html")
|
||||
err := http.ListenAndServe(":8081", app)
|
||||
if err != nil { log.Fatalln(err) }
|
||||
fmt.Println("API is online and waiting for requests.")
|
||||
fmt.Println("API: http://localhost:8081/api")
|
||||
fmt.Println("Swagger: http://localhost:8081/swagger/index.html")
|
||||
err := http.ListenAndServe(":8081", server.Router)
|
||||
if err != nil { panic(err) }
|
||||
}
|
12
makefile
12
makefile
@ -3,6 +3,9 @@ help: ## Shows this help command
|
||||
@egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
build: ## builds the application with the current go runtime
|
||||
sqlc generate
|
||||
~/go/bin/swag f
|
||||
~/go/bin/swag i
|
||||
go build .
|
||||
|
||||
docker-build: ## Generates the docker image
|
||||
@ -13,4 +16,11 @@ migrate-dev: ## Apply sql migrations to dev db
|
||||
goose -dir "./database/migrations" postgres "user=postgres password=postgres dbname=postgres sslmode=disable" up
|
||||
|
||||
migrate-dev-down: ## revert sql migrations to dev db
|
||||
goose -dir "./database/migrations" postgres "user=postgres password=postgres dbname=postgres sslmode=disable" down
|
||||
goose -dir "./database/migrations" postgres "user=postgres password=postgres dbname=postgres sslmode=disable" down
|
||||
|
||||
swag: ## Generates the swagger documentation with the swag tool
|
||||
~/go/bin/swag f
|
||||
~/go/bin/swag i
|
||||
|
||||
gensql: ## Generates SQL code with sqlc
|
||||
sqlc generate
|
95
routes/articles.go
Normal file
95
routes/articles.go
Normal file
@ -0,0 +1,95 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ListArticles
|
||||
// @Summary Lists the top 50 records
|
||||
// @Produce application/json
|
||||
// @Tags articles
|
||||
// @Router /articles [get]
|
||||
func (s *Server) listArticles(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
res, err := s.Db.ListArticles(*s.ctx, 50)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
||||
|
||||
// GetArticleById
|
||||
// @Summary Returns an article based on defined ID.
|
||||
// @Param id path string true "uuid"
|
||||
// @Produce application/json
|
||||
// @Tags articles
|
||||
// @Router /articles/{id} [get]
|
||||
func (s *Server) getArticleById(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
id := chi.URLParam(r, "ID")
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
res, err := s.Db.GetArticleByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
||||
|
||||
// TODO add page support
|
||||
// GetArticlesBySourceID
|
||||
// @Summary Finds the articles based on the SourceID provided. Returns the top 50.
|
||||
// @Param id path string true "Source ID UUID"
|
||||
// @Produce application/json
|
||||
// @Tags articles
|
||||
// @Router /articles/by/sourceid/{id} [get]
|
||||
func (s *Server) GetArticlesBySourceId(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
id := chi.URLParam(r, "ID")
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
res, err := s.Db.GetArticlesBySourceId(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
29
routes/discordQueue.go
Normal file
29
routes/discordQueue.go
Normal file
@ -0,0 +1,29 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetDiscordQueue
|
||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||
// @Produce application/json
|
||||
// @Tags debug, Discord, Queue
|
||||
// @Router /discord/queue [get]
|
||||
func (s *Server) GetDiscordQueue(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
res, err := s.Db.GetDiscordQueueItems(*s.ctx, 100)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
115
routes/discordwebhooks.go
Normal file
115
routes/discordwebhooks.go
Normal file
@ -0,0 +1,115 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jtom38/newsbot/collector/database"
|
||||
)
|
||||
|
||||
// GetDiscordWebHooks
|
||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||
// @Produce application/json
|
||||
// @Tags config, Discord, Webhooks
|
||||
// @Router /discord/webhooks [get]
|
||||
func (s *Server) GetDiscordWebHooks(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
res, err := s.Db.ListDiscordWebhooks(*s.ctx, 100)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
||||
|
||||
// GetDiscorWebHooksById
|
||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||
// @Produce application/json
|
||||
// @Param id query string true "id"
|
||||
// @Tags config, Discord, Webhooks
|
||||
// @Router /discord/webhooks/byId [get]
|
||||
func (s *Server) GetDiscordWebHooksById(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
query := r.URL.Query()
|
||||
_id := query["id"][0]
|
||||
if _id == "" {
|
||||
http.Error(w, "id is missing", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
uuid, err := uuid.Parse(_id)
|
||||
if err != nil {
|
||||
http.Error(w, "unable to parse id value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := s.Db.GetDiscordWebHooksByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, "no record found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
http.Error(w, "unable to convert to json", http.StatusBadRequest)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
||||
|
||||
// NewDiscordWebHook
|
||||
// @Summary Creates a new record for a discord web hook to post data to.
|
||||
// @Param url query string true "url"
|
||||
// @Param server query string true "Server name"
|
||||
// @Param channel query string true "Channel name."
|
||||
// @Tags config, Discord, Webhooks
|
||||
// @Router /discord/webhooks/new [post]
|
||||
func (s *Server) NewDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
||||
query := r.URL.Query()
|
||||
_url := query["url"][0]
|
||||
_server := query["server"][0]
|
||||
_channel := query["channel"][0]
|
||||
|
||||
if _url == "" {
|
||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(_url, "discord.com/api/webhooks") {
|
||||
http.Error(w, "invalid url", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if _server == ""{
|
||||
http.Error(w, "server is missing", http.StatusBadRequest)
|
||||
}
|
||||
if _channel == "" {
|
||||
http.Error(w, "channel is missing", http.StatusBadRequest)
|
||||
}
|
||||
params := database.CreateDiscordWebHookParams{
|
||||
ID: uuid.New(),
|
||||
Url: _url,
|
||||
Server: _server,
|
||||
Channel: _channel,
|
||||
Enabled: true,
|
||||
}
|
||||
s.Db.CreateDiscordWebHook(*s.ctx, params)
|
||||
|
||||
bJson, err := json.Marshal(¶ms)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bJson)
|
||||
}
|
@ -1,25 +1,50 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func RootRoutes() chi.Router {
|
||||
app := chi.NewRouter()
|
||||
app.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("Hello World!"))
|
||||
})
|
||||
|
||||
app.Get("/ping", func(w http.ResponseWriter, r *http.Request) {
|
||||
msg := "pong"
|
||||
w.Write([]byte(msg))
|
||||
})
|
||||
|
||||
app.Get("/hello/{world}", func(w http.ResponseWriter, r *http.Request) {
|
||||
msg := fmt.Sprintf("Hello %v", chi.URLParam(r, "world"))
|
||||
w.Write([]byte(msg))
|
||||
app.Route("/", func(r chi.Router) {
|
||||
r.Get("/helloworld", helloWorld)
|
||||
r.Get("/ping", ping)
|
||||
r.Route("/hello/{who}", func(r chi.Router) {
|
||||
r.Get("/", helloWho)
|
||||
})
|
||||
})
|
||||
return app
|
||||
}
|
||||
}
|
||||
|
||||
// HelloWorld
|
||||
// @Summary Responds back with "Hello world!"
|
||||
// @Produce plain
|
||||
// @Tags debug
|
||||
// @Router /helloworld [get]
|
||||
func helloWorld(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("Hello World!"))
|
||||
}
|
||||
|
||||
// Ping
|
||||
// @Summary Sends back "pong". Good to test with.
|
||||
// @Produce plain
|
||||
// @Tags debug
|
||||
// @Router /ping [get]
|
||||
func ping(w http.ResponseWriter, r *http.Request) {
|
||||
msg := "pong"
|
||||
w.Write([]byte(msg))
|
||||
}
|
||||
|
||||
// HelloWho
|
||||
// @Summary Responds back with "Hello x" depending on param passed in.
|
||||
// @Param who path string true "Who"
|
||||
// @Produce plain
|
||||
// @Tags debug
|
||||
// @Router /hello/{who} [get]
|
||||
func helloWho(w http.ResponseWriter, r *http.Request) {
|
||||
msg := fmt.Sprintf("Hello %v", chi.URLParam(r, "who"))
|
||||
w.Write([]byte(msg))
|
||||
}
|
||||
|
2
routes/root_test.go
Normal file
2
routes/root_test.go
Normal file
@ -0,0 +1,2 @@
|
||||
package routes_test
|
||||
|
108
routes/server.go
Normal file
108
routes/server.go
Normal file
@ -0,0 +1,108 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
//"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
httpSwagger "github.com/swaggo/http-swagger"
|
||||
_ "github.com/lib/pq"
|
||||
|
||||
"github.com/jtom38/newsbot/collector/database"
|
||||
"github.com/jtom38/newsbot/collector/services/config"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Router *chi.Mux
|
||||
Db *database.Queries
|
||||
ctx *context.Context
|
||||
}
|
||||
|
||||
var (
|
||||
ErrIdValueMissing string = "id value is missing"
|
||||
ErrValueNotUuid string = "a value given was expected to be a uuid but was not correct."
|
||||
ErrNoRecordFound string = "no record was found."
|
||||
ErrUnableToConvertToJson string = "Unable to convert to json"
|
||||
)
|
||||
|
||||
func NewServer(ctx context.Context) *Server {
|
||||
s := &Server{
|
||||
ctx: &ctx,
|
||||
}
|
||||
|
||||
db, err := openDatabase(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.Db = db
|
||||
|
||||
s.Router = chi.NewRouter()
|
||||
s.MountMiddleware()
|
||||
s.MountRoutes()
|
||||
return s
|
||||
}
|
||||
|
||||
func openDatabase(ctx context.Context) (*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 (s *Server) MountMiddleware() {
|
||||
s.Router.Use(middleware.Logger)
|
||||
s.Router.Use(middleware.Recoverer)
|
||||
}
|
||||
|
||||
func (s *Server) MountRoutes() {
|
||||
s.Router.Get("/swagger/*", httpSwagger.Handler(
|
||||
httpSwagger.URL("http://localhost:8081/swagger/doc.json"), //The url pointing to API definition
|
||||
))
|
||||
|
||||
/* Root Routes */
|
||||
s.Router.Get("/api/helloworld", helloWorld)
|
||||
s.Router.Get("/api/hello/{who}", helloWho)
|
||||
s.Router.Get("/api/ping", ping)
|
||||
|
||||
/* Article Routes */
|
||||
s.Router.Get("/api/articles", s.listArticles)
|
||||
s.Router.Route("/api/articles/{ID}", func(r chi.Router) {
|
||||
r.Get("/", s.getArticleById)
|
||||
})
|
||||
s.Router.Get("/api/articles/by/sourceid", s.GetArticlesBySourceId)
|
||||
|
||||
/* Discord Queue */
|
||||
s.Router.Get("/api/discord/queue", s.GetDiscordQueue)
|
||||
|
||||
/* Discord WebHooks */
|
||||
s.Router.Post("/api/discord/webhooks/new", s.NewDiscordWebHook)
|
||||
s.Router.Get("/api/discord/webhooks", s.GetDiscordWebHooks)
|
||||
s.Router.Get("/api/discord/webhooks/byId", s.GetDiscordWebHooksById)
|
||||
|
||||
/* Settings */
|
||||
s.Router.Get("/api/settings", s.getSettings)
|
||||
|
||||
/* Source Routes */
|
||||
s.Router.Get("/api/config/sources", s.listSources)
|
||||
s.Router.Post("/api/config/sources/new/reddit", s.newRedditSource)
|
||||
s.Router.Post("/api/config/sources/new/youtube", s.newYoutubeSource)
|
||||
s.Router.Post("/api/config/sources/new/twitch", s.newTwitchSource)
|
||||
s.Router.Route("/api/config/sources/{ID}", func(r chi.Router) {
|
||||
r.Get("/", s.getSources)
|
||||
r.Delete("/", s.deleteSources)
|
||||
r.Post("/disable", s.disableSource)
|
||||
r.Post("/enable", s.enableSource)
|
||||
})
|
||||
|
||||
/* Subscriptions */
|
||||
s.Router.Get("/api/subscriptions", s.ListSubscriptions)
|
||||
s.Router.Get("/api/subscriptions/byDiscordId", s.GetSubscriptionsByDiscordId)
|
||||
s.Router.Get("/api/subscriptions/bySourceId", s.GetSubscriptionsBySourceId)
|
||||
}
|
44
routes/settings.go
Normal file
44
routes/settings.go
Normal file
@ -0,0 +1,44 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// GetSettings
|
||||
// @Summary Returns a object based on the Key that was given/
|
||||
// @Param key path string true "Settings Key value"
|
||||
// @Produce application/json
|
||||
// @Tags settings
|
||||
// @Router /settings/{key} [get]
|
||||
func (s *Server) getSettings(w http.ResponseWriter, r *http.Request) {
|
||||
//var item model.Sources
|
||||
id := chi.URLParam(r, "ID")
|
||||
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
res, err := s.Db.GetSourceByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//itemId := fmt.Sprint(item.ID)
|
||||
//if id != itemId {
|
||||
// log.Panicln("Unable to find the requested record. Either unable to access SQL or the record does not exist.")
|
||||
//}
|
||||
|
||||
bResult, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bResult)
|
||||
}
|
278
routes/sources.go
Normal file
278
routes/sources.go
Normal file
@ -0,0 +1,278 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jtom38/newsbot/collector/database"
|
||||
)
|
||||
|
||||
// ListSources
|
||||
// @Summary Lists the top 50 records
|
||||
// @Produce application/json
|
||||
// @Tags config, source
|
||||
// @Router /config/sources [get]
|
||||
func (s *Server) listSources(w http.ResponseWriter, r *http.Request) {
|
||||
//TODO Add top?
|
||||
/*
|
||||
top := chi.URLParam(r, "top")
|
||||
topInt, err := strconv.ParseInt(top, 0, 32)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
res, err := s.Db.ListSources(*s.ctx, int32(topInt))
|
||||
*/
|
||||
|
||||
res, err := s.Db.ListSources(*s.ctx, 50)
|
||||
if err != nil {
|
||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
bResult, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
http.Error(w, "unable to convert to json", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bResult)
|
||||
}
|
||||
|
||||
// GetSource
|
||||
// @Summary Returns a single entity by ID
|
||||
// @Param id path string true "uuid"
|
||||
// @Produce application/json
|
||||
// @Tags config, source
|
||||
// @Router /config/sources/{id} [get]
|
||||
func (s *Server) getSources(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "ID")
|
||||
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
http.Error(w, "id is not a uuid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := s.Db.GetSourceByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, "invalid id was given", http.StatusBadRequest)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bResult, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bResult)
|
||||
}
|
||||
|
||||
// NewRedditSource
|
||||
// @Summary Creates a new reddit source to monitor.
|
||||
// @Param name query string true "name"
|
||||
// @Param url query string true "url"
|
||||
// @Tags config, source, reddit
|
||||
// @Router /config/sources/new/reddit [post]
|
||||
func (s *Server) newRedditSource(w http.ResponseWriter, r *http.Request) {
|
||||
query := r.URL.Query()
|
||||
_name := query["name"][0]
|
||||
_url := query["url"][0]
|
||||
_tags := query["tags"][0]
|
||||
|
||||
if _url == "" {
|
||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(_url, "reddit.com") {
|
||||
http.Error(w, "invalid url", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
tags := fmt.Sprintf("reddit, %v, %v", _name, _tags)
|
||||
params := database.CreateSourceParams{
|
||||
ID: uuid.New(),
|
||||
Site: "reddit",
|
||||
Name: _name,
|
||||
Source: "reddit",
|
||||
Type: "feed",
|
||||
Enabled: true,
|
||||
Url: _url,
|
||||
Tags: tags,
|
||||
}
|
||||
s.Db.CreateSource(*s.ctx, params)
|
||||
|
||||
bJson, err := json.Marshal(¶ms)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bJson)
|
||||
}
|
||||
|
||||
// NewYoutubeSource
|
||||
// @Summary Creates a new youtube source to monitor.
|
||||
// @Param name query string true "name"
|
||||
// @Param url query string true "url"
|
||||
// @Param tags query string true "tags"
|
||||
// @Tags config, source, youtube
|
||||
// @Router /config/sources/new/youtube [post]
|
||||
func (s *Server) newYoutubeSource(w http.ResponseWriter, r *http.Request) {
|
||||
query := r.URL.Query()
|
||||
_name := query["name"][0]
|
||||
_url := query["url"][0]
|
||||
_tags := query["tags"][0]
|
||||
|
||||
if _url == "" {
|
||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(_url, "youtube.com") {
|
||||
http.Error(w, "invalid url", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
tags := fmt.Sprintf("youtube, %v, %v", _name, _tags)
|
||||
params := database.CreateSourceParams{
|
||||
ID: uuid.New(),
|
||||
Site: "youtube",
|
||||
Name: _name,
|
||||
Source: "youtube",
|
||||
Type: "feed",
|
||||
Enabled: true,
|
||||
Url: _url,
|
||||
Tags: tags,
|
||||
}
|
||||
s.Db.CreateSource(*s.ctx, params)
|
||||
|
||||
bJson, err := json.Marshal(¶ms)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bJson)
|
||||
}
|
||||
|
||||
// NewTwitchSource
|
||||
// @Summary Creates a new twitch source to monitor.
|
||||
// @Param name query string true "name"
|
||||
// @Param url query string true "url"
|
||||
// @Param tags query string true "tags"
|
||||
// @Tags config, source, twitch
|
||||
// @Router /config/sources/new/twitch [post]
|
||||
func (s *Server) newTwitchSource(w http.ResponseWriter, r *http.Request) {
|
||||
query := r.URL.Query()
|
||||
_name := query["name"][0]
|
||||
_url := query["url"][0]
|
||||
_tags := query["tags"][0]
|
||||
|
||||
if _url == "" {
|
||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if !strings.Contains(_url, "twitch.tv") {
|
||||
http.Error(w, "invalid url", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
tags := fmt.Sprintf("twitch, %v, %v", _name, _tags)
|
||||
params := database.CreateSourceParams{
|
||||
ID: uuid.New(),
|
||||
Site: "twitch",
|
||||
Name: _name,
|
||||
Source: "twitch",
|
||||
Type: "api",
|
||||
Enabled: true,
|
||||
Url: _url,
|
||||
Tags: tags,
|
||||
}
|
||||
s.Db.CreateSource(*s.ctx, params)
|
||||
|
||||
bJson, err := json.Marshal(¶ms)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(bJson)
|
||||
}
|
||||
|
||||
// DeleteSource
|
||||
// @Summary Deletes a record by ID.
|
||||
// @Param id path string true "id"
|
||||
// @Tags config, source
|
||||
// @Router /config/sources/{id} [delete]
|
||||
func (s *Server) deleteSources(w http.ResponseWriter, r *http.Request) {
|
||||
//var item model.Sources = model.Sources{}
|
||||
|
||||
id := chi.URLParam(r, "ID")
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
// Check to make sure we can find the record
|
||||
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
// Delete the record
|
||||
err = s.Db.DeleteSource(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// DisableSource
|
||||
// @Summary Disables a source from processing.
|
||||
// @Param id path string true "id"
|
||||
// @Tags config, source
|
||||
// @Router /config/sources/{id}/disable [post]
|
||||
func (s *Server) disableSource(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "ID")
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
// Check to make sure we can find the record
|
||||
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
err = s.Db.DisableSource(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// EnableSource
|
||||
// @Summary Enables a source to continue processing.
|
||||
// @Param id path string true "id"
|
||||
// @Tags config, source
|
||||
// @Router /config/sources/{id}/enable [post]
|
||||
func (s *Server) enableSource(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "ID")
|
||||
uuid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
// Check to make sure we can find the record
|
||||
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
err = s.Db.EnableSource(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
105
routes/subscriptions.go
Normal file
105
routes/subscriptions.go
Normal file
@ -0,0 +1,105 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// GetSubscriptions
|
||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||
// @Produce application/json
|
||||
// @Tags config, Subscriptions
|
||||
// @Router /subscriptions [get]
|
||||
func (s *Server) ListSubscriptions(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
res, err := s.Db.ListSubscriptions(*s.ctx, 100)
|
||||
if err != nil {
|
||||
w.Write([]byte(err.Error()))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
http.Error(w, ErrUnableToConvertToJson, http.StatusBadRequest)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
||||
|
||||
// GetSubscriptionsByDiscordId
|
||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||
// @Produce application/json
|
||||
// @Param id query string true "id"
|
||||
// @Tags config, Subscriptions
|
||||
// @Router /subscriptions/byDiscordId [get]
|
||||
func (s *Server) GetSubscriptionsByDiscordId(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
query := r.URL.Query()
|
||||
_id := query["id"][0]
|
||||
if _id == "" {
|
||||
http.Error(w, ErrIdValueMissing, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
uuid, err := uuid.Parse(_id)
|
||||
if err != nil {
|
||||
http.Error(w, ErrValueNotUuid, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := s.Db.GetSubscriptionsByDiscordWebHookId(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, ErrNoRecordFound, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
http.Error(w, ErrUnableToConvertToJson, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
||||
|
||||
// GetSubscriptionsBySourceId
|
||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||
// @Produce application/json
|
||||
// @Param id query string true "id"
|
||||
// @Tags config, Subscriptions
|
||||
// @Router /subscriptions/bySourceId [get]
|
||||
func (s *Server) GetSubscriptionsBySourceId(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
query := r.URL.Query()
|
||||
_id := query["id"][0]
|
||||
if _id == "" {
|
||||
http.Error(w, ErrIdValueMissing, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
uuid, err := uuid.Parse(_id)
|
||||
if err != nil {
|
||||
http.Error(w, ErrValueNotUuid, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := s.Db.GetSubscriptionsByDiscordWebHookId(*s.ctx, uuid)
|
||||
if err != nil {
|
||||
http.Error(w, ErrNoRecordFound, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
bres, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
http.Error(w, ErrUnableToConvertToJson, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(bres)
|
||||
}
|
@ -15,40 +15,56 @@ import (
|
||||
"github.com/jtom38/newsbot/collector/services/config"
|
||||
)
|
||||
|
||||
var _env config.ConfigClient
|
||||
var _connString string
|
||||
var _queries *database.Queries
|
||||
|
||||
func EnableScheduler(ctx context.Context) {
|
||||
c := cron.New()
|
||||
OpenDatabase(ctx)
|
||||
|
||||
//c.AddFunc("*/5 * * * *", func() { go CheckCache() })
|
||||
c.AddFunc("* */1 * * *", func() { go CheckReddit(ctx) })
|
||||
//c.AddFunc("* */1 * * *", func() { go CheckYoutube() })
|
||||
//c.AddFunc("* */1 * * *", func() { go CheckFfxiv() })
|
||||
//c.AddFunc("* */1 * * *", func() { go CheckTwitch() })
|
||||
|
||||
c.Start()
|
||||
type Cron struct {
|
||||
Db *database.Queries
|
||||
ctx *context.Context
|
||||
timer *cron.Cron
|
||||
}
|
||||
|
||||
// Open the connection to the database and share it with the package so all of them are able to share.
|
||||
func OpenDatabase(ctx context.Context) error {
|
||||
_env = config.New()
|
||||
_connString = _env.GetConfig(config.Sql_Connection_String)
|
||||
db, err := sql.Open("postgres", _connString)
|
||||
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)
|
||||
_queries = queries
|
||||
return err
|
||||
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 CheckReddit(ctx context.Context) {
|
||||
sources, err := _queries.ListSourcesBySource(ctx, "reddit")
|
||||
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)
|
||||
}
|
||||
@ -63,13 +79,13 @@ func CheckReddit(ctx context.Context) {
|
||||
log.Println(err)
|
||||
}
|
||||
redditArticles := rc.ConvertToArticles(raw)
|
||||
checkPosts(ctx, redditArticles)
|
||||
c.checkPosts(*c.ctx, redditArticles)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckYoutube(ctx context.Context) {
|
||||
func (c *Cron) CheckYoutube(ctx context.Context) {
|
||||
// Add call to the db to request youtube sources.
|
||||
sources, err := _queries.ListSourcesBySource(ctx, "youtube")
|
||||
sources, err := c.Db.ListSourcesBySource(*c.ctx, "youtube")
|
||||
if err != nil {
|
||||
log.Printf("Youtube - No sources found to query - %v\r", err)
|
||||
}
|
||||
@ -83,12 +99,12 @@ func CheckYoutube(ctx context.Context) {
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
checkPosts(ctx, raw)
|
||||
c.checkPosts(*c.ctx, raw)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckFfxiv(ctx context.Context) {
|
||||
sources, err := _queries.ListSourcesBySource(ctx, "ffxiv")
|
||||
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)
|
||||
}
|
||||
@ -102,12 +118,12 @@ func CheckFfxiv(ctx context.Context) {
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
checkPosts(ctx, items)
|
||||
c.checkPosts(*c.ctx, items)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckTwitch(ctx context.Context) error {
|
||||
sources, err := _queries.ListSourcesBySource(ctx, "twitch")
|
||||
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)
|
||||
}
|
||||
@ -126,17 +142,17 @@ func CheckTwitch(ctx context.Context) error {
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
checkPosts(ctx, items)
|
||||
c.checkPosts(*c.ctx, items)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPosts(ctx context.Context, posts []database.Article) {
|
||||
func (c *Cron) checkPosts(ctx context.Context, posts []database.Article) {
|
||||
for _, item := range posts {
|
||||
_, err := _queries.GetArticleByUrl(ctx, item.Url)
|
||||
_, err := c.Db.GetArticleByUrl(*c.ctx, item.Url)
|
||||
if err != nil {
|
||||
err = postArticle(ctx, item)
|
||||
err = c.postArticle(ctx, item)
|
||||
if err != nil {
|
||||
log.Printf("Reddit - Failed to post article - %v - %v.\r", item.Url, err)
|
||||
} else {
|
||||
@ -147,8 +163,8 @@ func checkPosts(ctx context.Context, posts []database.Article) {
|
||||
time.Sleep(30 * time.Second)
|
||||
}
|
||||
|
||||
func postArticle(ctx context.Context, item database.Article) error {
|
||||
err := _queries.CreateArticle(ctx, database.CreateArticleParams{
|
||||
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,
|
||||
|
@ -14,23 +14,20 @@ func TestInvokeTwitch(t *testing.T) {
|
||||
// TODO add database mocks but not sure how to do that yet.
|
||||
func TestCheckReddit(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cron.OpenDatabase(ctx)
|
||||
cron.CheckReddit(ctx)
|
||||
c := cron.Cron{}
|
||||
c.CheckReddit(ctx)
|
||||
}
|
||||
|
||||
func TestCheckYouTube(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cron.OpenDatabase(ctx)
|
||||
cron.CheckYoutube(ctx)
|
||||
c := cron.Cron{}
|
||||
c.CheckYoutube(ctx)
|
||||
}
|
||||
|
||||
func TestCheckTwitch(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
err := cron.OpenDatabase(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = cron.CheckTwitch(ctx)
|
||||
c := cron.Cron{}
|
||||
err := c.CheckTwitch(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user