Features/delete source and first dto (#36)
* updated db, added dto for ListSources, and added delete source * updated from model > models * updated to models * sources now sends back a standard message * updated subscription routes to have beter logid and swagger details * moved the dto objects back to modles given they are not bound to the database * cleaned up how we return the error * cleaned up swag and updated models to take from the base apistatusmodel. less human errors this way * cleaned up swag and updated models * swag updated * updated queue to return a router and also renamed it as it will hold all queue info later on * removed config tag * added subscription details route * article routes have been moved to support dto * updated discordwebhooks to use dto * updated discordwebhookqueue to return details on the items via dto * removed the example routes * updated sources to use dto * subscriptions moved to dto * generated swag
This commit is contained in:
parent
a2147294d5
commit
ada453e08a
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.13.0
|
// sqlc v1.16.0
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.13.0
|
// sqlc v1.16.0
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.13.0
|
// sqlc v1.16.0
|
||||||
// source: query.sql
|
// source: query.sql
|
||||||
|
|
||||||
package database
|
package database
|
||||||
|
1128
docs/docs.go
1128
docs/docs.go
File diff suppressed because it is too large
Load Diff
1128
docs/swagger.json
1128
docs/swagger.json
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,239 @@
|
|||||||
basePath: /api
|
basePath: /api
|
||||||
|
definitions:
|
||||||
|
models.ArticleDetailsDto:
|
||||||
|
properties:
|
||||||
|
authorImage:
|
||||||
|
type: string
|
||||||
|
authorName:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
pubdate:
|
||||||
|
type: string
|
||||||
|
source:
|
||||||
|
$ref: '#/definitions/models.SourceDto'
|
||||||
|
tags:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
thumbnail:
|
||||||
|
type: string
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
video:
|
||||||
|
type: string
|
||||||
|
videoHeight:
|
||||||
|
type: integer
|
||||||
|
videoWidth:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
models.ArticleDto:
|
||||||
|
properties:
|
||||||
|
authorImage:
|
||||||
|
type: string
|
||||||
|
authorName:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
pubdate:
|
||||||
|
type: string
|
||||||
|
sourceid:
|
||||||
|
type: string
|
||||||
|
tags:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
thumbnail:
|
||||||
|
type: string
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
video:
|
||||||
|
type: string
|
||||||
|
videoHeight:
|
||||||
|
type: integer
|
||||||
|
videoWidth:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
models.DiscordQueueDetailsDto:
|
||||||
|
properties:
|
||||||
|
article:
|
||||||
|
$ref: '#/definitions/models.ArticleDetailsDto'
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
models.DiscordWebHooksDto:
|
||||||
|
properties:
|
||||||
|
ID:
|
||||||
|
type: string
|
||||||
|
channel:
|
||||||
|
type: string
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
server:
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
models.SourceDto:
|
||||||
|
properties:
|
||||||
|
deleted:
|
||||||
|
type: boolean
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
site:
|
||||||
|
type: string
|
||||||
|
source:
|
||||||
|
type: string
|
||||||
|
tags:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
url:
|
||||||
|
type: string
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
models.SubscriptionDetailsDto:
|
||||||
|
properties:
|
||||||
|
discordwebhook:
|
||||||
|
$ref: '#/definitions/models.DiscordWebHooksDto'
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
source:
|
||||||
|
$ref: '#/definitions/models.SourceDto'
|
||||||
|
type: object
|
||||||
|
models.SubscriptionDto:
|
||||||
|
properties:
|
||||||
|
discordwebhookid:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
sourceid:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
routes.ApiError:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ArticleDetailsResult:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
$ref: '#/definitions/models.ArticleDetailsDto'
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ArticleGetResults:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
$ref: '#/definitions/models.ArticleDto'
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ArticlesListResults:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.ArticleDto'
|
||||||
|
type: array
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.GetDiscordWebhook:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
$ref: '#/definitions/models.DiscordWebHooksDto'
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.GetSource:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
$ref: '#/definitions/models.SourceDto'
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ListDiscordWebHooksQueueResults:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.DiscordQueueDetailsDto'
|
||||||
|
type: array
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ListDiscordWebhooks:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.DiscordWebHooksDto'
|
||||||
|
type: array
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ListSources:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.SourceDto'
|
||||||
|
type: array
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ListSubscriptionDetails:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.SubscriptionDetailsDto'
|
||||||
|
type: array
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
routes.ListSubscriptions:
|
||||||
|
properties:
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/models.SubscriptionDto'
|
||||||
|
type: array
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
info:
|
info:
|
||||||
contact: {}
|
contact: {}
|
||||||
title: NewsBot collector
|
title: NewsBot collector
|
||||||
@ -8,7 +243,11 @@ paths:
|
|||||||
get:
|
get:
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ArticlesListResults'
|
||||||
summary: Lists the top 50 records
|
summary: Lists the top 50 records
|
||||||
tags:
|
tags:
|
||||||
- Articles
|
- Articles
|
||||||
@ -17,15 +256,37 @@ paths:
|
|||||||
parameters:
|
parameters:
|
||||||
- description: uuid
|
- description: uuid
|
||||||
in: path
|
in: path
|
||||||
name: id
|
name: ID
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ArticleGetResults'
|
||||||
summary: Returns an article based on defined ID.
|
summary: Returns an article based on defined ID.
|
||||||
tags:
|
tags:
|
||||||
- Articles
|
- Articles
|
||||||
|
/articles/{ID}/details:
|
||||||
|
get:
|
||||||
|
parameters:
|
||||||
|
- description: uuid
|
||||||
|
in: path
|
||||||
|
name: ID
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ArticleDetailsResult'
|
||||||
|
summary: Returns an article and source based on defined ID.
|
||||||
|
tags:
|
||||||
|
- Articles
|
||||||
/articles/by/sourceid:
|
/articles/by/sourceid:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
@ -36,184 +297,15 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ArticlesListResults'
|
||||||
summary: Finds the articles based on the SourceID provided. Returns the top
|
summary: Finds the articles based on the SourceID provided. Returns the top
|
||||||
50.
|
50.
|
||||||
tags:
|
tags:
|
||||||
- Articles
|
- Articles
|
||||||
/articles/by/tag:
|
|
||||||
get:
|
|
||||||
parameters:
|
|
||||||
- description: Tag name
|
|
||||||
in: query
|
|
||||||
name: tag
|
|
||||||
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}:
|
|
||||||
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
|
|
||||||
post:
|
|
||||||
parameters:
|
|
||||||
- description: id
|
|
||||||
in: path
|
|
||||||
name: id
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses: {}
|
|
||||||
summary: Marks a source as deleted based on its ID value.
|
|
||||||
tags:
|
|
||||||
- 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/by/source:
|
|
||||||
get:
|
|
||||||
parameters:
|
|
||||||
- description: Source Name
|
|
||||||
in: query
|
|
||||||
name: source
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses: {}
|
|
||||||
summary: 'Lists the top 50 records based on the name given. Example: reddit'
|
|
||||||
tags:
|
|
||||||
- Config
|
|
||||||
- Source
|
|
||||||
/config/sources/by/sourceAndName:
|
|
||||||
get:
|
|
||||||
parameters:
|
|
||||||
- description: dadjokes
|
|
||||||
in: query
|
|
||||||
name: name
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- description: reddit
|
|
||||||
in: query
|
|
||||||
name: source
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses: {}
|
|
||||||
summary: Returns a single entity by ID
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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:
|
/discord/webhooks:
|
||||||
get:
|
get:
|
||||||
produces:
|
produces:
|
||||||
@ -221,10 +313,9 @@ paths:
|
|||||||
responses: {}
|
responses: {}
|
||||||
summary: Returns the top 100 entries from the queue to be processed.
|
summary: Returns the top 100 entries from the queue to be processed.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Discord
|
- Discord
|
||||||
- Webhook
|
- Webhook
|
||||||
/discord/webhooks/{id}:
|
/discord/webhooks/{ID}:
|
||||||
delete:
|
delete:
|
||||||
parameters:
|
parameters:
|
||||||
- description: id
|
- description: id
|
||||||
@ -235,9 +326,35 @@ paths:
|
|||||||
responses: {}
|
responses: {}
|
||||||
summary: Deletes a record by ID.
|
summary: Deletes a record by ID.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Discord
|
- Discord
|
||||||
- Webhook
|
- Webhook
|
||||||
|
/discord/webhooks/{ID}/disable:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses: {}
|
||||||
|
summary: Disables a Webhook from being used.
|
||||||
|
tags:
|
||||||
|
- Discord
|
||||||
|
- Webhook
|
||||||
|
/discord/webhooks/{ID}/enable:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses: {}
|
||||||
|
summary: Enables a source to continue processing.
|
||||||
|
tags:
|
||||||
|
- Discord
|
||||||
|
- Webhook
|
||||||
|
/discord/webhooks/{id}:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
- description: id
|
- description: id
|
||||||
@ -247,10 +364,13 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.GetDiscordWebhook'
|
||||||
summary: Returns the top 100 entries from the queue to be processed.
|
summary: Returns the top 100 entries from the queue to be processed.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Discord
|
- Discord
|
||||||
- Webhook
|
- Webhook
|
||||||
patch:
|
patch:
|
||||||
@ -263,35 +383,6 @@ paths:
|
|||||||
responses: {}
|
responses: {}
|
||||||
summary: Updates a valid discord webhook ID based on the body given.
|
summary: Updates a valid discord webhook ID based on the body given.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Discord
|
|
||||||
- Webhook
|
|
||||||
/discord/webhooks/{id}/disable:
|
|
||||||
post:
|
|
||||||
parameters:
|
|
||||||
- description: id
|
|
||||||
in: path
|
|
||||||
name: id
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses: {}
|
|
||||||
summary: Disables a Webhook from being used.
|
|
||||||
tags:
|
|
||||||
- Config
|
|
||||||
- Discord
|
|
||||||
- Webhook
|
|
||||||
/discord/webhooks/{id}/enable:
|
|
||||||
post:
|
|
||||||
parameters:
|
|
||||||
- description: id
|
|
||||||
in: path
|
|
||||||
name: id
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses: {}
|
|
||||||
summary: Enables a source to continue processing.
|
|
||||||
tags:
|
|
||||||
- Config
|
|
||||||
- Discord
|
- Discord
|
||||||
- Webhook
|
- Webhook
|
||||||
/discord/webhooks/by/serverAndChannel:
|
/discord/webhooks/by/serverAndChannel:
|
||||||
@ -309,10 +400,13 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListDiscordWebhooks'
|
||||||
summary: Returns all the known web hooks based on the Server and Channel given.
|
summary: Returns all the known web hooks based on the Server and Channel given.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Discord
|
- Discord
|
||||||
- Webhook
|
- Webhook
|
||||||
/discord/webhooks/new:
|
/discord/webhooks/new:
|
||||||
@ -336,62 +430,229 @@ paths:
|
|||||||
responses: {}
|
responses: {}
|
||||||
summary: Creates a new record for a discord web hook to post data to.
|
summary: Creates a new record for a discord web hook to post data to.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Discord
|
- Discord
|
||||||
- Webhook
|
- Webhook
|
||||||
/hello/{who}:
|
/queue/discord/webhooks:
|
||||||
|
get:
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListDiscordWebHooksQueueResults'
|
||||||
|
summary: Returns the top 100 entries from the queue to be processed.
|
||||||
|
tags:
|
||||||
|
- Queue
|
||||||
|
/sources:
|
||||||
|
get:
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListSources'
|
||||||
|
"400":
|
||||||
|
description: Unable to reach SQL or Data problems
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
summary: Lists the top 50 records
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/sources/{id}:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
- description: Who
|
- description: uuid
|
||||||
in: path
|
in: path
|
||||||
name: who
|
name: id
|
||||||
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
|
required: true
|
||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
summary: Returns a object based on the Key that was given.
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.GetSource'
|
||||||
|
"204":
|
||||||
|
description: No record found.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"400":
|
||||||
|
description: Unable to query SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"500":
|
||||||
|
description: Failed to process data from SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
summary: Returns a single entity by ID
|
||||||
tags:
|
tags:
|
||||||
- Settings
|
- Source
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses: {}
|
||||||
|
summary: Marks a source as deleted based on its ID value.
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/sources/{id}/disable:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses: {}
|
||||||
|
summary: Disables a source from processing.
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/sources/{id}/enable:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: id
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses: {}
|
||||||
|
summary: Enables a source to continue processing.
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/sources/by/source:
|
||||||
|
get:
|
||||||
|
parameters:
|
||||||
|
- description: Source Name
|
||||||
|
in: query
|
||||||
|
name: source
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListSources'
|
||||||
|
"400":
|
||||||
|
description: Unable to query SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"500":
|
||||||
|
description: Problems with data.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
summary: 'Lists the top 50 records based on the name given. Example: reddit'
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/sources/by/sourceAndName:
|
||||||
|
get:
|
||||||
|
parameters:
|
||||||
|
- description: dadjokes
|
||||||
|
in: query
|
||||||
|
name: name
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: reddit
|
||||||
|
in: query
|
||||||
|
name: source
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.GetSource'
|
||||||
|
"204":
|
||||||
|
description: No record found.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"400":
|
||||||
|
description: Unable to query SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"500":
|
||||||
|
description: Failed to process data from SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
summary: Returns a single entity by ID
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/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:
|
||||||
|
- Source
|
||||||
|
/sources/new/twitch:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: name
|
||||||
|
in: query
|
||||||
|
name: name
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses: {}
|
||||||
|
summary: Creates a new twitch source to monitor.
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
|
/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
|
||||||
|
responses: {}
|
||||||
|
summary: Creates a new youtube source to monitor.
|
||||||
|
tags:
|
||||||
|
- Source
|
||||||
/subscriptions:
|
/subscriptions:
|
||||||
get:
|
get:
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListSubscriptions'
|
||||||
|
"400":
|
||||||
|
description: Unable to reach SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"500":
|
||||||
|
description: Failed to process data from SQL.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
summary: Returns the top 100 entries from the queue to be processed.
|
summary: Returns the top 100 entries from the queue to be processed.
|
||||||
tags:
|
tags:
|
||||||
- Subscription
|
- Subscription
|
||||||
/subscriptions/byDiscordId:
|
/subscriptions/by/SourceId:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
- description: id
|
- description: id
|
||||||
@ -401,11 +662,15 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListSubscriptions'
|
||||||
summary: Returns the top 100 entries from the queue to be processed.
|
summary: Returns the top 100 entries from the queue to be processed.
|
||||||
tags:
|
tags:
|
||||||
- Subscription
|
- Subscription
|
||||||
/subscriptions/bySourceId:
|
/subscriptions/by/discordId:
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
- description: id
|
- description: id
|
||||||
@ -415,26 +680,47 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses: {}
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListSubscriptions'
|
||||||
|
"400":
|
||||||
|
description: Unable to reach SQL or Data problems
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
|
"500":
|
||||||
|
description: Data problems
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ApiError'
|
||||||
summary: Returns the top 100 entries from the queue to be processed.
|
summary: Returns the top 100 entries from the queue to be processed.
|
||||||
tags:
|
tags:
|
||||||
- Subscription
|
- Subscription
|
||||||
|
/subscriptions/details:
|
||||||
|
get:
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ok
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/routes.ListSubscriptionDetails'
|
||||||
|
summary: Returns the top 50 entries with full deatils on the source and output.
|
||||||
|
tags:
|
||||||
|
- Subscription
|
||||||
/subscriptions/discord/webhook/delete:
|
/subscriptions/discord/webhook/delete:
|
||||||
delete:
|
delete:
|
||||||
parameters:
|
parameters:
|
||||||
- description: Id
|
- description: id
|
||||||
in: query
|
in: query
|
||||||
name: Id
|
name: id
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
responses: {}
|
responses: {}
|
||||||
summary: Removes a Discord WebHook Subscription based on the Subscription ID.
|
summary: Removes a Discord WebHook Subscription based on the Subscription ID.
|
||||||
tags:
|
tags:
|
||||||
- Config
|
|
||||||
- Source
|
|
||||||
- Discord
|
|
||||||
- Subscription
|
- Subscription
|
||||||
/subscriptions/new/discordwebhook:
|
/subscriptions/discord/webhook/new:
|
||||||
post:
|
post:
|
||||||
parameters:
|
parameters:
|
||||||
- description: discordWebHookId
|
- description: discordWebHookId
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package model
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
@ -1,4 +1,4 @@
|
|||||||
package model
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
129
domain/models/dto.go
Normal file
129
domain/models/dto.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ArticleDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Source uuid.UUID `json:"sourceid"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Pubdate time.Time `json:"pubdate"`
|
||||||
|
Video string `json:"video"`
|
||||||
|
Videoheight int32 `json:"videoHeight"`
|
||||||
|
Videowidth int32 `json:"videoWidth"`
|
||||||
|
Thumbnail string `json:"thumbnail"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Authorname string `json:"authorName"`
|
||||||
|
Authorimage string `json:"authorImage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticleDetailsDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Source SourceDto `json:"source"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Pubdate time.Time `json:"pubdate"`
|
||||||
|
Video string `json:"video"`
|
||||||
|
Videoheight int32 `json:"videoHeight"`
|
||||||
|
Videowidth int32 `json:"videoWidth"`
|
||||||
|
Thumbnail string `json:"thumbnail"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Authorname string `json:"authorName"`
|
||||||
|
Authorimage string `json:"authorImage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordWebHooksDto struct {
|
||||||
|
ID uuid.UUID `json:"ID"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Server string `json:"server"`
|
||||||
|
Channel string `json:"channel"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertToDiscordWebhookDto(i database.Discordwebhook) DiscordWebHooksDto {
|
||||||
|
return DiscordWebHooksDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Url: i.Url,
|
||||||
|
Server: i.Server,
|
||||||
|
Channel: i.Channel,
|
||||||
|
Enabled: i.Enabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SourceDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Site string `json:"site"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
Deleted bool `json:"deleted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertToSourceDto(i database.Source) SourceDto {
|
||||||
|
var deleted bool
|
||||||
|
if !i.Deleted.Valid {
|
||||||
|
deleted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return SourceDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Site: i.Site,
|
||||||
|
Name: i.Name,
|
||||||
|
Source: i.Source,
|
||||||
|
Type: i.Type,
|
||||||
|
Value: i.Value.String,
|
||||||
|
Enabled: i.Enabled,
|
||||||
|
Url: i.Url,
|
||||||
|
Tags: splitTags(i.Tags),
|
||||||
|
Deleted: deleted,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordQueueDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Articleid uuid.UUID `json:"articleId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscordQueueDetailsDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Article ArticleDetailsDto `json:"article"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SubscriptionDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
DiscordWebhookId uuid.UUID `json:"discordwebhookid"`
|
||||||
|
SourceId uuid.UUID `json:"sourceid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertToSubscriptionDto(i database.Subscription) SubscriptionDto {
|
||||||
|
c := SubscriptionDto{
|
||||||
|
ID: i.ID,
|
||||||
|
DiscordWebhookId: i.Discordwebhookid,
|
||||||
|
SourceId: i.Sourceid,
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
type SubscriptionDetailsDto struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
Source SourceDto `json:"source"`
|
||||||
|
DiscordWebHook DiscordWebHooksDto `json:"discordwebhook"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitTags(t string) []string {
|
||||||
|
items := strings.Split(t, ", ")
|
||||||
|
return items
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package model
|
package models
|
||||||
|
|
||||||
// This is the root Json object. It does not contain data that we care about though.
|
// This is the root Json object. It does not contain data that we care about though.
|
||||||
type RedditJsonContent struct {
|
type RedditJsonContent struct {
|
115
dto/articles.go
Normal file
115
dto/articles.go
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// The converter package lives between the database calls and the API calls.
|
||||||
|
// This way if any new methods like RPC calls are added later, the API does not need to be reworked as much
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DtoClient struct {
|
||||||
|
db *database.Queries
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDtoClient(db *database.Queries) DtoClient {
|
||||||
|
return DtoClient{
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ListArticles(ctx context.Context, limit int) ([]models.ArticleDto, error) {
|
||||||
|
var res []models.ArticleDto
|
||||||
|
|
||||||
|
a, err := c.db.ListArticles(ctx, int32(limit))
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, article := range a {
|
||||||
|
res = append(res, c.convertArticle(article))
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetArticle(ctx context.Context, ID uuid.UUID) (models.ArticleDto, error) {
|
||||||
|
a, err := c.db.GetArticleByID(ctx, ID)
|
||||||
|
if err != nil {
|
||||||
|
return models.ArticleDto{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.convertArticle(a), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetArticleDetails(ctx context.Context, ID uuid.UUID) (models.ArticleDetailsDto, error) {
|
||||||
|
a, err := c.db.GetArticleByID(ctx, ID)
|
||||||
|
if err != nil {
|
||||||
|
return models.ArticleDetailsDto{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := c.db.GetSourceByID(ctx, a.Sourceid)
|
||||||
|
if err != nil {
|
||||||
|
return models.ArticleDetailsDto{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := c.convertArticleDetails(a, s)
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetArticlesBySourceId(ctx context.Context, SourceID uuid.UUID) ([]models.ArticleDto, error) {
|
||||||
|
var res []models.ArticleDto
|
||||||
|
a, err := c.db.GetArticlesBySourceId(ctx, SourceID)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, article := range a {
|
||||||
|
res = append(res, c.convertArticle(article))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) convertArticle(i database.Article) models.ArticleDto {
|
||||||
|
return models.ArticleDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Source: i.Sourceid,
|
||||||
|
Tags: c.SplitTags(i.Tags),
|
||||||
|
Title: i.Title,
|
||||||
|
Url: i.Url,
|
||||||
|
Pubdate: i.Pubdate,
|
||||||
|
Video: i.Video.String,
|
||||||
|
Videoheight: i.Videoheight,
|
||||||
|
Videowidth: i.Videoheight,
|
||||||
|
Thumbnail: i.Thumbnail,
|
||||||
|
Description: i.Description,
|
||||||
|
Authorname: i.Authorname.String,
|
||||||
|
Authorimage: i.Authorimage.String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) convertArticleDetails(i database.Article, s database.Source) models.ArticleDetailsDto {
|
||||||
|
return models.ArticleDetailsDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Source: c.ConvertToSource(s),
|
||||||
|
Tags: c.SplitTags(i.Tags),
|
||||||
|
Title: i.Title,
|
||||||
|
Url: i.Url,
|
||||||
|
Pubdate: i.Pubdate,
|
||||||
|
Video: i.Video.String,
|
||||||
|
Videoheight: i.Videoheight,
|
||||||
|
Videowidth: i.Videoheight,
|
||||||
|
Thumbnail: i.Thumbnail,
|
||||||
|
Description: i.Description,
|
||||||
|
Authorname: i.Authorname.String,
|
||||||
|
Authorimage: i.Authorimage.String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) SplitTags(t string) []string {
|
||||||
|
return strings.Split(t, ", ")
|
||||||
|
}
|
63
dto/discordwebhooks.go
Normal file
63
dto/discordwebhooks.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c DtoClient) ListDiscordWebHooks(ctx context.Context, total int32) ([]models.DiscordWebHooksDto, error) {
|
||||||
|
var res []models.DiscordWebHooksDto
|
||||||
|
|
||||||
|
items, err := c.db.ListDiscordWebhooks(ctx, total)
|
||||||
|
if err != nil {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertDiscordWebhook(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetDiscordWebhook(ctx context.Context, id uuid.UUID) (models.DiscordWebHooksDto, error) {
|
||||||
|
var res models.DiscordWebHooksDto
|
||||||
|
|
||||||
|
item, err := c.db.GetDiscordWebHooksByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.ConvertDiscordWebhook(item), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetDiscordWebHookByServerAndChannel(ctx context.Context, server, channel string) ([]models.DiscordWebHooksDto, error) {
|
||||||
|
var res []models.DiscordWebHooksDto
|
||||||
|
|
||||||
|
items, err := c.db.GetDiscordWebHooksByServerAndChannel(ctx, database.GetDiscordWebHooksByServerAndChannelParams{
|
||||||
|
Server: server,
|
||||||
|
Channel: channel,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertDiscordWebhook(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ConvertDiscordWebhook(i database.Discordwebhook) models.DiscordWebHooksDto {
|
||||||
|
return models.DiscordWebHooksDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Url: i.Url,
|
||||||
|
Server: i.Server,
|
||||||
|
Channel: i.Channel,
|
||||||
|
Enabled: i.Enabled,
|
||||||
|
}
|
||||||
|
}
|
42
dto/queue.go
Normal file
42
dto/queue.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c DtoClient) ListDiscordWebhookQueue(ctx context.Context, limit int32) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ListDiscordWebhookQueueDetails(ctx context.Context, limit int32) ([]models.DiscordQueueDetailsDto, error) {
|
||||||
|
var res []models.DiscordQueueDetailsDto
|
||||||
|
|
||||||
|
items, err := c.db.ListDiscordQueueItems(ctx, limit)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
article, err := c.GetArticleDetails(ctx, item.ID)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res = append(res, models.DiscordQueueDetailsDto{
|
||||||
|
ID: item.ID,
|
||||||
|
Article: article,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ConvertToDiscordQueueDto(i database.Discordqueue) models.DiscordQueueDto {
|
||||||
|
return models.DiscordQueueDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Articleid: i.Articleid,
|
||||||
|
}
|
||||||
|
}
|
85
dto/sources.go
Normal file
85
dto/sources.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c DtoClient) ListSources(ctx context.Context, limit int32) ([]models.SourceDto, error) {
|
||||||
|
var res []models.SourceDto
|
||||||
|
|
||||||
|
items, err := c.db.ListSources(ctx, limit)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertToSource(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ListSourcesBySource(ctx context.Context, sourceName string) ([]models.SourceDto, error) {
|
||||||
|
var res []models.SourceDto
|
||||||
|
|
||||||
|
items, err := c.db.ListSourcesBySource(ctx, strings.ToLower(sourceName))
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertToSource(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetSourceById(ctx context.Context, id uuid.UUID) (models.SourceDto, error) {
|
||||||
|
var res models.SourceDto
|
||||||
|
|
||||||
|
item, err := c.db.GetSourceByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.ConvertToSource(item), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) GetSourceByNameAndSource(ctx context.Context, name, source string) (models.SourceDto, error) {
|
||||||
|
var res models.SourceDto
|
||||||
|
|
||||||
|
item, err := c.db.GetSourceByNameAndSource(ctx, database.GetSourceByNameAndSourceParams{
|
||||||
|
Name: name,
|
||||||
|
Source: source,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.ConvertToSource(item), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ConvertToSource(i database.Source) models.SourceDto {
|
||||||
|
var deleted bool
|
||||||
|
if !i.Deleted.Valid {
|
||||||
|
deleted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return models.SourceDto{
|
||||||
|
ID: i.ID,
|
||||||
|
Site: i.Site,
|
||||||
|
Name: i.Name,
|
||||||
|
Source: i.Source,
|
||||||
|
Type: i.Type,
|
||||||
|
Value: i.Value.String,
|
||||||
|
Enabled: i.Enabled,
|
||||||
|
Url: i.Url,
|
||||||
|
Tags: c.SplitTags(i.Tags),
|
||||||
|
Deleted: deleted,
|
||||||
|
}
|
||||||
|
}
|
91
dto/subscriptions.go
Normal file
91
dto/subscriptions.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c DtoClient) ListSubscriptions(ctx context.Context, limit int32) ([]models.SubscriptionDto, error) {
|
||||||
|
var res []models.SubscriptionDto
|
||||||
|
|
||||||
|
items, err := c.db.ListSubscriptions(ctx, limit)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertSubscription(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ListSubscriptionDetails(ctx context.Context, limit int32) ([]models.SubscriptionDetailsDto, error) {
|
||||||
|
var res []models.SubscriptionDetailsDto
|
||||||
|
|
||||||
|
items, err := c.ListSubscriptions(ctx, limit)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
dwh, err := c.GetDiscordWebhook(ctx, item.DiscordWebhookId)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := c.GetSourceById(ctx, item.SourceId)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res = append(res, models.SubscriptionDetailsDto{
|
||||||
|
ID: item.ID,
|
||||||
|
Source: source,
|
||||||
|
DiscordWebHook: dwh,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ListSubscriptionsByDiscordWebhookId(ctx context.Context, id uuid.UUID) ([]models.SubscriptionDto, error) {
|
||||||
|
var res []models.SubscriptionDto
|
||||||
|
|
||||||
|
items, err := c.db.GetSubscriptionsByDiscordWebHookId(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertSubscription(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ListSubscriptionsBySourceId(ctx context.Context, id uuid.UUID) ([]models.SubscriptionDto, error) {
|
||||||
|
var res []models.SubscriptionDto
|
||||||
|
|
||||||
|
items, err := c.db.GetSubscriptionsBySourceID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
res = append(res, c.ConvertSubscription(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c DtoClient) ConvertSubscription(i database.Subscription) models.SubscriptionDto {
|
||||||
|
return models.SubscriptionDto{
|
||||||
|
ID: i.ID,
|
||||||
|
DiscordWebhookId: i.Discordwebhookid,
|
||||||
|
SourceId: i.Sourceid,
|
||||||
|
}
|
||||||
|
}
|
13
main.go
13
main.go
@ -2,9 +2,11 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
"github.com/jtom38/newsbot/collector/docs"
|
"github.com/jtom38/newsbot/collector/docs"
|
||||||
"github.com/jtom38/newsbot/collector/routes"
|
"github.com/jtom38/newsbot/collector/routes"
|
||||||
"github.com/jtom38/newsbot/collector/services/config"
|
"github.com/jtom38/newsbot/collector/services/config"
|
||||||
@ -20,16 +22,23 @@ func main() {
|
|||||||
docs.SwaggerInfo.Host = fmt.Sprintf("%v:8081", address)
|
docs.SwaggerInfo.Host = fmt.Sprintf("%v:8081", address)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
db, err := sql.Open("postgres", cfg.GetConfig(config.Sql_Connection_String))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
queries := database.New(db)
|
||||||
|
|
||||||
c := cron.New(ctx)
|
c := cron.New(ctx)
|
||||||
c.Start()
|
c.Start()
|
||||||
|
|
||||||
server := routes.NewServer(ctx)
|
server := routes.NewServer(ctx, queries)
|
||||||
|
|
||||||
fmt.Println("API is online and waiting for requests.")
|
fmt.Println("API is online and waiting for requests.")
|
||||||
fmt.Printf("API: http://%v:8081/api\r\n", address)
|
fmt.Printf("API: http://%v:8081/api\r\n", address)
|
||||||
fmt.Printf("Swagger: http://%v:8081/swagger/index.html\r\n", address)
|
fmt.Printf("Swagger: http://%v:8081/swagger/index.html\r\n", address)
|
||||||
|
|
||||||
err := http.ListenAndServe(":8081", server.Router)
|
err = http.ListenAndServe(":8081", server.Router)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -6,61 +6,156 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetArticleRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Get("/", s.listArticles)
|
||||||
|
r.Route("/{ID}", func(r chi.Router) {
|
||||||
|
r.Get("/", s.getArticle)
|
||||||
|
r.Get("/details", s.getArticleDetails)
|
||||||
|
})
|
||||||
|
r.Get("/by/sourceid", s.GetArticlesBySourceId)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticlesListResults struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.ArticleDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListArticles
|
// ListArticles
|
||||||
// @Summary Lists the top 50 records
|
// @Summary Lists the top 50 records
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Articles
|
// @Tags Articles
|
||||||
// @Router /articles [get]
|
// @Router /articles [get]
|
||||||
|
// @Success 200 {object} ArticlesListResults "OK"
|
||||||
func (s *Server) listArticles(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) listArticles(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
p := ArticlesListResults{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
res, err := s.Db.ListArticlesByDate(*s.ctx, 50)
|
Message: "OK",
|
||||||
if err != nil {
|
StatusCode: http.StatusOK,
|
||||||
w.Write([]byte(err.Error()))
|
},
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
|
res, err := s.dto.ListArticles(r.Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.Write(bres)
|
w.Write(bres)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetArticleById
|
type ArticleGetResults struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.ArticleDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetArticle
|
||||||
// @Summary Returns an article based on defined ID.
|
// @Summary Returns an article based on defined ID.
|
||||||
// @Param id path string true "uuid"
|
// @Param ID path string true "uuid"
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Articles
|
// @Tags Articles
|
||||||
// @Router /articles/{ID} [get]
|
// @Router /articles/{ID} [get]
|
||||||
func (s *Server) getArticleById(w http.ResponseWriter, r *http.Request) {
|
// @Success 200 {object} ArticleGetResults "OK"
|
||||||
w.Header().Set("Content-Type", "application/json")
|
func (s *Server) getArticle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
p := ArticleGetResults {
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetArticleByID(*s.ctx, uuid)
|
res, err := s.dto.GetArticle(r.Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(bres)
|
w.Write(bres)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ArticleDetailsResult struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.ArticleDetailsDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetArticleDetails
|
||||||
|
// @Summary Returns an article and source based on defined ID.
|
||||||
|
// @Param ID path string true "uuid"
|
||||||
|
// @Produce application/json
|
||||||
|
// @Tags Articles
|
||||||
|
// @Router /articles/{ID}/details [get]
|
||||||
|
// @Success 200 {object} ArticleDetailsResult "OK"
|
||||||
|
func (s *Server) getArticleDetails(w http.ResponseWriter, r *http.Request) {
|
||||||
|
p := ArticleDetailsResult {
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
|
id := chi.URLParam(r, "ID")
|
||||||
|
uuid, err := uuid.Parse(id)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := s.dto.GetArticleDetails(r.Context(), uuid)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(bres)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticlesBySourceIDResults struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.ArticleDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
// TODO add page support
|
// TODO add page support
|
||||||
// GetArticlesBySourceID
|
// GetArticlesBySourceID
|
||||||
// @Summary Finds the articles based on the SourceID provided. Returns the top 50.
|
// @Summary Finds the articles based on the SourceID provided. Returns the top 50.
|
||||||
@ -68,6 +163,7 @@ func (s *Server) getArticleById(w http.ResponseWriter, r *http.Request) {
|
|||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Articles
|
// @Tags Articles
|
||||||
// @Router /articles/by/sourceid [get]
|
// @Router /articles/by/sourceid [get]
|
||||||
|
// @Success 200 {object} ArticlesListResults "OK"
|
||||||
func (s *Server) GetArticlesBySourceId(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetArticlesBySourceId(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
@ -77,56 +173,20 @@ func (s *Server) GetArticlesBySourceId(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
uuid, err := uuid.Parse(_id)
|
uuid, err := uuid.Parse(_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetNewArticlesBySourceId(*s.ctx, uuid)
|
res, err := s.dto.GetArticlesBySourceId(r.Context(), uuid)
|
||||||
//res, err := s.Db.GetArticlesBySourceId(*s.ctx, uuid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
bres, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
}
|
|
||||||
|
|
||||||
w.Write(bres)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO add page support
|
|
||||||
// GetArticlesByTag
|
|
||||||
// @Summary Finds the articles based on the SourceID provided. Returns the top 50.
|
|
||||||
// @Param tag query string true "Tag name"
|
|
||||||
// @Produce application/json
|
|
||||||
// @Tags Articles
|
|
||||||
// @Router /articles/by/tag [get]
|
|
||||||
func (s *Server) GetArticlesByTag(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
r.URL.Query()
|
|
||||||
query := r.URL.Query()
|
|
||||||
_id := query["tag"][0]
|
|
||||||
|
|
||||||
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)
|
w.Write(bres)
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
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.ListDiscordQueueItems(*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)
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -10,62 +9,106 @@ import (
|
|||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jtom38/newsbot/collector/database"
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetDiscordWebHooks
|
func (s Server) DiscordWebHookRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Get("/", s.ListDiscordWebHooks)
|
||||||
|
r.Post("/new", s.NewDiscordWebHook)
|
||||||
|
r.Get("/by/serverAndChannel", s.GetDiscordWebHooksByServerAndChannel)
|
||||||
|
r.Route("/{ID}", func(r chi.Router) {
|
||||||
|
r.Get("/", s.GetDiscordWebHooksById)
|
||||||
|
r.Delete("/", s.deleteDiscordWebHook)
|
||||||
|
r.Post("/disable", s.disableDiscordWebHook)
|
||||||
|
r.Post("/enable", s.enableDiscordWebHook)
|
||||||
|
})
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListDiscordWebhooks struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.DiscordWebHooksDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListDiscordWebhooks
|
||||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks [get]
|
// @Router /discord/webhooks [get]
|
||||||
func (s *Server) GetDiscordWebHooks(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ListDiscordWebHooks(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
p := ListDiscordWebhooks{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
res, err := s.Db.ListDiscordWebhooks(*s.ctx, 100)
|
Message: "OK",
|
||||||
if err != nil {
|
StatusCode: http.StatusOK,
|
||||||
w.Write([]byte(err.Error()))
|
},
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
|
res, err := s.dto.ListDiscordWebHooks(r.Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write([]byte(err.Error()))
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
|
}
|
||||||
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(bres)
|
w.Write(bres)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetDiscordWebhook struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.DiscordWebHooksDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetDiscordWebHook
|
// GetDiscordWebHook
|
||||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/{id} [get]
|
// @Router /discord/webhooks/{id} [get]
|
||||||
|
// @Success 200 {object} GetDiscordWebhook "OK"
|
||||||
func (s *Server) GetDiscordWebHooksById(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetDiscordWebHooksById(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
p := GetDiscordWebhook{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
_id := chi.URLParam(r, "ID")
|
_id := chi.URLParam(r, "ID")
|
||||||
if _id == "" {
|
if _id == "" {
|
||||||
http.Error(w, "id is missing", http.StatusBadRequest)
|
s.WriteError(w, "id is missing", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, err := uuid.Parse(_id)
|
uuid, err := uuid.Parse(_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "unable to parse id value", http.StatusBadRequest)
|
s.WriteError(w, "unable to parse id value", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetDiscordWebHooksByID(*s.ctx, uuid)
|
res, err := s.dto.GetDiscordWebhook(r.Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "no record found", http.StatusBadRequest)
|
s.WriteError(w, "no record found", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
p.Payload = res
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
bres, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "unable to convert to json", http.StatusBadRequest)
|
s.WriteError(w, "unable to convert to json", http.StatusBadRequest)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(bres)
|
w.Write(bres)
|
||||||
@ -76,49 +119,55 @@ func (s *Server) GetDiscordWebHooksById(w http.ResponseWriter, r *http.Request)
|
|||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Param server query string true "Fancy Server"
|
// @Param server query string true "Fancy Server"
|
||||||
// @Param channel query string true "memes"
|
// @Param channel query string true "memes"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/by/serverAndChannel [get]
|
// @Router /discord/webhooks/by/serverAndChannel [get]
|
||||||
|
// @Success 200 {object} ListDiscordWebhooks "OK"
|
||||||
func (s *Server) GetDiscordWebHooksByServerAndChannel(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetDiscordWebHooksByServerAndChannel(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
p := ListDiscordWebhooks{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_server := query["server"][0]
|
_server := query["server"][0]
|
||||||
if _server == "" {
|
if _server == "" {
|
||||||
http.Error(w, "ID is missing", http.StatusInternalServerError)
|
s.WriteError(w, "ID is missing", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_channel := query["channel"][0]
|
_channel := query["channel"][0]
|
||||||
if _channel == "" {
|
if _channel == "" {
|
||||||
http.Error(w, "Channel is missing", http.StatusInternalServerError)
|
s.WriteError(w, "Channel is missing", http.StatusInternalServerError)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := s.Db.GetDiscordWebHooksByServerAndChannel(context.Background(), database.GetDiscordWebHooksByServerAndChannelParams{
|
|
||||||
Server: _server,
|
|
||||||
Channel: _channel,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
res, err := s.dto.GetDiscordWebHookByServerAndChannel(r.Context(), _server, _channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "unable to convert to json", http.StatusInternalServerError)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
panic(err)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, "unable to convert to json", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(bres)
|
w.Write(bres)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// NewDiscordWebHook
|
// NewDiscordWebHook
|
||||||
// @Summary Creates a new record for a discord web hook to post data to.
|
// @Summary Creates a new record for a discord web hook to post data to.
|
||||||
// @Param url query string true "url"
|
// @Param url query string true "url"
|
||||||
// @Param server query string true "Server name"
|
// @Param server query string true "Server name"
|
||||||
// @Param channel query string true "Channel name"
|
// @Param channel query string true "Channel name"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/new [post]
|
// @Router /discord/webhooks/new [post]
|
||||||
func (s *Server) NewDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) NewDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
@ -160,82 +209,84 @@ func (s *Server) NewDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
|||||||
// DisableDiscordWebHooks
|
// DisableDiscordWebHooks
|
||||||
// @Summary Disables a Webhook from being used.
|
// @Summary Disables a Webhook from being used.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/{id}/disable [post]
|
// @Router /discord/webhooks/{ID}/disable [post]
|
||||||
func (s *Server) disableDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) disableDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure we can find the record
|
// Check to make sure we can find the record
|
||||||
_, err = s.Db.GetDiscordWebHooksByID(*s.ctx, uuid)
|
_, err = s.Db.GetDiscordWebHooksByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.DisableDiscordWebHook(*s.ctx, uuid)
|
err = s.Db.DisableDiscordWebHook(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableDiscordWebHook
|
// EnableDiscordWebHook
|
||||||
// @Summary Enables a source to continue processing.
|
// @Summary Enables a source to continue processing.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/{id}/enable [post]
|
// @Router /discord/webhooks/{ID}/enable [post]
|
||||||
func (s *Server) enableDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) enableDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure we can find the record
|
// Check to make sure we can find the record
|
||||||
_, err = s.Db.GetDiscordWebHooksByID(*s.ctx, uuid)
|
_, err = s.Db.GetDiscordWebHooksByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.EnableDiscordWebHook(*s.ctx, uuid)
|
err = s.Db.EnableDiscordWebHook(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteDiscordWebHook
|
// DeleteDiscordWebHook
|
||||||
// @Summary Deletes a record by ID.
|
// @Summary Deletes a record by ID.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/{id} [delete]
|
// @Router /discord/webhooks/{ID} [delete]
|
||||||
func (s *Server) deleteDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) deleteDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
||||||
//var item model.Sources = model.Sources{}
|
//var item model.Sources = model.Sources{}
|
||||||
|
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure we can find the record
|
// Check to make sure we can find the record
|
||||||
_, err = s.Db.GetDiscordQueueByID(*s.ctx, uuid)
|
_, err = s.Db.GetDiscordQueueByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the record
|
// Delete the record
|
||||||
err = s.Db.DeleteDiscordWebHooks(*s.ctx, uuid)
|
err = s.Db.DeleteDiscordWebHooks(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateDiscordWebHook
|
// UpdateDiscordWebHook
|
||||||
// @Summary Updates a valid discord webhook ID based on the body given.
|
// @Summary Updates a valid discord webhook ID based on the body given.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Discord, Webhook
|
// @Tags Discord, Webhook
|
||||||
// @Router /discord/webhooks/{id} [patch]
|
// @Router /discord/webhooks/{id} [patch]
|
||||||
func (s *Server) UpdateDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) UpdateDiscordWebHook(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
|
57
routes/queue.go
Normal file
57
routes/queue.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetQueueRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Get("/discord/webhooks", s.ListDiscordWebhookQueue)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListDiscordWebHooksQueueResults struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.DiscordQueueDetailsDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDiscordQueue
|
||||||
|
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||||
|
// @Produce application/json
|
||||||
|
// @Tags Queue
|
||||||
|
// @Router /queue/discord/webhooks [get]
|
||||||
|
// @Success 200 {object} ListDiscordWebHooksQueueResults "ok"
|
||||||
|
func (s *Server) ListDiscordWebhookQueue(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
p := ListDiscordWebHooksQueueResults{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the raw resp from sql
|
||||||
|
res, err := s.dto.ListDiscordWebhookQueueDetails(r.Context(), 50)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Payload = res
|
||||||
|
|
||||||
|
// convert to json
|
||||||
|
b, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
|
}
|
@ -1,50 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RootRoutes() chi.Router {
|
|
||||||
app := chi.NewRouter()
|
|
||||||
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))
|
|
||||||
}
|
|
107
routes/server.go
107
routes/server.go
@ -3,8 +3,8 @@ package routes
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
//"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
@ -12,15 +12,23 @@ import (
|
|||||||
httpSwagger "github.com/swaggo/http-swagger"
|
httpSwagger "github.com/swaggo/http-swagger"
|
||||||
|
|
||||||
"github.com/jtom38/newsbot/collector/database"
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/dto"
|
||||||
"github.com/jtom38/newsbot/collector/services/config"
|
"github.com/jtom38/newsbot/collector/services/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Router *chi.Mux
|
Router *chi.Mux
|
||||||
Db *database.Queries
|
Db *database.Queries
|
||||||
|
dto dto.DtoClient
|
||||||
ctx *context.Context
|
ctx *context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
HeaderContentType = "Content-Type"
|
||||||
|
|
||||||
|
ApplicationJson = "application/json"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrIdValueMissing string = "id value is missing"
|
ErrIdValueMissing string = "id value is missing"
|
||||||
ErrValueNotUuid string = "a value given was expected to be a uuid but was not correct."
|
ErrValueNotUuid string = "a value given was expected to be a uuid but was not correct."
|
||||||
@ -28,16 +36,18 @@ var (
|
|||||||
ErrUnableToConvertToJson string = "Unable to convert to json"
|
ErrUnableToConvertToJson string = "Unable to convert to json"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewServer(ctx context.Context) *Server {
|
func NewServer(ctx context.Context, db *database.Queries) *Server {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
ctx: &ctx,
|
ctx: &ctx,
|
||||||
|
Db: db,
|
||||||
|
dto: dto.NewDtoClient(db),
|
||||||
}
|
}
|
||||||
|
|
||||||
db, err := openDatabase(ctx)
|
//db, err := openDatabase(ctx)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
panic(err)
|
// panic(err)
|
||||||
}
|
//}
|
||||||
s.Db = db
|
//s.Db = db
|
||||||
|
|
||||||
s.Router = chi.NewRouter()
|
s.Router = chi.NewRouter()
|
||||||
s.MountMiddleware()
|
s.MountMiddleware()
|
||||||
@ -68,56 +78,37 @@ func (s *Server) MountRoutes() {
|
|||||||
httpSwagger.URL("doc.json"), //The url pointing to API definition
|
httpSwagger.URL("doc.json"), //The url pointing to API definition
|
||||||
))
|
))
|
||||||
|
|
||||||
/* Root Routes */
|
s.Router.Mount("/api/articles", s.GetArticleRouter())
|
||||||
s.Router.Get("/api/helloworld", helloWorld)
|
s.Router.Mount("/api/queue", s.GetQueueRouter())
|
||||||
s.Router.Get("/api/hello/{who}", helloWho)
|
s.Router.Mount("/api/discord/webhooks", s.DiscordWebHookRouter())
|
||||||
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)
|
|
||||||
s.Router.Get("/api/discord/webhooks/by/serverAndChannel", s.GetDiscordWebHooksByServerAndChannel)
|
|
||||||
|
|
||||||
s.Router.Route("/api/discord/webhooks/{ID}", func(r chi.Router) {
|
//s.Router.Get("/api/settings", s.getSettings)
|
||||||
r.Get("/", s.GetDiscordWebHooksById)
|
|
||||||
r.Delete("/", s.deleteDiscordWebHook)
|
|
||||||
r.Post("/disable", s.disableDiscordWebHook)
|
|
||||||
r.Post("/enable", s.enableDiscordWebHook)
|
|
||||||
})
|
|
||||||
|
|
||||||
/* Settings */
|
s.Router.Mount("/api/sources", s.GetSourcesRouter())
|
||||||
s.Router.Get("/api/settings", s.getSettings)
|
s.Router.Mount("/api/subscriptions", s.GetSubscriptionsRouter())
|
||||||
|
}
|
||||||
/* Source Routes */
|
|
||||||
s.Router.Get("/api/config/sources", s.listSources)
|
type ApiStatusModel struct {
|
||||||
s.Router.Get("/api/config/sources/by/source", s.listSourcesBySource)
|
StatusCode int `json:"status"`
|
||||||
s.Router.Post("/api/config/sources/new/reddit", s.newRedditSource)
|
Message string `json:"message"`
|
||||||
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) {
|
type ApiError struct {
|
||||||
r.Get("/", s.getSources)
|
*ApiStatusModel
|
||||||
r.Delete("/", s.deleteSources)
|
}
|
||||||
r.Post("/disable", s.disableSource)
|
|
||||||
r.Post("/enable", s.enableSource)
|
func (s *Server) WriteError(w http.ResponseWriter, errMessage string, HttpStatusCode int) {
|
||||||
//r.Post("/delete", )
|
e := ApiError{
|
||||||
})
|
ApiStatusModel: &ApiStatusModel{
|
||||||
s.Router.Get("/api/config/sources/by/sourceAndName", s.GetSourceBySourceAndName)
|
StatusCode: http.StatusInternalServerError,
|
||||||
|
Message: errMessage,
|
||||||
/* Subscriptions */
|
},
|
||||||
s.Router.Get("/api/subscriptions", s.ListSubscriptions)
|
}
|
||||||
s.Router.Get("/api/subscriptions/byDiscordId", s.GetSubscriptionsByDiscordId)
|
|
||||||
s.Router.Get("/api/subscriptions/bySourceId", s.GetSubscriptionsBySourceId)
|
b, err := json.Marshal(e)
|
||||||
s.Router.Post("/api/subscriptions/new/discordwebhook", s.newDiscordWebHookSubscription)
|
if err != nil {
|
||||||
s.Router.Delete("/api/subscriptions/discord/webhook/delete", s.DeleteDiscordWebHookSubscription)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
@ -2,43 +2,43 @@ package routes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"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) {
|
func (s *Server) getSettings(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// 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]
|
||||||
|
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
//var item model.Sources
|
//var item model.Sources
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
|
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetSourceByID(*s.ctx, uuid)
|
res, err := s.Db.GetSourceByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
s.WriteError(w, err.Error(), http.StatusNotFound)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//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)
|
bResult, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bResult)
|
w.Write(bResult)
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,55 @@
|
|||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jtom38/newsbot/collector/database"
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetSourcesRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Get("/", s.listSources)
|
||||||
|
r.Get("/by/source", s.listSourcesBySource)
|
||||||
|
r.Get("/by/sourceAndName", s.GetSourceBySourceAndName)
|
||||||
|
|
||||||
|
r.Post("/new/reddit", s.newRedditSource)
|
||||||
|
r.Post("/new/youtube", s.newYoutubeSource)
|
||||||
|
r.Post("/new/twitch", s.newTwitchSource)
|
||||||
|
|
||||||
|
r.Route("/{ID}", func(p chi.Router) {
|
||||||
|
p.Get("/", s.getSources)
|
||||||
|
p.Delete("/", s.deleteSources)
|
||||||
|
p.Post("/disable", s.disableSource)
|
||||||
|
p.Post("/enable", s.enableSource)
|
||||||
|
})
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListSources struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.SourceDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetSource struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.SourceDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListSources
|
// ListSources
|
||||||
// @Summary Lists the top 50 records
|
// @Summary Lists the top 50 records
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Config, Source
|
// @Tags Source
|
||||||
// @Router /config/sources [get]
|
// @Router /sources [get]
|
||||||
|
// @Success 200 {object} ListSources "ok"
|
||||||
|
// @Failure 400 {object} ApiError "Unable to reach SQL or Data problems"
|
||||||
func (s *Server) listSources(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) listSources(w http.ResponseWriter, r *http.Request) {
|
||||||
//TODO Add top?
|
//TODO Add top?
|
||||||
/*
|
/*
|
||||||
@ -29,35 +61,41 @@ func (s *Server) listSources(w http.ResponseWriter, r *http.Request) {
|
|||||||
res, err := s.Db.ListSources(*s.ctx, int32(topInt))
|
res, err := s.Db.ListSources(*s.ctx, int32(topInt))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
result := ListSources{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Message: "OK",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// Default way of showing all sources
|
// Default way of showing all sources
|
||||||
res, err := s.Db.ListSources(*s.ctx, 50)
|
items, err := s.dto.ListSources(r.Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var dto []database.SourceDto
|
result.Payload = items
|
||||||
for _, item := range res {
|
|
||||||
dto = append(dto, database.ConvertToSourceDto(item))
|
|
||||||
}
|
|
||||||
|
|
||||||
bResult, err := json.Marshal(dto)
|
bResult, err := json.Marshal(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "unable to convert to json", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bResult)
|
w.Write(bResult)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListSourcesBySource
|
// ListSourcesBySource
|
||||||
// @Summary Lists the top 50 records based on the name given. Example: reddit
|
// @Summary Lists the top 50 records based on the name given. Example: reddit
|
||||||
// @Param source query string true "Source Name"
|
// @Param source query string true "Source Name"
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Config, Source
|
// @Tags Source
|
||||||
// @Router /config/sources/by/source [get]
|
// @Router /sources/by/source [get]
|
||||||
|
// @Success 200 {object} ListSources "ok"
|
||||||
|
// @Failure 400 {object} ApiError "Unable to query SQL."
|
||||||
|
// @Failure 500 {object} ApiError "Problems with data."
|
||||||
func (s *Server) listSourcesBySource(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) listSourcesBySource(w http.ResponseWriter, r *http.Request) {
|
||||||
//TODO Add top?
|
//TODO Add top?
|
||||||
/*
|
/*
|
||||||
@ -68,23 +106,33 @@ func (s *Server) listSourcesBySource(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
res, err := s.Db.ListSources(*s.ctx, int32(topInt))
|
res, err := s.Db.ListSources(*s.ctx, int32(topInt))
|
||||||
*/
|
*/
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
|
result := ListSources{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Message: "OK",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_source := query["source"][0]
|
_source := query["source"][0]
|
||||||
|
|
||||||
// Shows the list by Sources.source
|
// Shows the list by Sources.source
|
||||||
res, err := s.Db.ListSourcesBySource(*s.ctx, strings.ToLower(_source))
|
res, err := s.dto.ListSourcesBySource(r.Context(), _source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "invalid source is missing a value", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bResult, err := json.Marshal(res)
|
|
||||||
if err != nil {
|
result.Payload = res
|
||||||
http.Error(w, "unable to convert to json", http.StatusBadRequest)
|
|
||||||
|
bResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bResult)
|
w.Write(bResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,29 +140,43 @@ func (s *Server) listSourcesBySource(w http.ResponseWriter, r *http.Request) {
|
|||||||
// @Summary Returns a single entity by ID
|
// @Summary Returns a single entity by ID
|
||||||
// @Param id path string true "uuid"
|
// @Param id path string true "uuid"
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Config, Source
|
// @Tags Source
|
||||||
// @Router /config/sources/{id} [get]
|
// @Router /sources/{id} [get]
|
||||||
|
// @Success 200 {object} GetSource "ok"
|
||||||
|
// @Failure 204 {object} ApiError "No record found."
|
||||||
|
// @Failure 400 {object} ApiError "Unable to query SQL."
|
||||||
|
// @Failure 500 {object} ApiError "Failed to process data from SQL."
|
||||||
func (s *Server) getSources(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) getSources(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "ID")
|
payload := GetSource{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "id is not a uuid", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetSourceByID(*s.ctx, uuid)
|
res, err := s.dto.GetSourceById(r.Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "invalid id was given", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusNoContent)
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bResult, err := json.Marshal(res)
|
payload.Payload = res
|
||||||
|
|
||||||
|
bResult, err := json.Marshal(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bResult)
|
w.Write(bResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,37 +185,48 @@ func (s *Server) getSources(w http.ResponseWriter, r *http.Request) {
|
|||||||
// @Param name query string true "dadjokes"
|
// @Param name query string true "dadjokes"
|
||||||
// @Param source query string true "reddit"
|
// @Param source query string true "reddit"
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Config, Source
|
// @Tags Source
|
||||||
// @Router /config/sources/by/sourceAndName [get]
|
// @Router /sources/by/sourceAndName [get]
|
||||||
|
// @Success 200 {object} GetSource "ok"
|
||||||
|
// @Failure 204 {object} ApiError "No record found."
|
||||||
|
// @Failure 400 {object} ApiError "Unable to query SQL."
|
||||||
|
// @Failure 500 {object} ApiError "Failed to process data from SQL."
|
||||||
func (s *Server) GetSourceBySourceAndName(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetSourceBySourceAndName(w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
p := GetSource{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
query := r.URL.Query()
|
||||||
name := query["name"][0]
|
name := query["name"][0]
|
||||||
if name == "" {
|
if name == "" {
|
||||||
http.Error(w, "Parameter 'name' was missing in the query.", http.StatusInternalServerError)
|
s.WriteError(w, "Parameter 'name' was missing in the query.", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
source := query["source"][0]
|
source := query["source"][0]
|
||||||
if source == "" {
|
if source == "" {
|
||||||
http.Error(w, "The parameter 'source' was missing in the query.", http.StatusInternalServerError)
|
s.WriteError(w, "The parameter 'source' was missing in the query.", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
item, err := s.Db.GetSourceByNameAndSource(context.Background(), database.GetSourceByNameAndSourceParams{
|
item, err := s.dto.GetSourceByNameAndSource(r.Context(), name, source)
|
||||||
Name: name,
|
|
||||||
Source: source,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Unable to find the requested record.", http.StatusInternalServerError)
|
s.WriteError(w, "Unable to find the requested record.", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.Payload = item
|
||||||
|
|
||||||
bResult, err := json.Marshal(item)
|
bResult, err := json.Marshal(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
w.Write(bResult)
|
w.Write(bResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,20 +234,22 @@ func (s *Server) GetSourceBySourceAndName(w http.ResponseWriter, r *http.Request
|
|||||||
// @Summary Creates a new reddit source to monitor.
|
// @Summary Creates a new reddit source to monitor.
|
||||||
// @Param name query string true "name"
|
// @Param name query string true "name"
|
||||||
// @Param url query string true "url"
|
// @Param url query string true "url"
|
||||||
// @Tags Config, Source, Reddit
|
// @Tags Source
|
||||||
// @Router /config/sources/new/reddit [post]
|
// @Router /sources/new/reddit [post]
|
||||||
func (s *Server) newRedditSource(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) newRedditSource(w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_name := query["name"][0]
|
_name := query["name"][0]
|
||||||
_url := query["url"][0]
|
_url := query["url"][0]
|
||||||
//_tags := query["tags"][0]
|
//_tags := query["tags"][0]
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
if _url == "" {
|
if _url == "" {
|
||||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
s.WriteError(w, "url is missing a value", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(_url, "reddit.com") {
|
if !strings.Contains(_url, "reddit.com") {
|
||||||
http.Error(w, "invalid url", http.StatusBadRequest)
|
s.WriteError(w, "invalid url", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,13 +272,18 @@ func (s *Server) newRedditSource(w http.ResponseWriter, r *http.Request) {
|
|||||||
Url: _url,
|
Url: _url,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
}
|
}
|
||||||
s.Db.CreateSource(*s.ctx, params)
|
err := s.Db.CreateSource(*s.ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bJson)
|
w.Write(bJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,20 +291,21 @@ func (s *Server) newRedditSource(w http.ResponseWriter, r *http.Request) {
|
|||||||
// @Summary Creates a new youtube source to monitor.
|
// @Summary Creates a new youtube source to monitor.
|
||||||
// @Param name query string true "name"
|
// @Param name query string true "name"
|
||||||
// @Param url query string true "url"
|
// @Param url query string true "url"
|
||||||
// @Tags Config, Source, YouTube
|
// @Tags Source
|
||||||
// @Router /config/sources/new/youtube [post]
|
// @Router /sources/new/youtube [post]
|
||||||
func (s *Server) newYoutubeSource(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) newYoutubeSource(w http.ResponseWriter, r *http.Request) {
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_name := query["name"][0]
|
_name := query["name"][0]
|
||||||
_url := query["url"][0]
|
_url := query["url"][0]
|
||||||
//_tags := query["tags"][0]
|
//_tags := query["tags"][0]
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if _url == "" {
|
if _url == "" {
|
||||||
http.Error(w, "url is missing a value", http.StatusBadRequest)
|
s.WriteError(w, "url is missing a value", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(_url, "youtube.com") {
|
if !strings.Contains(_url, "youtube.com") {
|
||||||
http.Error(w, "invalid url", http.StatusBadRequest)
|
s.WriteError(w, "invalid url", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,22 +327,29 @@ func (s *Server) newYoutubeSource(w http.ResponseWriter, r *http.Request) {
|
|||||||
Url: _url,
|
Url: _url,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
}
|
}
|
||||||
s.Db.CreateSource(*s.ctx, params)
|
err := s.Db.CreateSource(*s.ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bJson)
|
w.Write(bJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTwitchSource
|
// NewTwitchSource
|
||||||
// @Summary Creates a new twitch source to monitor.
|
// @Summary Creates a new twitch source to monitor.
|
||||||
// @Param name query string true "name"
|
// @Param name query string true "name"
|
||||||
// @Tags Config, Source, Twitch
|
// @Tags Source
|
||||||
// @Router /config/sources/new/twitch [post]
|
// @Router /sources/new/twitch [post]
|
||||||
func (s *Server) newTwitchSource(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) newTwitchSource(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_name := query["name"][0]
|
_name := query["name"][0]
|
||||||
|
|
||||||
@ -278,13 +366,18 @@ func (s *Server) newTwitchSource(w http.ResponseWriter, r *http.Request) {
|
|||||||
Url: _url,
|
Url: _url,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
}
|
}
|
||||||
s.Db.CreateSource(*s.ctx, params)
|
err := s.Db.CreateSource(*s.ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bJson)
|
w.Write(bJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,73 +385,115 @@ func (s *Server) newTwitchSource(w http.ResponseWriter, r *http.Request) {
|
|||||||
// @Summary Marks a source as deleted based on its ID value.
|
// @Summary Marks a source as deleted based on its ID value.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Source
|
// @Tags Source
|
||||||
// @Router /config/sources/{id} [POST]
|
// @Router /sources/{id} [POST]
|
||||||
func (s *Server) deleteSources(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) deleteSources(w http.ResponseWriter, r *http.Request) {
|
||||||
//var item model.Sources = model.Sources{}
|
//var item model.Sources = model.Sources{}
|
||||||
|
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure we can find the record
|
// Check to make sure we can find the record
|
||||||
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the record
|
// Delete the record
|
||||||
err = s.Db.DeleteSource(*s.ctx, uuid)
|
err = s.Db.DeleteSource(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p := ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableSource
|
// DisableSource
|
||||||
// @Summary Disables a source from processing.
|
// @Summary Disables a source from processing.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Source
|
// @Tags Source
|
||||||
// @Router /config/sources/{id}/disable [post]
|
// @Router /sources/{id}/disable [post]
|
||||||
func (s *Server) disableSource(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) disableSource(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure we can find the record
|
// Check to make sure we can find the record
|
||||||
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.DisableSource(*s.ctx, uuid)
|
err = s.Db.DisableSource(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p := ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableSource
|
// EnableSource
|
||||||
// @Summary Enables a source to continue processing.
|
// @Summary Enables a source to continue processing.
|
||||||
// @Param id path string true "id"
|
// @Param id path string true "id"
|
||||||
// @Tags Config, Source
|
// @Tags Source
|
||||||
// @Router /config/sources/{id}/enable [post]
|
// @Router /sources/{id}/enable [post]
|
||||||
func (s *Server) enableSource(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) enableSource(w http.ResponseWriter, r *http.Request) {
|
||||||
id := chi.URLParam(r, "ID")
|
id := chi.URLParam(r, "ID")
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicln(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to make sure we can find the record
|
// Check to make sure we can find the record
|
||||||
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
_, err = s.Db.GetSourceByID(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.EnableSource(*s.ctx, uuid)
|
err = s.Db.EnableSource(*s.ctx, uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p := ApiStatusModel{
|
||||||
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
}
|
}
|
||||||
|
@ -5,64 +5,149 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jtom38/newsbot/collector/database"
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetSubscriptionsRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
r.Get("/", s.ListSubscriptions)
|
||||||
|
r.Get("/details", s.ListSubscriptionDetails)
|
||||||
|
r.Get("/by/discordId", s.GetSubscriptionsByDiscordId)
|
||||||
|
r.Get("/by/sourceId", s.GetSubscriptionsBySourceId)
|
||||||
|
r.Post("/discord/webhook/new", s.newDiscordWebHookSubscription)
|
||||||
|
r.Delete("/discord/webhook/delete", s.DeleteDiscordWebHookSubscription)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListSubscriptions struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.SubscriptionDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetSubscription struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.SubscriptionDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetSubscriptions
|
// GetSubscriptions
|
||||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Subscription
|
// @Tags Subscription
|
||||||
// @Router /subscriptions [get]
|
// @Router /subscriptions [get]
|
||||||
|
// @Success 200 {object} ListSubscriptions "ok"
|
||||||
|
// @Failure 400 {object} ApiError "Unable to reach SQL."
|
||||||
|
// @Failure 500 {object} ApiError "Failed to process data from SQL."
|
||||||
func (s *Server) ListSubscriptions(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ListSubscriptions(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
res, err := s.Db.ListSubscriptions(*s.ctx, 100)
|
payload := ListSubscriptions{
|
||||||
if err != nil {
|
ApiStatusModel: ApiStatusModel{
|
||||||
w.Write([]byte(err.Error()))
|
StatusCode: http.StatusOK,
|
||||||
panic(err)
|
Message: "OK",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
res, err := s.dto.ListSubscriptions(r.Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrUnableToConvertToJson, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
panic(err)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write(bres)
|
w.Write(bres)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListSubscriptionDetails struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.SubscriptionDetailsDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListSubscriptionDetails
|
||||||
|
// @Summary Returns the top 50 entries with full deatils on the source and output.
|
||||||
|
// @Produce application/json
|
||||||
|
// @Tags Subscription
|
||||||
|
// @Router /subscriptions/details [get]
|
||||||
|
// @Success 200 {object} ListSubscriptionDetails "ok"
|
||||||
|
func (s Server) ListSubscriptionDetails(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
payload := ListSubscriptionDetails{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Message: "OK",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := s.dto.ListSubscriptionDetails(r.Context(), 50)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.Payload = res
|
||||||
|
|
||||||
|
b, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
// GetSubscriptionsByDiscordId
|
// GetSubscriptionsByDiscordId
|
||||||
// @Summary Returns the top 100 entries from the queue to be processed.
|
// @Summary Returns the top 100 entries from the queue to be processed.
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Param id query string true "id"
|
// @Param id query string true "id"
|
||||||
// @Tags Subscription
|
// @Tags Subscription
|
||||||
// @Router /subscriptions/byDiscordId [get]
|
// @Router /subscriptions/by/discordId [get]
|
||||||
|
// @Success 200 {object} ListSubscriptions "ok"
|
||||||
|
// @Failure 400 {object} ApiError "Unable to reach SQL or Data problems"
|
||||||
|
// @Failure 500 {object} ApiError "Data problems"
|
||||||
func (s *Server) GetSubscriptionsByDiscordId(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetSubscriptionsByDiscordId(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set(HeaderContentType, ApplicationJson)
|
||||||
|
|
||||||
|
p := ListSubscriptions{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Message: "OK",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_id := query["id"][0]
|
_id := query["id"][0]
|
||||||
if _id == "" {
|
if _id == "" {
|
||||||
http.Error(w, ErrIdValueMissing, http.StatusBadRequest)
|
s.WriteError(w, ErrIdValueMissing, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, err := uuid.Parse(_id)
|
uuid, err := uuid.Parse(_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrValueNotUuid, http.StatusBadRequest)
|
s.WriteError(w, ErrValueNotUuid, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetSubscriptionsByDiscordWebHookId(*s.ctx, uuid)
|
res, err := s.dto.ListSubscriptionsByDiscordWebhookId(r.Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrNoRecordFound, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusNoContent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrUnableToConvertToJson, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,32 +159,42 @@ func (s *Server) GetSubscriptionsByDiscordId(w http.ResponseWriter, r *http.Requ
|
|||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Param id query string true "id"
|
// @Param id query string true "id"
|
||||||
// @Tags Subscription
|
// @Tags Subscription
|
||||||
// @Router /subscriptions/bySourceId [get]
|
// @Router /subscriptions/by/SourceId [get]
|
||||||
|
// @Success 200 {object} ListSubscriptions "ok"
|
||||||
func (s *Server) GetSubscriptionsBySourceId(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) GetSubscriptionsBySourceId(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
p := ListSubscriptions{
|
||||||
|
ApiStatusModel: ApiStatusModel{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Message: "OK",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
_id := query["id"][0]
|
_id := query["id"][0]
|
||||||
if _id == "" {
|
if _id == "" {
|
||||||
http.Error(w, ErrIdValueMissing, http.StatusBadRequest)
|
s.WriteError(w, ErrIdValueMissing, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, err := uuid.Parse(_id)
|
uuid, err := uuid.Parse(_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrValueNotUuid, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.Db.GetSubscriptionsByDiscordWebHookId(*s.ctx, uuid)
|
res, err := s.dto.ListSubscriptionsBySourceId(r.Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrNoRecordFound, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusNoContent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bres, err := json.Marshal(res)
|
p.Payload = res
|
||||||
|
|
||||||
|
bres, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrUnableToConvertToJson, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,48 +206,44 @@ func (s *Server) GetSubscriptionsBySourceId(w http.ResponseWriter, r *http.Reque
|
|||||||
// @Param discordWebHookId query string true "discordWebHookId"
|
// @Param discordWebHookId query string true "discordWebHookId"
|
||||||
// @Param sourceId query string true "sourceId"
|
// @Param sourceId query string true "sourceId"
|
||||||
// @Tags Subscription
|
// @Tags Subscription
|
||||||
// @Router /subscriptions/new/discordwebhook [post]
|
// @Router /subscriptions/discord/webhook/new [post]
|
||||||
func (s *Server) newDiscordWebHookSubscription(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) newDiscordWebHookSubscription(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
// Extract the values given
|
// Extract the values given
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
discordWebHookId := query["discordWebHookId"][0]
|
discordWebHookId := query["discordWebHookId"][0]
|
||||||
sourceId := query["sourceId"][0]
|
sourceId := query["sourceId"][0]
|
||||||
|
|
||||||
// Check to make we didnt get a null
|
// Check to make we didn't get a null
|
||||||
if discordWebHookId == "" {
|
if discordWebHookId == "" {
|
||||||
http.Error(w, "invalid discordWebHooksId given", http.StatusBadRequest)
|
s.WriteError(w, "invalid discordWebHooksId given", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if sourceId == "" {
|
if sourceId == "" {
|
||||||
http.Error(w, "invalid sourceID given", http.StatusBadRequest)
|
s.WriteError(w, "invalid sourceID given", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valide they are UUID values
|
// Validate they are UUID values
|
||||||
uHook, err := uuid.Parse(discordWebHookId)
|
uHook, err := uuid.Parse(discordWebHookId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "DiscordWebHooksID was not a uuid value.", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
uSource, err := uuid.Parse(sourceId)
|
uSource, err := uuid.Parse(sourceId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "SourceId was not a uuid value", http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the sub already exists
|
// Check if the sub already exists
|
||||||
item, err := s.Db.QuerySubscriptions(*s.ctx, database.QuerySubscriptionsParams{
|
_, err = s.Db.QuerySubscriptions(*s.ctx, database.QuerySubscriptionsParams{
|
||||||
Discordwebhookid: uHook,
|
Discordwebhookid: uHook,
|
||||||
Sourceid: uSource,
|
Sourceid: uSource,
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
bJson, err := json.Marshal(&item)
|
s.WriteError(w, "a subscription already exists between these two entities", http.StatusBadRequest)
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bJson)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,29 +253,39 @@ func (s *Server) newDiscordWebHookSubscription(w http.ResponseWriter, r *http.Re
|
|||||||
Discordwebhookid: uHook,
|
Discordwebhookid: uHook,
|
||||||
Sourceid: uSource,
|
Sourceid: uSource,
|
||||||
}
|
}
|
||||||
s.Db.CreateSubscription(*s.ctx, params)
|
err = s.Db.CreateSubscription(*s.ctx, params)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
w.Write(bJson)
|
w.Write(bJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteDiscordWebHookSubscription
|
// DeleteDiscordWebHookSubscription
|
||||||
// @Summary Removes a Discord WebHook Subscription based on the Subscription ID.
|
// @Summary Removes a Discord WebHook Subscription based on the Subscription ID.
|
||||||
// @Param Id query string true "Id"
|
// @Param id query string true "id"
|
||||||
// @Tags Config, Source, Discord, Subscription
|
// @Tags Subscription
|
||||||
// @Router /subscriptions/discord/webhook/delete [delete]
|
// @Router /subscriptions/discord/webhook/delete [delete]
|
||||||
func (s *Server) DeleteDiscordWebHookSubscription(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) DeleteDiscordWebHookSubscription(w http.ResponseWriter, r *http.Request) {
|
||||||
var ErrMissingSubscriptionID string = "Request was missing a 'Id' or was a invalid UUID."
|
var ErrMissingSubscriptionID string = "the request was missing a 'Id'"
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
|
|
||||||
uid, err := uuid.Parse(query["Id"][0])
|
id := query["id"][0]
|
||||||
|
if id == "" {
|
||||||
|
s.WriteError(w, ErrMissingSubscriptionID, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uid, err := uuid.Parse(query["id"][0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, ErrMissingSubscriptionID, http.StatusBadRequest)
|
s.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
services/cache/cache.go
vendored
12
services/cache/cache.go
vendored
@ -3,7 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jtom38/newsbot/collector/domain/model"
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CacheClient struct {
|
type CacheClient struct {
|
||||||
@ -19,7 +19,7 @@ func NewCacheClient(group string) CacheClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cc *CacheClient) Insert(key string, value string) {
|
func (cc *CacheClient) Insert(key string, value string) {
|
||||||
item := model.CacheItem{
|
item := models.CacheItem{
|
||||||
Key: key,
|
Key: key,
|
||||||
Value: value,
|
Value: value,
|
||||||
Group: cc.group,
|
Group: cc.group,
|
||||||
@ -29,7 +29,7 @@ func (cc *CacheClient) Insert(key string, value string) {
|
|||||||
cacheStorage = append(cacheStorage, &item)
|
cacheStorage = append(cacheStorage, &item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *CacheClient) FindByKey(key string) (*model.CacheItem, error) {
|
func (cc *CacheClient) FindByKey(key string) (*models.CacheItem, error) {
|
||||||
for _, item := range cacheStorage {
|
for _, item := range cacheStorage {
|
||||||
if item.Group != cc.group {
|
if item.Group != cc.group {
|
||||||
continue
|
continue
|
||||||
@ -46,10 +46,10 @@ func (cc *CacheClient) FindByKey(key string) (*model.CacheItem, error) {
|
|||||||
return item, nil
|
return item, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &model.CacheItem{}, ErrCacheRecordMissing
|
return &models.CacheItem{}, ErrCacheRecordMissing
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *CacheClient) FindByValue(value string) (*model.CacheItem, error) {
|
func (cc *CacheClient) FindByValue(value string) (*models.CacheItem, error) {
|
||||||
for _, item := range cacheStorage {
|
for _, item := range cacheStorage {
|
||||||
if item.Group != cc.group {
|
if item.Group != cc.group {
|
||||||
continue
|
continue
|
||||||
@ -65,5 +65,5 @@ func (cc *CacheClient) FindByValue(value string) (*model.CacheItem, error) {
|
|||||||
}
|
}
|
||||||
return item, nil
|
return item, nil
|
||||||
}
|
}
|
||||||
return &model.CacheItem{}, ErrCacheRecordMissing
|
return &models.CacheItem{}, ErrCacheRecordMissing
|
||||||
}
|
}
|
||||||
|
4
services/cache/common.go
vendored
4
services/cache/common.go
vendored
@ -3,11 +3,11 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/jtom38/newsbot/collector/domain/model"
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cacheStorage []*model.CacheItem
|
cacheStorage []*models.CacheItem
|
||||||
|
|
||||||
ErrCacheRecordMissing = errors.New("unable to find the requested record")
|
ErrCacheRecordMissing = errors.New("unable to find the requested record")
|
||||||
)
|
)
|
||||||
|
6
services/cache/monitor.go
vendored
6
services/cache/monitor.go
vendored
@ -3,7 +3,7 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jtom38/newsbot/collector/domain/model"
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// When a record becomes tainted, it needs to be renewed or it will be dropped from the cache.
|
// When a record becomes tainted, it needs to be renewed or it will be dropped from the cache.
|
||||||
@ -36,8 +36,8 @@ func (cam CacheAgeMonitor) CheckExpiredEntries() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This creates a new slice and skips over the item that needs to be dropped
|
// This creates a new slice and skips over the item that needs to be dropped
|
||||||
func (cam CacheAgeMonitor) removeEntry(index int) []*model.CacheItem {
|
func (cam CacheAgeMonitor) removeEntry(index int) []*models.CacheItem {
|
||||||
var temp []*model.CacheItem
|
var temp []*models.CacheItem
|
||||||
for i, item := range cacheStorage {
|
for i, item := range cacheStorage {
|
||||||
if i != index {
|
if i != index {
|
||||||
temp = append(temp, item)
|
temp = append(temp, item)
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/go-rod/rod"
|
"github.com/go-rod/rod"
|
||||||
"github.com/go-rod/rod/lib/launcher"
|
"github.com/go-rod/rod/lib/launcher"
|
||||||
"github.com/jtom38/newsbot/collector/database"
|
"github.com/jtom38/newsbot/collector/database"
|
||||||
"github.com/jtom38/newsbot/collector/domain/model"
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
"github.com/jtom38/newsbot/collector/services/config"
|
"github.com/jtom38/newsbot/collector/services/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,8 +65,8 @@ func (rc *RedditClient) GetPage(parser *rod.Browser, url string) *rod.Page {
|
|||||||
|
|
||||||
// GetContent() reaches out to Reddit and pulls the Json data.
|
// GetContent() reaches out to Reddit and pulls the Json data.
|
||||||
// It will then convert the data to a struct and return the struct.
|
// It will then convert the data to a struct and return the struct.
|
||||||
func (rc *RedditClient) GetContent() (model.RedditJsonContent, error) {
|
func (rc *RedditClient) GetContent() (models.RedditJsonContent, error) {
|
||||||
var items model.RedditJsonContent = model.RedditJsonContent{}
|
var items models.RedditJsonContent = models.RedditJsonContent{}
|
||||||
|
|
||||||
// TODO Wire this to support the config options
|
// TODO Wire this to support the config options
|
||||||
Url := fmt.Sprintf("%v.json", rc.record.Url)
|
Url := fmt.Sprintf("%v.json", rc.record.Url)
|
||||||
@ -88,7 +88,7 @@ func (rc *RedditClient) GetContent() (model.RedditJsonContent, error) {
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RedditClient) ConvertToArticles(items model.RedditJsonContent) []database.Article {
|
func (rc *RedditClient) ConvertToArticles(items models.RedditJsonContent) []database.Article {
|
||||||
var redditArticles []database.Article
|
var redditArticles []database.Article
|
||||||
for _, item := range items.Data.Children {
|
for _, item := range items.Data.Children {
|
||||||
var article database.Article
|
var article database.Article
|
||||||
@ -104,7 +104,7 @@ func (rc *RedditClient) ConvertToArticles(items model.RedditJsonContent) []datab
|
|||||||
|
|
||||||
// ConvertToArticle() will take the reddit model struct and convert them over to Article structs.
|
// ConvertToArticle() will take the reddit model struct and convert them over to Article structs.
|
||||||
// This data can be passed to the database.
|
// This data can be passed to the database.
|
||||||
func (rc *RedditClient) convertToArticle(source model.RedditPost) (database.Article, error) {
|
func (rc *RedditClient) convertToArticle(source models.RedditPost) (database.Article, error) {
|
||||||
var item database.Article
|
var item database.Article
|
||||||
|
|
||||||
if source.Content == "" && source.Url != "" {
|
if source.Content == "" && source.Url != "" {
|
||||||
@ -131,7 +131,7 @@ func (rc *RedditClient) convertToArticle(source model.RedditPost) (database.Arti
|
|||||||
return item, nil
|
return item, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RedditClient) convertPicturePost(source model.RedditPost) database.Article {
|
func (rc *RedditClient) convertPicturePost(source models.RedditPost) database.Article {
|
||||||
var item = database.Article{
|
var item = database.Article{
|
||||||
Sourceid: rc.record.ID,
|
Sourceid: rc.record.ID,
|
||||||
Title: source.Title,
|
Title: source.Title,
|
||||||
@ -149,7 +149,7 @@ func (rc *RedditClient) convertPicturePost(source model.RedditPost) database.Art
|
|||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RedditClient) convertTextPost(source model.RedditPost) database.Article {
|
func (rc *RedditClient) convertTextPost(source models.RedditPost) database.Article {
|
||||||
var item = database.Article{
|
var item = database.Article{
|
||||||
Sourceid: rc.record.ID,
|
Sourceid: rc.record.ID,
|
||||||
Tags: "a",
|
Tags: "a",
|
||||||
@ -164,7 +164,7 @@ func (rc *RedditClient) convertTextPost(source model.RedditPost) database.Articl
|
|||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RedditClient) convertVideoPost(source model.RedditPost) database.Article {
|
func (rc *RedditClient) convertVideoPost(source models.RedditPost) database.Article {
|
||||||
var item = database.Article{
|
var item = database.Article{
|
||||||
Sourceid: rc.record.ID,
|
Sourceid: rc.record.ID,
|
||||||
Tags: "a",
|
Tags: "a",
|
||||||
@ -180,7 +180,7 @@ func (rc *RedditClient) convertVideoPost(source model.RedditPost) database.Artic
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This post is nothing more then a redirect to another location.
|
// This post is nothing more then a redirect to another location.
|
||||||
func (rc *RedditClient) convertRedirectPost(source model.RedditPost) database.Article {
|
func (rc *RedditClient) convertRedirectPost(source models.RedditPost) database.Article {
|
||||||
var item = database.Article{
|
var item = database.Article{
|
||||||
Sourceid: rc.record.ID,
|
Sourceid: rc.record.ID,
|
||||||
Tags: "a",
|
Tags: "a",
|
||||||
|
@ -4,16 +4,16 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/jtom38/newsbot/collector/domain/model"
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
"github.com/jtom38/newsbot/collector/services/cache"
|
"github.com/jtom38/newsbot/collector/services/cache"
|
||||||
"github.com/mmcdole/gofeed"
|
"github.com/mmcdole/gofeed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rssClient struct {
|
type rssClient struct {
|
||||||
SourceRecord model.Sources
|
SourceRecord models.Sources
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRssClient(sourceRecord model.Sources) rssClient {
|
func NewRssClient(sourceRecord models.Sources) rssClient {
|
||||||
client := rssClient{
|
client := rssClient{
|
||||||
SourceRecord: sourceRecord,
|
SourceRecord: sourceRecord,
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@ package input_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jtom38/newsbot/collector/domain/model"
|
"github.com/jtom38/newsbot/collector/domain/models"
|
||||||
"github.com/jtom38/newsbot/collector/services/input"
|
"github.com/jtom38/newsbot/collector/services/input"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rssRecord = model.Sources{
|
var rssRecord = models.Sources{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Name: "ArsTechnica",
|
Name: "ArsTechnica",
|
||||||
Url: "https://feeds.arstechnica.com/arstechnica/index",
|
Url: "https://feeds.arstechnica.com/arstechnica/index",
|
||||||
|
Loading…
Reference in New Issue
Block a user