source handlers have been updated

This commit is contained in:
James Tombleson 2024-04-28 19:29:49 -07:00
parent 7fee03c416
commit 84d108f2dd
7 changed files with 620 additions and 348 deletions

View File

@ -498,11 +498,19 @@ const docTemplate = `{
"Source" "Source"
], ],
"summary": "Lists the top 50 records", "summary": "Lists the top 50 records",
"parameters": [
{
"type": "string",
"description": "page number",
"name": "page",
"in": "query"
}
],
"responses": { "responses": {
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.ListSources" "$ref": "#/definitions/domain.SourcesResponse"
} }
}, },
"400": { "400": {
@ -530,25 +538,31 @@ const docTemplate = `{
"name": "source", "name": "source",
"in": "query", "in": "query",
"required": true "required": true
},
{
"type": "string",
"description": "page number",
"name": "page",
"in": "query"
} }
], ],
"responses": { "responses": {
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.ListSources" "$ref": "#/definitions/domain.SourcesResponse"
} }
}, },
"400": { "400": {
"description": "Unable to query SQL.", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
}, },
"500": { "500": {
"description": "Problems with data.", "description": "Internal Server Error",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
} }
} }
@ -583,25 +597,19 @@ const docTemplate = `{
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.GetSource" "$ref": "#/definitions/domain.SourcesResponse"
}
},
"204": {
"description": "No record found.",
"schema": {
"$ref": "#/definitions/v1.ApiError"
} }
}, },
"400": { "400": {
"description": "Unable to query SQL.", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
}, },
"500": { "500": {
"description": "Failed to process data from SQL.", "description": "Internal Server Error",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
} }
} }
@ -629,7 +637,70 @@ const docTemplate = `{
"required": true "required": true
} }
], ],
"responses": {} "responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
}
},
"/sources/new/rss": {
"post": {
"tags": [
"Source"
],
"summary": "Creates a new rss source to monitor.",
"parameters": [
{
"type": "string",
"description": "Site Name",
"name": "name",
"in": "query",
"required": true
},
{
"type": "string",
"description": "RSS Url",
"name": "url",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
} }
}, },
"/sources/new/twitch": { "/sources/new/twitch": {
@ -686,7 +757,7 @@ const docTemplate = `{
"summary": "Returns a single entity by ID", "summary": "Returns a single entity by ID",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "integer",
"description": "uuid", "description": "uuid",
"name": "id", "name": "id",
"in": "path", "in": "path",
@ -697,25 +768,19 @@ const docTemplate = `{
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.GetSource" "$ref": "#/definitions/domain.SourcesResponse"
}
},
"204": {
"description": "No record found.",
"schema": {
"$ref": "#/definitions/v1.ApiError"
} }
}, },
"400": { "400": {
"description": "Unable to query SQL.", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
}, },
"500": { "500": {
"description": "Failed to process data from SQL.", "description": "Internal Server Error",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
} }
} }
@ -745,14 +810,33 @@ const docTemplate = `{
"summary": "Disables a source from processing.", "summary": "Disables a source from processing.",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "integer",
"description": "id", "description": "id",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
} }
], ],
"responses": {} "responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
} }
}, },
"/sources/{id}/enable": { "/sources/{id}/enable": {
@ -770,7 +854,26 @@ const docTemplate = `{
"required": true "required": true
} }
], ],
"responses": {} "responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
} }
}, },
"/subscriptions": { "/subscriptions": {
@ -1076,6 +1179,20 @@ const docTemplate = `{
} }
} }
}, },
"domain.SourcesResponse": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"payload": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.SourceDto"
}
}
}
},
"models.ArticleDetailsDto": { "models.ArticleDetailsDto": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -1231,20 +1348,6 @@ const docTemplate = `{
} }
} }
}, },
"v1.GetSource": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"payload": {
"$ref": "#/definitions/models.SourceDto"
},
"status": {
"type": "integer"
}
}
},
"v1.ListDiscordWebHooksQueueResults": { "v1.ListDiscordWebHooksQueueResults": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -1262,23 +1365,6 @@ const docTemplate = `{
} }
} }
}, },
"v1.ListSources": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"payload": {
"type": "array",
"items": {
"$ref": "#/definitions/models.SourceDto"
}
},
"status": {
"type": "integer"
}
}
},
"v1.ListSubscriptionDetails": { "v1.ListSubscriptionDetails": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -489,11 +489,19 @@
"Source" "Source"
], ],
"summary": "Lists the top 50 records", "summary": "Lists the top 50 records",
"parameters": [
{
"type": "string",
"description": "page number",
"name": "page",
"in": "query"
}
],
"responses": { "responses": {
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.ListSources" "$ref": "#/definitions/domain.SourcesResponse"
} }
}, },
"400": { "400": {
@ -521,25 +529,31 @@
"name": "source", "name": "source",
"in": "query", "in": "query",
"required": true "required": true
},
{
"type": "string",
"description": "page number",
"name": "page",
"in": "query"
} }
], ],
"responses": { "responses": {
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.ListSources" "$ref": "#/definitions/domain.SourcesResponse"
} }
}, },
"400": { "400": {
"description": "Unable to query SQL.", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
}, },
"500": { "500": {
"description": "Problems with data.", "description": "Internal Server Error",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
} }
} }
@ -574,25 +588,19 @@
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.GetSource" "$ref": "#/definitions/domain.SourcesResponse"
}
},
"204": {
"description": "No record found.",
"schema": {
"$ref": "#/definitions/v1.ApiError"
} }
}, },
"400": { "400": {
"description": "Unable to query SQL.", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
}, },
"500": { "500": {
"description": "Failed to process data from SQL.", "description": "Internal Server Error",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
} }
} }
@ -620,7 +628,70 @@
"required": true "required": true
} }
], ],
"responses": {} "responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
}
},
"/sources/new/rss": {
"post": {
"tags": [
"Source"
],
"summary": "Creates a new rss source to monitor.",
"parameters": [
{
"type": "string",
"description": "Site Name",
"name": "name",
"in": "query",
"required": true
},
{
"type": "string",
"description": "RSS Url",
"name": "url",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
} }
}, },
"/sources/new/twitch": { "/sources/new/twitch": {
@ -677,7 +748,7 @@
"summary": "Returns a single entity by ID", "summary": "Returns a single entity by ID",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "integer",
"description": "uuid", "description": "uuid",
"name": "id", "name": "id",
"in": "path", "in": "path",
@ -688,25 +759,19 @@
"200": { "200": {
"description": "ok", "description": "ok",
"schema": { "schema": {
"$ref": "#/definitions/v1.GetSource" "$ref": "#/definitions/domain.SourcesResponse"
}
},
"204": {
"description": "No record found.",
"schema": {
"$ref": "#/definitions/v1.ApiError"
} }
}, },
"400": { "400": {
"description": "Unable to query SQL.", "description": "Bad Request",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
}, },
"500": { "500": {
"description": "Failed to process data from SQL.", "description": "Internal Server Error",
"schema": { "schema": {
"$ref": "#/definitions/v1.ApiError" "$ref": "#/definitions/domain.BaseResponse"
} }
} }
} }
@ -736,14 +801,33 @@
"summary": "Disables a source from processing.", "summary": "Disables a source from processing.",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "integer",
"description": "id", "description": "id",
"name": "id", "name": "id",
"in": "path", "in": "path",
"required": true "required": true
} }
], ],
"responses": {} "responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
} }
}, },
"/sources/{id}/enable": { "/sources/{id}/enable": {
@ -761,7 +845,26 @@
"required": true "required": true
} }
], ],
"responses": {} "responses": {
"200": {
"description": "ok",
"schema": {
"$ref": "#/definitions/domain.SourcesResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.BaseResponse"
}
}
}
} }
}, },
"/subscriptions": { "/subscriptions": {
@ -1067,6 +1170,20 @@
} }
} }
}, },
"domain.SourcesResponse": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"payload": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.SourceDto"
}
}
}
},
"models.ArticleDetailsDto": { "models.ArticleDetailsDto": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -1222,20 +1339,6 @@
} }
} }
}, },
"v1.GetSource": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"payload": {
"$ref": "#/definitions/models.SourceDto"
},
"status": {
"type": "integer"
}
}
},
"v1.ListDiscordWebHooksQueueResults": { "v1.ListDiscordWebHooksQueueResults": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -1253,23 +1356,6 @@
} }
} }
}, },
"v1.ListSources": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"payload": {
"type": "array",
"items": {
"$ref": "#/definitions/models.SourceDto"
}
},
"status": {
"type": "integer"
}
}
},
"v1.ListSubscriptionDetails": { "v1.ListSubscriptionDetails": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -93,6 +93,15 @@ definitions:
url: url:
type: string type: string
type: object type: object
domain.SourcesResponse:
properties:
message:
type: string
payload:
items:
$ref: '#/definitions/domain.SourceDto'
type: array
type: object
models.ArticleDetailsDto: models.ArticleDetailsDto:
properties: properties:
authorImage: authorImage:
@ -194,15 +203,6 @@ definitions:
status: status:
type: integer type: integer
type: object type: object
v1.GetSource:
properties:
message:
type: string
payload:
$ref: '#/definitions/models.SourceDto'
status:
type: integer
type: object
v1.ListDiscordWebHooksQueueResults: v1.ListDiscordWebHooksQueueResults:
properties: properties:
message: message:
@ -214,17 +214,6 @@ definitions:
status: status:
type: integer type: integer
type: object type: object
v1.ListSources:
properties:
message:
type: string
payload:
items:
$ref: '#/definitions/models.SourceDto'
type: array
status:
type: integer
type: object
v1.ListSubscriptionDetails: v1.ListSubscriptionDetails:
properties: properties:
message: message:
@ -566,13 +555,18 @@ paths:
- Settings - Settings
/sources: /sources:
get: get:
parameters:
- description: page number
in: query
name: page
type: string
produces: produces:
- application/json - application/json
responses: responses:
"200": "200":
description: ok description: ok
schema: schema:
$ref: '#/definitions/v1.ListSources' $ref: '#/definitions/domain.SourcesResponse'
"400": "400":
description: Unable to reach SQL or Data problems description: Unable to reach SQL or Data problems
schema: schema:
@ -587,26 +581,22 @@ paths:
in: path in: path
name: id name: id
required: true required: true
type: string type: integer
produces: produces:
- application/json - application/json
responses: responses:
"200": "200":
description: ok description: ok
schema: schema:
$ref: '#/definitions/v1.GetSource' $ref: '#/definitions/domain.SourcesResponse'
"204":
description: No record found.
schema:
$ref: '#/definitions/v1.ApiError'
"400": "400":
description: Unable to query SQL. description: Bad Request
schema: schema:
$ref: '#/definitions/v1.ApiError' $ref: '#/definitions/domain.BaseResponse'
"500": "500":
description: Failed to process data from SQL. description: Internal Server Error
schema: schema:
$ref: '#/definitions/v1.ApiError' $ref: '#/definitions/domain.BaseResponse'
summary: Returns a single entity by ID summary: Returns a single entity by ID
tags: tags:
- Source - Source
@ -628,8 +618,20 @@ paths:
in: path in: path
name: id name: id
required: true required: true
type: string type: integer
responses: {} responses:
"200":
description: ok
schema:
$ref: '#/definitions/domain.SourcesResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/domain.BaseResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/domain.BaseResponse'
summary: Disables a source from processing. summary: Disables a source from processing.
tags: tags:
- Source - Source
@ -641,7 +643,19 @@ paths:
name: id name: id
required: true required: true
type: string type: string
responses: {} responses:
"200":
description: ok
schema:
$ref: '#/definitions/domain.SourcesResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/domain.BaseResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/domain.BaseResponse'
summary: Enables a source to continue processing. summary: Enables a source to continue processing.
tags: tags:
- Source - Source
@ -653,21 +667,25 @@ paths:
name: source name: source
required: true required: true
type: string type: string
- description: page number
in: query
name: page
type: string
produces: produces:
- application/json - application/json
responses: responses:
"200": "200":
description: ok description: ok
schema: schema:
$ref: '#/definitions/v1.ListSources' $ref: '#/definitions/domain.SourcesResponse'
"400": "400":
description: Unable to query SQL. description: Bad Request
schema: schema:
$ref: '#/definitions/v1.ApiError' $ref: '#/definitions/domain.BaseResponse'
"500": "500":
description: Problems with data. description: Internal Server Error
schema: schema:
$ref: '#/definitions/v1.ApiError' $ref: '#/definitions/domain.BaseResponse'
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'
tags: tags:
- Source - Source
@ -690,19 +708,15 @@ paths:
"200": "200":
description: ok description: ok
schema: schema:
$ref: '#/definitions/v1.GetSource' $ref: '#/definitions/domain.SourcesResponse'
"204":
description: No record found.
schema:
$ref: '#/definitions/v1.ApiError'
"400": "400":
description: Unable to query SQL. description: Bad Request
schema: schema:
$ref: '#/definitions/v1.ApiError' $ref: '#/definitions/domain.BaseResponse'
"500": "500":
description: Failed to process data from SQL. description: Internal Server Error
schema: schema:
$ref: '#/definitions/v1.ApiError' $ref: '#/definitions/domain.BaseResponse'
summary: Returns a single entity by ID summary: Returns a single entity by ID
tags: tags:
- Source - Source
@ -719,10 +733,51 @@ paths:
name: url name: url
required: true required: true
type: string type: string
responses: {} responses:
"200":
description: ok
schema:
$ref: '#/definitions/domain.SourcesResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/domain.BaseResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/domain.BaseResponse'
summary: Creates a new reddit source to monitor. summary: Creates a new reddit source to monitor.
tags: tags:
- Source - Source
/sources/new/rss:
post:
parameters:
- description: Site Name
in: query
name: name
required: true
type: string
- description: RSS Url
in: query
name: url
required: true
type: string
responses:
"200":
description: ok
schema:
$ref: '#/definitions/domain.SourcesResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/domain.BaseResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/domain.BaseResponse'
summary: Creates a new rss source to monitor.
tags:
- Source
/sources/new/twitch: /sources/new/twitch:
post: post:
parameters: parameters:

View File

@ -24,3 +24,8 @@ type DiscordWebhookResponse struct {
BaseResponse BaseResponse
Payload []DiscordWebHookDto `json:"payload"` Payload []DiscordWebHookDto `json:"payload"`
} }
type SourcesResponse struct {
BaseResponse
Payload []SourceDto `json:"payload"`
}

View File

@ -23,14 +23,11 @@ type Handler struct {
} }
const ( const (
HeaderContentType = "Content-Type" ErrParameterIdMissing = "The requested parameter ID was not found."
ErrParameterMissing = "The requested parameter was not found found:"
//ApplicationJson = "application/json" ErrUnableToParseId = "Unable to parse the requested ID"
ErrRecordMissing = "The requested record was not found"
ErrParameterIdMissing = "The requested parameter ID was not found." ErrFailedToCreateRecord = "The record was not created due to a database problem"
ErrParameterMissing = "The requested parameter was found found:"
ErrUnableToParseId = "Unable to parse the requested ID."
ErrRecordMissing = "The requested record was not found"
ResponseMessageSuccess = "Success" ResponseMessageSuccess = "Success"
) )
@ -79,11 +76,11 @@ func NewServer(ctx context.Context, db *database.Queries, configs services.Confi
sources.GET("/", s.listSources) sources.GET("/", s.listSources)
sources.GET("/by/source", s.listSourcesBySource) sources.GET("/by/source", s.listSourcesBySource)
sources.GET("/by/sourceAndName", s.GetSourceBySourceAndName) sources.GET("/by/sourceAndName", s.GetSourceBySourceAndName)
sources.POST("/new/reddit", s.newRedditSource) //sources.POST("/new/reddit", s.newRedditSource)
sources.POST("/new/youtube", s.newYoutubeSource) //sources.POST("/new/youtube", s.newYoutubeSource)
sources.POST("/new/twitch", s.newTwitchSource) //sources.POST("/new/twitch", s.newTwitchSource)
sources.POST("/new/rss", s.newRssSource)
sources.GET("/:ID/", s.getSources) sources.GET("/:ID/", s.getSource)
sources.DELETE("/:ID/", s.deleteSources) sources.DELETE("/:ID/", s.deleteSources)
sources.POST("/:ID/disable", s.disableSource) sources.POST("/:ID/disable", s.disableSource)
sources.POST("/:ID/enable", s.enableSource) sources.POST("/:ID/enable", s.enableSource)

View File

@ -5,11 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"strings" "strings"
"git.jamestombleson.com/jtom38/newsbot-api/internal/database" "git.jamestombleson.com/jtom38/newsbot-api/internal/database"
"git.jamestombleson.com/jtom38/newsbot-api/internal/domain" "git.jamestombleson.com/jtom38/newsbot-api/internal/domain"
"git.jamestombleson.com/jtom38/newsbot-api/internal/domain/models" "git.jamestombleson.com/jtom38/newsbot-api/internal/domain/models"
"git.jamestombleson.com/jtom38/newsbot-api/internal/services"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -26,115 +28,105 @@ type GetSource struct {
// ListSources // ListSources
// @Summary Lists the top 50 records // @Summary Lists the top 50 records
// @Param page query string false "page number"
// @Produce application/json // @Produce application/json
// @Tags Source // @Tags Source
// @Router /sources [get] // @Router /sources [get]
// @Success 200 {object} ListSources "ok" // @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 400 {object} domain.BaseResponse "Unable to reach SQL or Data problems" // @Failure 400 {object} domain.BaseResponse "Unable to reach SQL or Data problems"
func (s *Handler) listSources(c echo.Context) error { func (s *Handler) listSources(c echo.Context) error {
//TODO Add top? resp := domain.SourcesResponse {
/* BaseResponse: domain.BaseResponse{
top := chi.URLParam(r, "top") Message: ResponseMessageSuccess,
topInt, err := strconv.ParseInt(top, 0, 32)
if err != nil {
panic(err)
}
res, err := s.Db.ListSources(r.Context(), int32(topInt))
*/
p := ListSources{
ApiStatusModel: ApiStatusModel{
StatusCode: http.StatusOK,
Message: "OK",
}, },
} }
page, err := strconv.Atoi(c.QueryParam("page"))
if err != nil {
page = 0
}
// Default way of showing all sources // Default way of showing all sources
items, err := s.dto.ListSources(c.Request().Context(), 50) items, err := s.repo.Sources.List(c.Request().Context(), page, 25)
if err != nil { if err != nil {
s.WriteError(c, err, http.StatusInternalServerError) s.WriteError(c, err, http.StatusInternalServerError)
} }
p.Payload = items resp.Payload = services.SourcesToDto(items)
return c.JSON(http.StatusOK, p) return c.JSON(http.StatusOK, resp)
} }
// 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"
// @Param page query string false "page number"
// @Produce application/json // @Produce application/json
// @Tags Source // @Tags Source
// @Router /sources/by/source [get] // @Router /sources/by/source [get]
// @Success 200 {object} ListSources "ok" // @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 400 {object} ApiError "Unable to query SQL." // @Failure 400 {object} domain.BaseResponse
// @Failure 500 {object} ApiError "Problems with data." // @Failure 500 {object} domain.BaseResponse
func (s *Handler) listSourcesBySource(c echo.Context) error { func (s *Handler) listSourcesBySource(c echo.Context) error {
//TODO Add top? resp := domain.SourcesResponse{
/* BaseResponse: domain.BaseResponse{
top := chi.URLParam(r, "top") Message: ResponseMessageSuccess,
topInt, err := strconv.ParseInt(top, 0, 32)
if err != nil {
panic(err)
}
res, err := s.Db.ListSources(r.Context(), int32(topInt))
*/
p := ListSources{
ApiStatusModel: ApiStatusModel{
StatusCode: http.StatusOK,
Message: "OK",
}, },
} }
source := c.QueryParam("source") source := c.QueryParam("source")
if source == "" {
s.WriteMessage(c, fmt.Sprintf("%s source", ErrParameterMissing), http.StatusBadRequest)
}
page, err := strconv.Atoi(c.QueryParam("page"))
if err != nil {
page = 0
}
// Shows the list by Sources.source // Shows the list by Sources.source
res, err := s.dto.ListSourcesBySource(c.Request().Context(), source) items, err := s.repo.Sources.ListBySource(c.Request().Context(), page, 25, source)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
Message: err.Error(), Message: err.Error(),
}) })
} }
p.Payload = res resp.Payload = services.SourcesToDto(items)
return c.JSON(http.StatusOK, p) return c.JSON(http.StatusOK, resp)
} }
// GetSource // GetSource
// @Summary Returns a single entity by ID // @Summary Returns a single entity by ID
// @Param id path string true "uuid" // @Param id path int true "uuid"
// @Produce application/json // @Produce application/json
// @Tags Source // @Tags Source
// @Router /sources/{id} [get] // @Router /sources/{id} [get]
// @Success 200 {object} GetSource "ok" // @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 204 {object} ApiError "No record found." // @Failure 400 {object} domain.BaseResponse
// @Failure 400 {object} ApiError "Unable to query SQL." // @Failure 500 {object} domain.BaseResponse
// @Failure 500 {object} ApiError "Failed to process data from SQL." func (s *Handler) getSource(c echo.Context) error {
func (s *Handler) getSources(c echo.Context) error { resp := domain.SourcesResponse{
payload := GetSource{ BaseResponse: domain.BaseResponse{
ApiStatusModel: ApiStatusModel{ Message: ResponseMessageSuccess,
Message: "OK",
StatusCode: http.StatusOK,
}, },
} }
id := c.Param("ID") id, err := strconv.Atoi(c.Param("ID"))
uuid, err := uuid.Parse(id)
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, domain.BaseResponse{ return c.JSON(http.StatusBadRequest, domain.BaseResponse{
Message: ErrUnableToParseId, Message: ErrUnableToParseId,
}) })
} }
res, err := s.dto.GetSourceById(c.Request().Context(), uuid) item, err := s.repo.Sources.GetById(c.Request().Context(), int64(id))
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusInternalServerError)
Message: ErrNoRecordFound,
})
} }
payload.Payload = res var dto []domain.SourceDto
return c.JSON(http.StatusOK, payload) dto = append(dto, services.SourceToDto(item))
resp.Payload = dto
return c.JSON(http.StatusOK, resp)
} }
// GetSourceByNameAndSource // GetSourceByNameAndSource
@ -144,15 +136,13 @@ func (s *Handler) getSources(c echo.Context) error {
// @Produce application/json // @Produce application/json
// @Tags Source // @Tags Source
// @Router /sources/by/sourceAndName [get] // @Router /sources/by/sourceAndName [get]
// @Success 200 {object} GetSource "ok" // @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 204 {object} ApiError "No record found." // @Failure 400 {object} domain.BaseResponse
// @Failure 400 {object} ApiError "Unable to query SQL." // @Failure 500 {object} domain.BaseResponse
// @Failure 500 {object} ApiError "Failed to process data from SQL."
func (s *Handler) GetSourceBySourceAndName(c echo.Context) error { func (s *Handler) GetSourceBySourceAndName(c echo.Context) error {
p := GetSource{ resp := domain.SourcesResponse{
ApiStatusModel: ApiStatusModel{ BaseResponse: domain.BaseResponse{
Message: "OK", Message: ResponseMessageSuccess,
StatusCode: http.StatusOK,
}, },
} }
@ -164,25 +154,15 @@ func (s *Handler) GetSourceBySourceAndName(c echo.Context) error {
}) })
} }
//name := c.QueryParam("name") item, err := s.repo.Sources.GetBySourceAndName(c.Request().Context(), param.Source, param.Name)
//if name == "" {
// s.WriteError(w, "Parameter 'name' was missing in the query.", http.StatusInternalServerError)
// return c.JSON(http.bad)
//}
//source := query["source"][0]
//if source == "" {
// s.WriteError(w, "The parameter 'source' was missing in the query.", http.StatusInternalServerError)
// return
//}
item, err := s.dto.GetSourceByNameAndSource(c.Request().Context(), param.Name, param.Source)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error()) return c.JSON(http.StatusInternalServerError, err.Error())
} }
p.Payload = item var dto []domain.SourceDto
return c.JSON(http.StatusOK, p) dto = append(dto, services.SourceToDto(item))
resp.Payload = dto
return c.JSON(http.StatusOK, resp)
} }
// NewRedditSource // NewRedditSource
@ -191,7 +171,16 @@ func (s *Handler) GetSourceBySourceAndName(c echo.Context) error {
// @Param url query string true "url" // @Param url query string true "url"
// @Tags Source // @Tags Source
// @Router /sources/new/reddit [post] // @Router /sources/new/reddit [post]
// @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 400 {object} domain.BaseResponse
// @Failure 500 {object} domain.BaseResponse
func (s *Handler) newRedditSource(c echo.Context) error { func (s *Handler) newRedditSource(c echo.Context) error {
resp := domain.SourcesResponse{
BaseResponse: domain.BaseResponse{
Message: ResponseMessageSuccess,
},
}
var param domain.NewSourceParamRequest var param domain.NewSourceParamRequest
err := c.Bind(&param) err := c.Bind(&param)
if err != nil { if err != nil {
@ -199,10 +188,6 @@ func (s *Handler) newRedditSource(c echo.Context) error {
Message: err.Error(), Message: err.Error(),
}) })
} }
//query := r.URL.Query()
//_name := query["name"][0]
//_url := query["url"][0]
//_tags := query["tags"][0]
if param.Url == "" { if param.Url == "" {
return c.JSON(http.StatusBadRequest, domain.BaseResponse{ return c.JSON(http.StatusBadRequest, domain.BaseResponse{
@ -215,40 +200,25 @@ func (s *Handler) newRedditSource(c echo.Context) error {
}) })
} }
/* tags := fmt.Sprintf("twitch, %v, %s", param.Name, param.Tags)
var tags string rows, err := s.repo.Sources.Create(c.Request().Context(), domain.SourceCollectorReddit, param.Name, param.Url, tags, true)
if _tags == "" {
tags = fmt.Sprintf("twitch, %v", _name)
} else {
}
*/
tags := fmt.Sprintf("twitch, %v", param.Name)
params := database.CreateSourceParams{
ID: uuid.New(),
Site: "reddit",
Name: param.Name,
Source: "reddit",
Type: "feed",
Enabled: true,
Url: param.Url,
Tags: tags,
}
err = s.Db.CreateSource(c.Request().Context(), params)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusInternalServerError)
Message: err.Error(),
})
} }
//s.WriteJson(w, &params)
bJson, err := json.Marshal(&params) if rows != 1 {
s.WriteMessage(c, ErrFailedToCreateRecord, http.StatusInternalServerError)
}
item, err := s.repo.Sources.GetBySourceAndName(c.Request().Context(), domain.SourceCollectorReddit, param.Name)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error()) s.WriteError(c, err, http.StatusInternalServerError)
} }
return c.JSON(http.StatusOK, bJson) var dto []domain.SourceDto
dto = append(dto, services.SourceToDto(item))
resp.Payload = dto
return c.JSON(http.StatusOK, resp)
} }
// NewYoutubeSource // NewYoutubeSource
@ -362,6 +332,57 @@ func (s *Handler) newTwitchSource(c echo.Context) error {
return c.JSON(http.StatusOK, bJson) return c.JSON(http.StatusOK, bJson)
} }
// NewRssSource
// @Summary Creates a new rss source to monitor.
// @Param name query string true "Site Name"
// @Param url query string true "RSS Url"
// @Tags Source
// @Router /sources/new/rss [post]
// @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 400 {object} domain.BaseResponse
// @Failure 500 {object} domain.BaseResponse
func (s *Handler) newRssSource(c echo.Context) error {
resp := domain.SourcesResponse{
BaseResponse: domain.BaseResponse{
Message: ResponseMessageSuccess,
},
}
var param domain.NewSourceParamRequest
err := c.Bind(&param)
if err != nil {
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
Message: err.Error(),
})
}
if param.Url == "" {
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
Message: "Url is missing a value",
})
}
tags := fmt.Sprintf("rss, %v, %s", param.Name, param.Tags)
rows, err := s.repo.Sources.Create(c.Request().Context(), domain.SourceCollectorRss, param.Name, param.Url, tags, true)
if err != nil {
s.WriteError(c, err, http.StatusInternalServerError)
}
if rows != 1 {
s.WriteMessage(c, ErrFailedToCreateRecord, http.StatusInternalServerError)
}
item, err := s.repo.Sources.GetBySourceAndName(c.Request().Context(), domain.SourceCollectorRss, param.Name)
if err != nil {
s.WriteError(c, err, http.StatusInternalServerError)
}
var dto []domain.SourceDto
dto = append(dto, services.SourceToDto(item))
resp.Payload = dto
return c.JSON(http.StatusOK, resp)
}
// DeleteSource // DeleteSource
// @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"
@ -409,46 +430,44 @@ func (s *Handler) deleteSources(c echo.Context) error {
// DisableSource // DisableSource
// @Summary Disables a source from processing. // @Summary Disables a source from processing.
// @Param id path string true "id" // @Param id path int true "id"
// @Tags Source // @Tags Source
// @Router /sources/{id}/disable [post] // @Router /sources/{id}/disable [post]
// @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 400 {object} domain.BaseResponse
// @Failure 500 {object} domain.BaseResponse
func (s *Handler) disableSource(c echo.Context) error { func (s *Handler) disableSource(c echo.Context) error {
id := c.Param("ID") resp := domain.SourcesResponse {
uuid, err := uuid.Parse(id) BaseResponse: domain.BaseResponse{
Message: ResponseMessageSuccess,
},
}
id, err := strconv.Atoi(c.Param("ID"))
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, domain.BaseResponse{ s.WriteError(c, err, http.StatusBadRequest)
Message: err.Error(),
})
} }
// Check to make sure we can find the record // Check to make sure we can find the record
_, err = s.Db.GetSourceByID(c.Request().Context(), uuid) _, err = s.repo.Sources.GetById(c.Request().Context(), int64(id))
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusBadRequest)
Message: err.Error(),
})
} }
err = s.Db.DisableSource(context.Background(), uuid) _, err = s.repo.Sources.Disable(c.Request().Context(), int64(id))
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusInternalServerError)
Message: err.Error(),
})
} }
p := ApiStatusModel{ item, err := s.repo.Sources.GetById(c.Request().Context(), int64(id))
Message: "OK",
StatusCode: http.StatusOK,
}
b, err := json.Marshal(p)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusInternalServerError)
Message: err.Error(),
})
} }
return c.JSON(http.StatusOK, b) var dto []domain.SourceDto
dto = append(dto, services.SourceToDto(item))
resp.Payload = dto
return c.JSON(http.StatusOK, resp)
} }
// EnableSource // EnableSource
@ -456,39 +475,39 @@ func (s *Handler) disableSource(c echo.Context) error {
// @Param id path string true "id" // @Param id path string true "id"
// @Tags Source // @Tags Source
// @Router /sources/{id}/enable [post] // @Router /sources/{id}/enable [post]
// @Success 200 {object} domain.SourcesResponse "ok"
// @Failure 400 {object} domain.BaseResponse
// @Failure 500 {object} domain.BaseResponse
func (s *Handler) enableSource(c echo.Context) error { func (s *Handler) enableSource(c echo.Context) error {
id := c.Param("ID") resp := domain.SourcesResponse {
uuid, err := uuid.Parse(id) BaseResponse: domain.BaseResponse{
Message: ResponseMessageSuccess,
},
}
id, err := strconv.Atoi(c.Param("ID"))
if err != nil { if err != nil {
return c.JSON(http.StatusBadRequest, err.Error()) s.WriteError(c, err, http.StatusBadRequest)
} }
// Check to make sure we can find the record // Check to make sure we can find the record
_, err = s.Db.GetSourceByID(c.Request().Context(), uuid) _, err = s.repo.Sources.GetById(c.Request().Context(), int64(id))
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusBadRequest)
Message: err.Error(),
})
} }
err = s.Db.EnableSource(c.Request().Context(), uuid) _, err = s.repo.Sources.Enable(c.Request().Context(), int64(id))
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusInternalServerError)
Message: err.Error(),
})
} }
p := ApiStatusModel{ item, err := s.repo.Sources.GetById(c.Request().Context(), int64(id))
Message: "OK",
StatusCode: http.StatusOK,
}
b, err := json.Marshal(p)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{ s.WriteError(c, err, http.StatusInternalServerError)
Message: err.Error(),
})
} }
return c.JSON(http.StatusOK, b) var dto []domain.SourceDto
dto = append(dto, services.SourceToDto(item))
resp.Payload = dto
return c.JSON(http.StatusOK, resp)
} }

View File

@ -14,6 +14,7 @@ type Sources interface {
GetById(ctx context.Context, id int64) (domain.SourceEntity, error) GetById(ctx context.Context, id int64) (domain.SourceEntity, error)
GetByDisplayName(ctx context.Context, displayName string) (domain.SourceEntity, error) GetByDisplayName(ctx context.Context, displayName string) (domain.SourceEntity, error)
GetBySource(ctx context.Context, source string) (domain.SourceEntity, error) GetBySource(ctx context.Context, source string) (domain.SourceEntity, error)
GetBySourceAndName(ctx context.Context, source, name string) (domain.SourceEntity, error)
List(ctx context.Context, page, limit int) ([]domain.SourceEntity, error) List(ctx context.Context, page, limit int) ([]domain.SourceEntity, error)
ListBySource(ctx context.Context, page, limit int, source string) ([]domain.SourceEntity, error) ListBySource(ctx context.Context, page, limit int, source string) ([]domain.SourceEntity, error)
Enable(ctx context.Context, id int64) (int64, error) Enable(ctx context.Context, id int64) (int64, error)
@ -115,6 +116,29 @@ func (r sourceRepository) GetBySource(ctx context.Context, source string) (domai
return data[0], nil return data[0], nil
} }
func (r sourceRepository) GetBySourceAndName(ctx context.Context, source, name string) (domain.SourceEntity, error) {
b := sqlbuilder.NewSelectBuilder()
b.Select("*")
b.From("Sources").Where(
b.Equal("Source", source),
b.Equal("Name", name),
)
b.Limit(1)
query, args := b.Build()
rows, err := r.conn.QueryContext(ctx, query, args...)
if err != nil {
return domain.SourceEntity{}, err
}
data, err := r.processRows(rows)
if len(data) == 0 {
return domain.SourceEntity{}, err
}
return data[0], nil
}
func (r sourceRepository) List(ctx context.Context, page, limit int) ([]domain.SourceEntity, error) { func (r sourceRepository) List(ctx context.Context, page, limit int) ([]domain.SourceEntity, error) {
builder := sqlbuilder.NewSelectBuilder() builder := sqlbuilder.NewSelectBuilder()
builder.Select("*") builder.Select("*")