Compare commits
No commits in common. "2b6ab134d9583d76a72e066d74f9f85661aee3d2" and "72277446217471758169754dffac4d53734dbd21" have entirely different histories.
2b6ab134d9
...
7227744621
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.22 as build
|
FROM golang:1.18.4 as build
|
||||||
|
|
||||||
COPY . /app
|
COPY . /app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
@ -3,26 +3,33 @@ package domain
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type ArticleDto struct {
|
type ArticleDto struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
SourceID int64 `json:"sourceId"`
|
SourceID int64 `json:"sourceId"`
|
||||||
Tags string `json:"tags"`
|
Tags string `json:"tags"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
PubDate time.Time `json:"pubDate"`
|
PubDate time.Time `json:"pubDate"`
|
||||||
IsVideo bool `json:"isVideo"`
|
Video string `json:"video"`
|
||||||
Thumbnail string `json:"thumbnail"`
|
VideoHeight uint16 `json:"videoHeight"`
|
||||||
Description string `json:"description"`
|
VideoWidth uint16 `json:"videoWidth"`
|
||||||
AuthorName string `json:"authorName"`
|
Thumbnail string `json:"thumbnail"`
|
||||||
AuthorImageUrl string `json:"authorImage"`
|
Description string `json:"description"`
|
||||||
|
AuthorName string `json:"authorName"`
|
||||||
|
AuthorImage string `json:"authorImage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiscordQueueDto struct {
|
type DiscordQueueDto struct {
|
||||||
|
//CreatedAt time.Time `json:"createdAt"`
|
||||||
|
//UpdatedAt time.Time `json:"updatedAt"`
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
ArticleId int64 `json:"articleId"`
|
ArticleId int64 `json:"articleId"`
|
||||||
SourceId int64 `json:"sourceId"`
|
SourceId int64 `json:"sourceId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiscordWebHookDto struct {
|
type DiscordWebHookDto struct {
|
||||||
|
//CreatedAt time.Time `json:"CreatedAt"`
|
||||||
|
//UpdatedAt time.Time `json:"UpdatedAt"`
|
||||||
|
//DeletedAt time.Time `json:"DeletedAt"`
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
@ -33,12 +40,18 @@ type DiscordWebHookDto struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IconDto struct {
|
type IconDto struct {
|
||||||
|
//CreatedAt time.Time `json:"CreatedAt"`
|
||||||
|
//UpdatedAt time.Time `json:"UpdatedAt"`
|
||||||
|
//DeletedAt time.Time `json:"DeletedAt"`
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
FileName string `json:"fileName"`
|
FileName string `json:"fileName"`
|
||||||
Site string `json:"site"`
|
Site string `json:"site"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingDto struct {
|
type SettingDto struct {
|
||||||
|
//CreatedAt time.Time `json:"CreatedAt"`
|
||||||
|
//UpdatedAt time.Time `json:"UpdatedAt"`
|
||||||
|
//DeletedAt time.Time `json:"DeletedAt"`
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
@ -46,6 +59,9 @@ type SettingDto struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SubscriptionDto struct {
|
type SubscriptionDto struct {
|
||||||
|
//CreatedAt time.Time `json:"CreatedAt"`
|
||||||
|
//UpdatedAt time.Time `json:"UpdatedAt"`
|
||||||
|
//DeletedAt time.Time `json:"DeletedAt"`
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
SourceID int64 `json:"sourceId"`
|
SourceID int64 `json:"sourceId"`
|
||||||
SourceType string `json:"sourceType"`
|
SourceType string `json:"sourceType"`
|
||||||
@ -55,10 +71,16 @@ type SubscriptionDto struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SourceDto struct {
|
type SourceDto struct {
|
||||||
ID int64 `json:"id"`
|
//CreatedAt time.Time `json:"CreatedAt"`
|
||||||
Source string `json:"source"`
|
//UpdatedAt time.Time `json:"UpdatedAt"`
|
||||||
DisplayName string `json:"name"`
|
//DeletedAt time.Time `json:"DeletedAt"`
|
||||||
Url string `json:"url"`
|
ID int64 `json:"id"`
|
||||||
Tags string `json:"tags"`
|
Site string `json:"site"`
|
||||||
Enabled bool `json:"enabled"`
|
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"`
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,5 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
|
type ErrorResponse struct {
|
||||||
type BaseResponse struct {
|
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArticleResponse struct {
|
|
||||||
BaseResponse
|
|
||||||
Payload []ArticleDto `json:"payload"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ArticleAndSourceModel struct {
|
|
||||||
Article ArticleDto `json:"article"`
|
|
||||||
Source SourceDto `json:"source"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ArticleDetailResponse struct {
|
|
||||||
BaseResponse
|
|
||||||
Payload ArticleAndSourceModel `json:"payload"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DiscordWebhookResponse struct {
|
|
||||||
BaseResponse
|
|
||||||
Payload []DiscordWebHookDto `json:"payload"`
|
|
||||||
}
|
|
@ -4,148 +4,186 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"git.jamestombleson.com/jtom38/newsbot-api/internal/domain"
|
"git.jamestombleson.com/jtom38/newsbot-api/internal/domain/models"
|
||||||
"git.jamestombleson.com/jtom38/newsbot-api/internal/services"
|
"github.com/google/uuid"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//func (s *Handler) 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.ListArticlesBySourceId)
|
||||||
|
//
|
||||||
|
// return r
|
||||||
|
//}
|
||||||
|
|
||||||
|
type ArticlesListResults struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload []models.ArticleDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticleGetResults struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.ArticleDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticleDetailsResult struct {
|
||||||
|
ApiStatusModel
|
||||||
|
Payload models.ArticleDetailsDto `json:"payload"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListArticles
|
// ListArticles
|
||||||
// @Summary Lists the top 25 records ordering from newest to oldest.
|
// @Summary Lists the top 25 records ordering from newest to oldest.
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Param page query string false "page number"
|
// @Param page query string false "page number"
|
||||||
// @Tags Articles
|
// @Tags Articles
|
||||||
// @Router /articles [get]
|
// @Router /articles [get]
|
||||||
// @Success 200 {object} domain.ArticleResponse
|
// @Success 200 {object} ArticlesListResults "OK"
|
||||||
// @Failure 400 {object} domain.BaseResponse
|
|
||||||
// @Failure 500 {object} domain.BaseResponse
|
|
||||||
func (s *Handler) listArticles(c echo.Context) error {
|
func (s *Handler) listArticles(c echo.Context) error {
|
||||||
resp := domain.ArticleResponse{
|
p := ArticlesListResults{
|
||||||
BaseResponse: domain.BaseResponse{
|
ApiStatusModel: ApiStatusModel{
|
||||||
Message: ResponseMessageSuccess,
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
page, err := strconv.Atoi(c.QueryParam("page"))
|
queryPage := c.QueryParam("page")
|
||||||
if err != nil {
|
|
||||||
page = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := s.repo.Articles.ListByPage(c.Request().Context(), page, 25)
|
// if a page number was sent, process it
|
||||||
if err != nil {
|
if len(queryPage) >= 1 {
|
||||||
s.WriteError(c, err, http.StatusInternalServerError)
|
page, err := strconv.Atoi(queryPage)
|
||||||
}
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
|
||||||
resp.Payload = services.ArticlesToDto(res)
|
res, err := s.dto.ListArticles(c.Request().Context(), 25, page)
|
||||||
return c.JSON(http.StatusOK, resp)
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
p.Payload = res
|
||||||
|
return c.JSON(http.StatusOK, p)
|
||||||
|
} else {
|
||||||
|
res, err := s.dto.ListArticles(c.Request().Context(), 25, 0)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
p.Payload = res
|
||||||
|
return c.JSON(http.StatusOK, p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetArticle
|
// GetArticle
|
||||||
// @Summary Returns an article based on defined ID.
|
// @Summary Returns an article based on defined ID.
|
||||||
// @Param ID path string true "int"
|
// @Param ID path string true "uuid"
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Articles
|
// @Tags Articles
|
||||||
// @Router /articles/{ID} [get]
|
// @Router /articles/{ID} [get]
|
||||||
// @Success 200 {object} ArticleGetResults "OK"
|
// @Success 200 {object} ArticleGetResults "OK"
|
||||||
// @Failure 400 {object} domain.BaseResponse
|
|
||||||
// @Failure 500 {object} domain.BaseResponse
|
|
||||||
func (s *Handler) getArticle(c echo.Context) error {
|
func (s *Handler) getArticle(c echo.Context) error {
|
||||||
p := domain.ArticleResponse{
|
p := ArticleGetResults{
|
||||||
BaseResponse: domain.BaseResponse{
|
ApiStatusModel: ApiStatusModel{
|
||||||
Message: ResponseMessageSuccess,
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
id := c.Param("ID")
|
id := c.Param("ID")
|
||||||
idNumber, err := strconv.Atoi(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteError(c, err, http.StatusBadRequest)
|
return c.JSON(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
item, err := s.repo.Articles.GetById(c.Request().Context(), int64(idNumber))
|
res, err := s.dto.GetArticle(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, err)
|
return c.JSON(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtos []domain.ArticleDto
|
p.Payload = res
|
||||||
dtos = append(dtos, services.ArticleToDto(item))
|
|
||||||
p.Payload = dtos
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, p)
|
return c.JSON(http.StatusOK, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetArticleDetails
|
// GetArticleDetails
|
||||||
// @Summary Returns an article and source based on defined ID.
|
// @Summary Returns an article and source based on defined ID.
|
||||||
// @Param ID path string true "int"
|
// @Param ID path string true "uuid"
|
||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Articles
|
// @Tags Articles
|
||||||
// @Router /articles/{ID}/details [get]
|
// @Router /articles/{ID}/details [get]
|
||||||
// @Success 200 {object} ArticleDetailsResult "OK"
|
// @Success 200 {object} ArticleDetailsResult "OK"
|
||||||
// @Failure 400 {object} domain.BaseResponse
|
|
||||||
// @Failure 500 {object} domain.BaseResponse
|
|
||||||
func (s *Handler) getArticleDetails(c echo.Context) error {
|
func (s *Handler) getArticleDetails(c echo.Context) error {
|
||||||
p := domain.ArticleDetailResponse{
|
p := ArticleDetailsResult{
|
||||||
BaseResponse: domain.BaseResponse{
|
ApiStatusModel: ApiStatusModel{
|
||||||
Message: ResponseMessageSuccess,
|
Message: "OK",
|
||||||
},
|
StatusCode: http.StatusOK,
|
||||||
Payload: domain.ArticleAndSourceModel{
|
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := strconv.Atoi(c.Param("ID"))
|
id := c.Param("ID")
|
||||||
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteError(c, err, http.StatusBadRequest)
|
return c.JSON(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
article, err := s.repo.Articles.GetById(c.Request().Context(), int64(id))
|
res, err := s.dto.GetArticleDetails(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteError(c, err, http.StatusInternalServerError)
|
return c.JSON(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
source, err := s.repo.Sources.GetById(c.Request().Context(), article.SourceID)
|
p.Payload = res
|
||||||
if err != nil {
|
|
||||||
s.WriteError(c, err, http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Payload.Article = services.ArticleToDto(article)
|
|
||||||
p.Payload.Source = services.SourceToDto(source)
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, p)
|
return c.JSON(http.StatusOK, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO add page support
|
||||||
// ListArticlesBySourceID
|
// ListArticlesBySourceID
|
||||||
// @Summary Finds the articles based on the SourceID provided. Returns the top 25.
|
// @Summary Finds the articles based on the SourceID provided. Returns the top 25.
|
||||||
// @Param id query string true
|
// @Param id query string true "Source ID UUID"
|
||||||
// @Param page query int false "Page to query"
|
// @Param page query int false "Page to query"
|
||||||
// @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"
|
// @Success 200 {object} ArticlesListResults "OK"
|
||||||
// @Failure 400 {object} domain.BaseResponse
|
|
||||||
// @Failure 500 {object} domain.BaseResponse
|
|
||||||
func (s *Handler) ListArticlesBySourceId(c echo.Context) error {
|
func (s *Handler) ListArticlesBySourceId(c echo.Context) error {
|
||||||
p := domain.ArticleResponse{
|
p := ArticlesListResults{
|
||||||
BaseResponse: domain.BaseResponse{
|
ApiStatusModel: ApiStatusModel{
|
||||||
Message: ResponseMessageSuccess,
|
Message: "OK",
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := strconv.Atoi(c.QueryParam("id"))
|
id := c.QueryParam("id")
|
||||||
|
|
||||||
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteError(c, err, http.StatusBadRequest)
|
return c.JSON(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the page number is missing, default to 0
|
// if a page number was sent, process it
|
||||||
_page, err := strconv.Atoi(c.QueryParam("page"))
|
if len(c.QueryParam("page")) >= 1 {
|
||||||
if err != nil {
|
_page, err := strconv.Atoi(c.QueryParam("page"))
|
||||||
_page = 0
|
if err != nil {
|
||||||
}
|
return c.JSON(http.StatusBadRequest, err)
|
||||||
|
}
|
||||||
|
|
||||||
items, err := s.repo.Articles.ListBySource(c.Request().Context(), _page, 25, id, "")
|
res, err := s.dto.ListNewArticlesBySourceId(c.Request().Context(), uuid, 25, _page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, err)
|
return c.JSON(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Payload = services.ArticlesToDto(items)
|
p.Payload = res
|
||||||
|
} else {
|
||||||
|
res, err := s.dto.ListNewArticlesBySourceId(c.Request().Context(), uuid, 25, 0)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSON(http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Payload = res
|
||||||
|
}
|
||||||
return c.JSON(http.StatusOK, p)
|
return c.JSON(http.StatusOK, p)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,21 +60,21 @@ func (s *Handler) GetDiscordWebHooksById(c echo.Context) error {
|
|||||||
|
|
||||||
_id := c.Param("ID")
|
_id := c.Param("ID")
|
||||||
if _id == "" {
|
if _id == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: ErrIdValueMissing,
|
Message: ErrIdValueMissing,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, err := uuid.Parse(_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.ErrorResponse{
|
||||||
Message: ErrUnableToParseId,
|
Message: ErrUnableToParseId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.dto.GetDiscordWebhook(c.Request().Context(), uuid)
|
res, err := s.dto.GetDiscordWebhook(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: ErrNoRecordFound,
|
Message: ErrNoRecordFound,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -100,21 +100,21 @@ func (s *Handler) GetDiscordWebHooksByServerAndChannel(c echo.Context) error {
|
|||||||
|
|
||||||
_server := c.QueryParam("server")
|
_server := c.QueryParam("server")
|
||||||
if _server == "" {
|
if _server == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: ErrIdValueMissing,
|
Message: ErrIdValueMissing,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_channel := c.QueryParam("channel")
|
_channel := c.QueryParam("channel")
|
||||||
if _channel == "" {
|
if _channel == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: fmt.Sprintf("%s channel", ErrParameterMissing),
|
Message: fmt.Sprintf("%s channel", ErrParameterMissing),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.dto.GetDiscordWebHookByServerAndChannel(c.Request().Context(), _server, _channel)
|
res, err := s.dto.GetDiscordWebHookByServerAndChannel(c.Request().Context(), _server, _channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -136,22 +136,22 @@ func (s *Handler) NewDiscordWebHook(c echo.Context) error {
|
|||||||
_channel := c.QueryParam("channel")
|
_channel := c.QueryParam("channel")
|
||||||
|
|
||||||
if _url == "" {
|
if _url == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "url is missing a value",
|
Message: "url is missing a value",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if !strings.Contains(_url, "discord.com/api/webhooks") {
|
if !strings.Contains(_url, "discord.com/api/webhooks") {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "invalid url",
|
Message: "invalid url",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if _server == "" {
|
if _server == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "server is missing",
|
Message: "server is missing",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if _channel == "" {
|
if _channel == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "channel is missing",
|
Message: "channel is missing",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ func (s *Handler) disableDiscordWebHook(c echo.Context) error {
|
|||||||
id := c.Param("ID")
|
id := c.Param("ID")
|
||||||
uuid, err := uuid.Parse(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.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ func (s *Handler) disableDiscordWebHook(c echo.Context) error {
|
|||||||
|
|
||||||
err = s.Db.DisableDiscordWebHook(c.Request().Context(), uuid)
|
err = s.Db.DisableDiscordWebHook(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -205,7 +205,7 @@ func (s *Handler) enableDiscordWebHook(c echo.Context) error {
|
|||||||
id := c.Param("ID")
|
id := c.Param("ID")
|
||||||
uuid, err := uuid.Parse(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.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -15,24 +15,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
Router *echo.Echo
|
Router *echo.Echo
|
||||||
Db *database.Queries
|
Db *database.Queries
|
||||||
dto *dto.DtoClient
|
dto *dto.DtoClient
|
||||||
config services.Configs
|
config services.Configs
|
||||||
repo services.RepositoryService
|
sqlConnection *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HeaderContentType = "Content-Type"
|
HeaderContentType = "Content-Type"
|
||||||
|
|
||||||
//ApplicationJson = "application/json"
|
ApplicationJson = "application/json"
|
||||||
|
|
||||||
ErrParameterIdMissing = "The requested parameter ID was not found."
|
ErrParameterIdMissing = "The requested parameter ID was not found."
|
||||||
ErrParameterMissing = "The requested parameter was found found:"
|
ErrParameterMissing = "The requested parameter was found found:"
|
||||||
ErrUnableToParseId = "Unable to parse the requested ID."
|
ErrUnableToParseId = "Unable to parse the requested ID."
|
||||||
ErrRecordMissing = "The requested record was not found"
|
ErrRecordMissing = "The requested record was not found"
|
||||||
|
|
||||||
ResponseMessageSuccess = "Success"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -44,12 +42,18 @@ var (
|
|||||||
|
|
||||||
func NewServer(ctx context.Context, db *database.Queries, configs services.Configs, conn *sql.DB) *Handler {
|
func NewServer(ctx context.Context, db *database.Queries, configs services.Configs, conn *sql.DB) *Handler {
|
||||||
s := &Handler{
|
s := &Handler{
|
||||||
Db: db,
|
Db: db,
|
||||||
dto: dto.NewDtoClient(db),
|
dto: dto.NewDtoClient(db),
|
||||||
config: configs,
|
config: configs,
|
||||||
repo: services.NewRepositoryService(conn),
|
sqlConnection: conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db, err := openDatabase(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
s.Db = db
|
||||||
|
|
||||||
router := echo.New()
|
router := echo.New()
|
||||||
router.GET("/swagger/*", swagger.WrapHandler)
|
router.GET("/swagger/*", swagger.WrapHandler)
|
||||||
|
|
||||||
@ -69,11 +73,11 @@ func NewServer(ctx context.Context, db *database.Queries, configs services.Confi
|
|||||||
dwh.POST("/:ID/disable", s.disableDiscordWebHook)
|
dwh.POST("/:ID/disable", s.disableDiscordWebHook)
|
||||||
dwh.POST("/:ID/enable", s.enableDiscordWebHook)
|
dwh.POST("/:ID/enable", s.enableDiscordWebHook)
|
||||||
|
|
||||||
//queue := v1.Group("/queue")
|
queue := v1.Group("/queue")
|
||||||
//queue.GET("/discord/webhooks", s.ListDiscordWebhookQueue) // TODO this needs to be reworked
|
queue.GET("/discord/webhooks", s.ListDiscordWebhookQueue) // TODO this needs to be reworked
|
||||||
|
|
||||||
//settings := v1.Group("/settings")
|
settings := v1.Group("/settings")
|
||||||
//settings.GET("/", s.getSettings)
|
settings.GET("/", s.getSettings)
|
||||||
|
|
||||||
sources := v1.Group("/sources")
|
sources := v1.Group("/sources")
|
||||||
sources.GET("/", s.listSources)
|
sources.GET("/", s.listSources)
|
||||||
@ -99,6 +103,28 @@ func NewServer(ctx context.Context, db *database.Queries, configs services.Confi
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func openDatabase(ctx context.Context) (*database.Queries, error) {
|
||||||
|
_env := services.NewConfig()
|
||||||
|
connString := _env.GetConfig(services.Sql_Connection_String)
|
||||||
|
db, err := sql.Open("postgres", connString)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
queries := database.New(db)
|
||||||
|
return queries, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Handler) MountRoutes() {
|
||||||
|
//s.Router.Get("/swagger/*", httpSwagger.Handler(
|
||||||
|
// httpSwagger.URL("doc.json"), //The url pointing to API definition
|
||||||
|
//))
|
||||||
|
//s.Router.Get("/api/settings", s.getSettings)
|
||||||
|
|
||||||
|
//s.Router.Mount("/api/sources", s.GetSourcesRouter())
|
||||||
|
//s.Router.Mount("/api/subscriptions", s.GetSubscriptionsRouter())
|
||||||
|
}
|
||||||
|
|
||||||
type ApiStatusModel struct {
|
type ApiStatusModel struct {
|
||||||
StatusCode int `json:"status"`
|
StatusCode int `json:"status"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
@ -108,14 +134,8 @@ type ApiError struct {
|
|||||||
*ApiStatusModel
|
*ApiStatusModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Handler) WriteError(c echo.Context, errMessage error, HttpStatusCode int) error {
|
func (s *Handler) WriteError(c echo.Context, errMessage string, HttpStatusCode int) error {
|
||||||
return c.JSON(HttpStatusCode, domain.BaseResponse{
|
return c.JSON(HttpStatusCode, domain.ErrorResponse{
|
||||||
Message: errMessage.Error(),
|
Message: errMessage,
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Handler) WriteMessage(c echo.Context, msg string, HttpStatusCode int) error {
|
|
||||||
return c.JSON(HttpStatusCode, domain.BaseResponse{
|
|
||||||
Message: msg,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func (s *Handler) ListDiscordWebhookQueue(c echo.Context) error {
|
|||||||
// Get the raw resp from sql
|
// Get the raw resp from sql
|
||||||
res, err := s.dto.ListDiscordWebhookQueueDetails(c.Request().Context(), 50)
|
res, err := s.dto.ListDiscordWebhookQueueDetails(c.Request().Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func (s *Handler) getSettings(c echo.Context) error {
|
|||||||
|
|
||||||
uuid, err := uuid.Parse(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.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,19 @@ import (
|
|||||||
"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"
|
||||||
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (s *Handler) GetSourcesRouter() http.Handler {
|
||||||
|
r := chi.NewRouter()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
type ListSources struct {
|
type ListSources struct {
|
||||||
ApiStatusModel
|
ApiStatusModel
|
||||||
Payload []models.SourceDto `json:"payload"`
|
Payload []models.SourceDto `json:"payload"`
|
||||||
@ -29,8 +38,8 @@ type GetSource struct {
|
|||||||
// @Produce application/json
|
// @Produce application/json
|
||||||
// @Tags Source
|
// @Tags Source
|
||||||
// @Router /sources [get]
|
// @Router /sources [get]
|
||||||
// @Success 200 {object} ListSources "ok"
|
// @Success 200 {object} ListSources "ok"
|
||||||
// @Failure 400 {object} domain.BaseResponse "Unable to reach SQL or Data problems"
|
// @Failure 400 {object} ApiError "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?
|
//TODO Add top?
|
||||||
/*
|
/*
|
||||||
@ -52,7 +61,9 @@ func (s *Handler) listSources(c echo.Context) error {
|
|||||||
// Default way of showing all sources
|
// Default way of showing all sources
|
||||||
items, err := s.dto.ListSources(c.Request().Context(), 50)
|
items, err := s.dto.ListSources(c.Request().Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteError(c, err, http.StatusInternalServerError)
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Payload = items
|
p.Payload = items
|
||||||
@ -91,7 +102,7 @@ func (s *Handler) listSourcesBySource(c echo.Context) error {
|
|||||||
// Shows the list by Sources.source
|
// Shows the list by Sources.source
|
||||||
res, err := s.dto.ListSourcesBySource(c.Request().Context(), source)
|
res, err := s.dto.ListSourcesBySource(c.Request().Context(), source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -121,14 +132,14 @@ func (s *Handler) getSources(c echo.Context) error {
|
|||||||
id := c.Param("ID")
|
id := c.Param("ID")
|
||||||
uuid, err := uuid.Parse(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.ErrorResponse{
|
||||||
Message: ErrUnableToParseId,
|
Message: ErrUnableToParseId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.dto.GetSourceById(c.Request().Context(), uuid)
|
res, err := s.dto.GetSourceById(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: ErrNoRecordFound,
|
Message: ErrNoRecordFound,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -159,7 +170,7 @@ func (s *Handler) GetSourceBySourceAndName(c echo.Context) error {
|
|||||||
var param domain.GetSourceBySourceAndNameParamRequest
|
var param domain.GetSourceBySourceAndNameParamRequest
|
||||||
err := c.Bind(¶m)
|
err := c.Bind(¶m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -195,7 +206,7 @@ func (s *Handler) newRedditSource(c echo.Context) error {
|
|||||||
var param domain.NewSourceParamRequest
|
var param domain.NewSourceParamRequest
|
||||||
err := c.Bind(¶m)
|
err := c.Bind(¶m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -205,12 +216,12 @@ func (s *Handler) newRedditSource(c echo.Context) error {
|
|||||||
//_tags := query["tags"][0]
|
//_tags := query["tags"][0]
|
||||||
|
|
||||||
if param.Url == "" {
|
if param.Url == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "Url is missing a value",
|
Message: "Url is missing a value",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if !strings.Contains(param.Url, "reddit.com") {
|
if !strings.Contains(param.Url, "reddit.com") {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "Invalid URL given",
|
Message: "Invalid URL given",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -237,7 +248,7 @@ func (s *Handler) newRedditSource(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
err = s.Db.CreateSource(c.Request().Context(), params)
|
err = s.Db.CreateSource(c.Request().Context(), params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -261,7 +272,7 @@ func (s *Handler) newYoutubeSource(c echo.Context) error {
|
|||||||
var param domain.NewSourceParamRequest
|
var param domain.NewSourceParamRequest
|
||||||
err := c.Bind(¶m)
|
err := c.Bind(¶m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -272,12 +283,12 @@ func (s *Handler) newYoutubeSource(c echo.Context) error {
|
|||||||
////_tags := query["tags"][0]
|
////_tags := query["tags"][0]
|
||||||
|
|
||||||
if param.Url == "" {
|
if param.Url == "" {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "url is missing a value",
|
Message: "url is missing a value",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if !strings.Contains(param.Url, "youtube.com") {
|
if !strings.Contains(param.Url, "youtube.com") {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: "Invalid URL",
|
Message: "Invalid URL",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -307,7 +318,7 @@ func (s *Handler) newYoutubeSource(c echo.Context) error {
|
|||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -324,7 +335,7 @@ func (s *Handler) newTwitchSource(c echo.Context) error {
|
|||||||
var param domain.NewSourceParamRequest
|
var param domain.NewSourceParamRequest
|
||||||
err := c.Bind(¶m)
|
err := c.Bind(¶m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusBadRequest, domain.BaseResponse{
|
return c.JSON(http.StatusBadRequest, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -347,14 +358,14 @@ func (s *Handler) newTwitchSource(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
err = s.Db.CreateSource(c.Request().Context(), params)
|
err = s.Db.CreateSource(c.Request().Context(), params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -371,7 +382,7 @@ func (s *Handler) deleteSources(c echo.Context) error {
|
|||||||
id := c.Param("ID")
|
id := c.Param("ID")
|
||||||
uuid, err := uuid.Parse(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.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -379,7 +390,7 @@ func (s *Handler) deleteSources(c echo.Context) 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.Db.GetSourceByID(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -387,7 +398,7 @@ func (s *Handler) deleteSources(c echo.Context) error {
|
|||||||
// Delete the record
|
// Delete the record
|
||||||
err = s.Db.DeleteSource(c.Request().Context(), uuid)
|
err = s.Db.DeleteSource(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -399,7 +410,7 @@ func (s *Handler) deleteSources(c echo.Context) error {
|
|||||||
|
|
||||||
b, err := json.Marshal(p)
|
b, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -416,7 +427,7 @@ func (s *Handler) disableSource(c echo.Context) error {
|
|||||||
id := c.Param("ID")
|
id := c.Param("ID")
|
||||||
uuid, err := uuid.Parse(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.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -424,14 +435,14 @@ func (s *Handler) disableSource(c echo.Context) 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.Db.GetSourceByID(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.DisableSource(context.Background(), uuid)
|
err = s.Db.DisableSource(context.Background(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -443,7 +454,7 @@ func (s *Handler) disableSource(c echo.Context) error {
|
|||||||
|
|
||||||
b, err := json.Marshal(p)
|
b, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -466,14 +477,14 @@ func (s *Handler) enableSource(c echo.Context) 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.Db.GetSourceByID(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.EnableSource(c.Request().Context(), uuid)
|
err = s.Db.EnableSource(c.Request().Context(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -485,7 +496,7 @@ func (s *Handler) enableSource(c echo.Context) error {
|
|||||||
|
|
||||||
b, err := json.Marshal(p)
|
b, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(http.StatusInternalServerError, domain.BaseResponse{
|
return c.JSON(http.StatusInternalServerError, domain.ErrorResponse{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package v1
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.jamestombleson.com/jtom38/newsbot-api/internal/database"
|
"git.jamestombleson.com/jtom38/newsbot-api/internal/database"
|
||||||
@ -45,7 +44,7 @@ func (s *Handler) ListSubscriptions(c echo.Context) error {
|
|||||||
|
|
||||||
res, err := s.dto.ListSubscriptions(c.Request().Context(), 50)
|
res, err := s.dto.ListSubscriptions(c.Request().Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusBadRequest)
|
return s.WriteError(c, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
payload.Payload = res
|
payload.Payload = res
|
||||||
@ -68,7 +67,7 @@ func (s *Handler) ListSubscriptionDetails(c echo.Context) error {
|
|||||||
|
|
||||||
res, err := s.dto.ListSubscriptionDetails(c.Request().Context(), 50)
|
res, err := s.dto.ListSubscriptionDetails(c.Request().Context(), 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusInternalServerError)
|
return s.WriteError(c, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
payload.Payload = res
|
payload.Payload = res
|
||||||
@ -94,18 +93,18 @@ func (s *Handler) GetSubscriptionsByDiscordId(c echo.Context) error {
|
|||||||
|
|
||||||
id := c.QueryParam("id")
|
id := c.QueryParam("id")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return s.WriteError(c, errors.New(ErrIdValueMissing), http.StatusBadRequest)
|
return s.WriteError(c, ErrIdValueMissing, http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, err := uuid.Parse(id)
|
uuid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, errors.New(ErrValueNotUuid), http.StatusBadRequest)
|
return s.WriteError(c, ErrValueNotUuid, http.StatusBadRequest)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.dto.ListSubscriptionsByDiscordWebhookId(context.Background(), uuid)
|
res, err := s.dto.ListSubscriptionsByDiscordWebhookId(context.Background(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusNoContent)
|
return s.WriteError(c, err.Error(), http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Payload = res
|
p.Payload = res
|
||||||
@ -129,17 +128,17 @@ func (s *Handler) GetSubscriptionsBySourceId(c echo.Context) error {
|
|||||||
|
|
||||||
_id := c.QueryParam("id")
|
_id := c.QueryParam("id")
|
||||||
if _id == "" {
|
if _id == "" {
|
||||||
return s.WriteError(c, errors.New(ErrIdValueMissing), http.StatusBadRequest)
|
return s.WriteError(c, ErrIdValueMissing, http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
uuid, err := uuid.Parse(_id)
|
uuid, err := uuid.Parse(_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusBadRequest)
|
return s.WriteError(c, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := s.dto.ListSubscriptionsBySourceId(context.Background(), uuid)
|
res, err := s.dto.ListSubscriptionsBySourceId(context.Background(), uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusNoContent)
|
return s.WriteError(c, err.Error(), http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Payload = res
|
p.Payload = res
|
||||||
@ -159,20 +158,20 @@ func (s *Handler) newDiscordWebHookSubscription(c echo.Context) error {
|
|||||||
|
|
||||||
// Check to make we didn't get a null
|
// Check to make we didn't get a null
|
||||||
if discordWebHookId == "" {
|
if discordWebHookId == "" {
|
||||||
return s.WriteError(c, errors.New("invalid discordWebHooksId given"), http.StatusBadRequest)
|
return s.WriteError(c, "invalid discordWebHooksId given", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
if sourceId == "" {
|
if sourceId == "" {
|
||||||
return s.WriteError(c, errors.New("invalid sourceID given"), http.StatusBadRequest)
|
return s.WriteError(c, "invalid sourceID given", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate 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 {
|
||||||
return s.WriteError(c, err, http.StatusBadRequest)
|
return s.WriteError(c, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
uSource, err := uuid.Parse(sourceId)
|
uSource, err := uuid.Parse(sourceId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusBadRequest)
|
return s.WriteError(c, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the sub already exists
|
// Check if the sub already exists
|
||||||
@ -181,7 +180,7 @@ func (s *Handler) newDiscordWebHookSubscription(c echo.Context) error {
|
|||||||
Sourceid: uSource,
|
Sourceid: uSource,
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return s.WriteError(c, errors.New("a subscription already exists between these two entities"), http.StatusBadRequest)
|
return s.WriteError(c, "a subscription already exists between these two entities", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does not exist, so make it.
|
// Does not exist, so make it.
|
||||||
@ -192,12 +191,12 @@ func (s *Handler) newDiscordWebHookSubscription(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
err = s.Db.CreateSubscription(context.Background(), params)
|
err = s.Db.CreateSubscription(context.Background(), params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusInternalServerError)
|
return s.WriteError(c, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
bJson, err := json.Marshal(¶ms)
|
bJson, err := json.Marshal(¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusInternalServerError)
|
return s.WriteError(c, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, bJson)
|
return c.JSON(http.StatusOK, bJson)
|
||||||
@ -213,17 +212,17 @@ func (s *Handler) DeleteDiscordWebHookSubscription(c echo.Context) error {
|
|||||||
|
|
||||||
id := c.QueryParam("id")
|
id := c.QueryParam("id")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return s.WriteError(c, errors.New(ErrMissingSubscriptionID), http.StatusBadRequest)
|
return s.WriteError(c, ErrMissingSubscriptionID, http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, err := uuid.Parse(id)
|
uid, err := uuid.Parse(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusBadRequest)
|
return s.WriteError(c, err.Error(), http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Db.DeleteSubscription(context.Background(), uid)
|
err = s.Db.DeleteSubscription(context.Background(), uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.WriteError(c, err, http.StatusInternalServerError)
|
return s.WriteError(c, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, nil)
|
return c.JSON(http.StatusOK, nil)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -13,19 +12,9 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ArticleOrderByPublishDateDesc = "pubDate desc"
|
ArticleOrderByPublishDateDesc = "pubDate desc"
|
||||||
ArticleOrderByPublishDateAsc = "pubDate asc"
|
ArticleOrderByPublishDatAsc = "pubDate asc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArticlesRepo interface {
|
|
||||||
GetById(ctx context.Context, id int64) (domain.ArticleEntity, error)
|
|
||||||
GetByUrl(ctx context.Context, url string) (domain.ArticleEntity, error)
|
|
||||||
ListTop(ctx context.Context, limit int) ([]domain.ArticleEntity, error)
|
|
||||||
ListByPage(ctx context.Context, page, limit int) ([]domain.ArticleEntity, error)
|
|
||||||
ListByPublishDate(ctx context.Context, page, limit int, orderBy string) ([]domain.ArticleEntity, error)
|
|
||||||
ListBySource(ctx context.Context, page, limit, sourceId int, orderBy string) ([]domain.ArticleEntity, error)
|
|
||||||
Create(ctx context.Context, sourceId int64, tags, title, url, thumbnailUrl, description, authorName, authorImageUrl string, pubDate time.Time, isVideo bool) (int64, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ArticleRepository struct {
|
type ArticleRepository struct {
|
||||||
conn *sql.DB
|
conn *sql.DB
|
||||||
defaultLimit int
|
defaultLimit int
|
||||||
@ -40,7 +29,7 @@ func NewArticleRepository(conn *sql.DB) ArticleRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) GetById(ctx context.Context, id int64) (domain.ArticleEntity, error) {
|
func (ar ArticleRepository) GetById(id int64) (domain.ArticleEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*")
|
builder.Select("*")
|
||||||
builder.From("articles").Where(
|
builder.From("articles").Where(
|
||||||
@ -49,7 +38,7 @@ func (ar ArticleRepository) GetById(ctx context.Context, id int64) (domain.Artic
|
|||||||
builder.Limit(1)
|
builder.Limit(1)
|
||||||
|
|
||||||
query, args := builder.Build()
|
query, args := builder.Build()
|
||||||
rows, err := ar.conn.QueryContext(ctx, query, args...)
|
rows, err := ar.conn.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.ArticleEntity{}, err
|
return domain.ArticleEntity{}, err
|
||||||
}
|
}
|
||||||
@ -62,7 +51,7 @@ func (ar ArticleRepository) GetById(ctx context.Context, id int64) (domain.Artic
|
|||||||
return data[0], nil
|
return data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) GetByUrl(ctx context.Context, url string) (domain.ArticleEntity, error) {
|
func (ar ArticleRepository) GetByUrl(url string) (domain.ArticleEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*")
|
builder.Select("*")
|
||||||
builder.From("articles").Where(
|
builder.From("articles").Where(
|
||||||
@ -71,7 +60,7 @@ func (ar ArticleRepository) GetByUrl(ctx context.Context, url string) (domain.Ar
|
|||||||
builder.Limit(1)
|
builder.Limit(1)
|
||||||
|
|
||||||
query, args := builder.Build()
|
query, args := builder.Build()
|
||||||
rows, err := ar.conn.QueryContext(ctx, query, args...)
|
rows, err := ar.conn.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.ArticleEntity{}, err
|
return domain.ArticleEntity{}, err
|
||||||
}
|
}
|
||||||
@ -84,14 +73,14 @@ func (ar ArticleRepository) GetByUrl(ctx context.Context, url string) (domain.Ar
|
|||||||
return data[0], nil
|
return data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) ListTop(ctx context.Context, limit int) ([]domain.ArticleEntity, error) {
|
func (ar ArticleRepository) ListTop(limit int) ([]domain.ArticleEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*")
|
builder.Select("*")
|
||||||
builder.From("articles")
|
builder.From("articles")
|
||||||
builder.Limit(limit)
|
builder.Limit(limit)
|
||||||
|
|
||||||
query, args := builder.Build()
|
query, args := builder.Build()
|
||||||
rows, err := ar.conn.QueryContext(ctx, query, args...)
|
rows, err := ar.conn.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []domain.ArticleEntity{}, err
|
return []domain.ArticleEntity{}, err
|
||||||
}
|
}
|
||||||
@ -104,16 +93,16 @@ func (ar ArticleRepository) ListTop(ctx context.Context, limit int) ([]domain.Ar
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) ListByPage(ctx context.Context, page, limit int) ([]domain.ArticleEntity, error) {
|
func (ar ArticleRepository) ListByPage(page, limit int) ([]domain.ArticleEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*")
|
builder.Select("*")
|
||||||
builder.From("articles")
|
builder.From("articles")
|
||||||
builder.OrderBy(ArticleOrderByPublishDateDesc)
|
builder.OrderBy("pubdate desc")
|
||||||
builder.Offset(page * limit)
|
builder.Offset(page * limit)
|
||||||
builder.Limit(limit)
|
builder.Limit(limit)
|
||||||
|
|
||||||
query, args := builder.Build()
|
query, args := builder.Build()
|
||||||
rows, err := ar.conn.QueryContext(ctx, query, args...)
|
rows, err := ar.conn.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []domain.ArticleEntity{}, err
|
return []domain.ArticleEntity{}, err
|
||||||
}
|
}
|
||||||
@ -126,7 +115,7 @@ func (ar ArticleRepository) ListByPage(ctx context.Context, page, limit int) ([]
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) ListByPublishDate(ctx context.Context, page, limit int, orderBy string) ([]domain.ArticleEntity, error) {
|
func (ar ArticleRepository) ListByPublishDate(page, limit int, orderBy string) ([]domain.ArticleEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*")
|
builder.Select("*")
|
||||||
builder.From("articles")
|
builder.From("articles")
|
||||||
@ -137,7 +126,7 @@ func (ar ArticleRepository) ListByPublishDate(ctx context.Context, page, limit i
|
|||||||
builder.Limit(limit)
|
builder.Limit(limit)
|
||||||
|
|
||||||
query, args := builder.Build()
|
query, args := builder.Build()
|
||||||
rows, err := ar.conn.QueryContext(ctx, query, args...)
|
rows, err := ar.conn.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []domain.ArticleEntity{}, err
|
return []domain.ArticleEntity{}, err
|
||||||
}
|
}
|
||||||
@ -149,7 +138,7 @@ func (ar ArticleRepository) ListByPublishDate(ctx context.Context, page, limit i
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) ListBySource(ctx context.Context, page, limit, sourceId int, orderBy string) ([]domain.ArticleEntity, error) {
|
func (ar ArticleRepository) ListBySource(page, limit int, orderBy string) ([]domain.ArticleEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*")
|
builder.Select("*")
|
||||||
builder.From("articles")
|
builder.From("articles")
|
||||||
@ -157,14 +146,11 @@ func (ar ArticleRepository) ListBySource(ctx context.Context, page, limit, sourc
|
|||||||
if orderBy != "" {
|
if orderBy != "" {
|
||||||
builder.OrderBy(orderBy)
|
builder.OrderBy(orderBy)
|
||||||
}
|
}
|
||||||
builder.Where(
|
|
||||||
builder.Equal("SourceId", sourceId),
|
|
||||||
)
|
|
||||||
builder.Offset(50)
|
builder.Offset(50)
|
||||||
builder.Limit(page * limit)
|
builder.Limit(page * limit)
|
||||||
|
|
||||||
query, args := builder.Build()
|
query, args := builder.Build()
|
||||||
rows, err := ar.conn.QueryContext(ctx, query, args...)
|
rows, err := ar.conn.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []domain.ArticleEntity{}, err
|
return []domain.ArticleEntity{}, err
|
||||||
}
|
}
|
||||||
@ -176,7 +162,7 @@ func (ar ArticleRepository) ListBySource(ctx context.Context, page, limit, sourc
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ar ArticleRepository) Create(ctx context.Context, sourceId int64, tags, title, url, thumbnailUrl, description, authorName, authorImageUrl string, pubDate time.Time, isVideo bool) (int64, error) {
|
func (ar ArticleRepository) Create(sourceId int64, tags, title, url, thumbnailUrl, description, authorName, authorImageUrl string, pubDate time.Time, isVideo bool) (int64, error) {
|
||||||
dt := time.Now()
|
dt := time.Now()
|
||||||
queryBuilder := sqlbuilder.NewInsertBuilder()
|
queryBuilder := sqlbuilder.NewInsertBuilder()
|
||||||
queryBuilder.InsertInto("articles")
|
queryBuilder.InsertInto("articles")
|
||||||
@ -184,7 +170,7 @@ func (ar ArticleRepository) Create(ctx context.Context, sourceId int64, tags, ti
|
|||||||
queryBuilder.Values(dt, dt, timeZero, sourceId, tags, title, url, pubDate, isVideo, thumbnailUrl, description, authorName, authorImageUrl)
|
queryBuilder.Values(dt, dt, timeZero, sourceId, tags, title, url, pubDate, isVideo, thumbnailUrl, description, authorName, authorImageUrl)
|
||||||
query, args := queryBuilder.Build()
|
query, args := queryBuilder.Build()
|
||||||
|
|
||||||
_, err := ar.conn.ExecContext(ctx, query, args...)
|
_, err := ar.conn.Exec(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package repository_test
|
package repository_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ func TestCreateArticle(t *testing.T) {
|
|||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
r := repository.NewArticleRepository(db)
|
r := repository.NewArticleRepository(db)
|
||||||
created, err := r.Create(context.Background(), 1, "", "unit test", articleFakeDotCom, "", "testing", "", "", time.Now(), false)
|
created, err := r.Create(1, "", "unit test", articleFakeDotCom, "", "testing", "", "", time.Now(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -49,7 +48,7 @@ func TestArticleByUrl(t *testing.T) {
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
article, err := r.GetByUrl(context.Background(), articleFakeDotCom)
|
article, err := r.GetByUrl(articleFakeDotCom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -74,7 +73,7 @@ func TestPullingMultipleArticlesWithLimit(t *testing.T) {
|
|||||||
insertFakeArticles(r, "u3", 0)
|
insertFakeArticles(r, "u3", 0)
|
||||||
insertFakeArticles(r, "u4", 0)
|
insertFakeArticles(r, "u4", 0)
|
||||||
|
|
||||||
items, err := r.ListTop(context.Background(), 3)
|
items, err := r.ListTop(3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -99,7 +98,7 @@ func TestPullingMultipleArticlesWithPaging(t *testing.T) {
|
|||||||
insertFakeArticles(r, "u3", 0)
|
insertFakeArticles(r, "u3", 0)
|
||||||
insertFakeArticles(r, "u4", 0)
|
insertFakeArticles(r, "u4", 0)
|
||||||
|
|
||||||
items, err := r.ListByPage(context.Background(), 2, 1)
|
items, err := r.ListByPage(2, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -126,7 +125,7 @@ func TestPullingByPublishDate(t *testing.T) {
|
|||||||
insertFakeArticles(r, "u1", -1)
|
insertFakeArticles(r, "u1", -1)
|
||||||
insertFakeArticles(r, "u1", -2)
|
insertFakeArticles(r, "u1", -2)
|
||||||
|
|
||||||
items, err := r.ListByPublishDate(context.Background(), 0, 2, repository.ArticleOrderByPublishDateDesc)
|
items, err := r.ListByPublishDate(0, 2, repository.ArticleOrderByPublishDateDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
@ -148,7 +147,7 @@ func TestPullingByPublishDate(t *testing.T) {
|
|||||||
|
|
||||||
func insertFakeArticles(r repository.ArticleRepository, title string, daysOld int) error {
|
func insertFakeArticles(r repository.ArticleRepository, title string, daysOld int) error {
|
||||||
pubDate := time.Now().AddDate(0,0, daysOld)
|
pubDate := time.Now().AddDate(0,0, daysOld)
|
||||||
_, err := r.Create(context.Background(), 1, "", title, articleFakeDotCom, "", "testing", "", "", pubDate, false)
|
_, err := r.Create(1, "", title, articleFakeDotCom, "", "testing", "", "", pubDate, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -9,19 +9,6 @@ import (
|
|||||||
"github.com/huandu/go-sqlbuilder"
|
"github.com/huandu/go-sqlbuilder"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DiscordWebHookRepo interface{
|
|
||||||
Create(ctx context.Context, url, server, channel string, enabled bool) (int64, error)
|
|
||||||
Enable(ctx context.Context, id int64) (int64, error)
|
|
||||||
Disable(ctx context.Context, id int64) (int64, error)
|
|
||||||
SoftDelete(ctx context.Context, id int64) (int64, error)
|
|
||||||
Restore(ctx context.Context, id int64) (int64, error)
|
|
||||||
Delete(ctx context.Context, id int64) (int64, error)
|
|
||||||
GetById(ctx context.Context, id int64) (domain.DiscordWebHookEntity, error)
|
|
||||||
GetByUrl(ctx context.Context, url string) (domain.DiscordWebHookEntity, error)
|
|
||||||
ListByServerName(ctx context.Context, name string) ([]domain.DiscordWebHookEntity, error)
|
|
||||||
ListByServerAndChannel(ctx context.Context, server, channel string) ([]domain.DiscordWebHookEntity, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type discordWebHookRepository struct {
|
type discordWebHookRepository struct {
|
||||||
conn *sql.DB
|
conn *sql.DB
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ const (
|
|||||||
refreshTokenTableName = "RefreshTokens"
|
refreshTokenTableName = "RefreshTokens"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RefreshToken interface {
|
type RefreshTokenTable interface {
|
||||||
Create(username string, token string) (int64, error)
|
Create(username string, token string) (int64, error)
|
||||||
GetByUsername(name string) (domain.RefreshTokenEntity, error)
|
GetByUsername(name string) (domain.RefreshTokenEntity, error)
|
||||||
DeleteById(id int64) (int64, error)
|
DeleteById(id int64) (int64, error)
|
||||||
|
@ -9,20 +9,6 @@ import (
|
|||||||
"github.com/huandu/go-sqlbuilder"
|
"github.com/huandu/go-sqlbuilder"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Sources interface {
|
|
||||||
Create(ctx context.Context, source, displayName, url, tags string, enabled bool) (int64, error)
|
|
||||||
GetById(ctx context.Context, id int64) (domain.SourceEntity, error)
|
|
||||||
GetByDisplayName(ctx context.Context, displayName string) (domain.SourceEntity, error)
|
|
||||||
GetBySource(ctx context.Context, source string) (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)
|
|
||||||
Enable(ctx context.Context, id int64) (int64, error)
|
|
||||||
Disable(ctx context.Context, id int64) (int64, error)
|
|
||||||
SoftDelete(ctx context.Context, id int64) (int64, error)
|
|
||||||
Restore(ctx context.Context, id int64) (int64, error)
|
|
||||||
Delete(ctx context.Context, id int64) (int64, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type sourceRepository struct {
|
type sourceRepository struct {
|
||||||
conn *sql.DB
|
conn *sql.DB
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ const (
|
|||||||
ErrUserNotFound string = "requested user was not found"
|
ErrUserNotFound string = "requested user was not found"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Users interface {
|
type IUserTable interface {
|
||||||
GetByName(name string) (domain.UserEntity, error)
|
GetByName(name string) (domain.UserEntity, error)
|
||||||
Create(name, password, scope string) (int64, error)
|
Create(name, password, scope string) (int64, error)
|
||||||
Update(id int, entity domain.UserEntity) error
|
Update(id int, entity domain.UserEntity) error
|
||||||
@ -27,17 +27,17 @@ type Users interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a new instance of UserRepository with the bound sql
|
// Creates a new instance of UserRepository with the bound sql
|
||||||
func NewUserRepository(conn *sql.DB) userRepository {
|
func NewUserRepository(conn *sql.DB) UserRepository {
|
||||||
return userRepository{
|
return UserRepository{
|
||||||
connection: conn,
|
connection: conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type userRepository struct {
|
type UserRepository struct {
|
||||||
connection *sql.DB
|
connection *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur userRepository) GetByName(name string) (domain.UserEntity, error) {
|
func (ur UserRepository) GetByName(name string) (domain.UserEntity, error) {
|
||||||
builder := sqlbuilder.NewSelectBuilder()
|
builder := sqlbuilder.NewSelectBuilder()
|
||||||
builder.Select("*").From("users").Where(
|
builder.Select("*").From("users").Where(
|
||||||
builder.E("Name", name),
|
builder.E("Name", name),
|
||||||
@ -57,7 +57,7 @@ func (ur userRepository) GetByName(name string) (domain.UserEntity, error) {
|
|||||||
return data[0], nil
|
return data[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur userRepository) Create(name, password, scope string) (int64, error) {
|
func (ur UserRepository) Create(name, password, scope string) (int64, error) {
|
||||||
passwordBytes := []byte(password)
|
passwordBytes := []byte(password)
|
||||||
hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
|
hash, err := bcrypt.GenerateFromPassword(passwordBytes, bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -79,11 +79,11 @@ func (ur userRepository) Create(name, password, scope string) (int64, error) {
|
|||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur userRepository) Update(id int, entity domain.UserEntity) error {
|
func (ur UserRepository) Update(id int, entity domain.UserEntity) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur userRepository) UpdatePassword(name, password string) error {
|
func (ur UserRepository) UpdatePassword(name, password string) error {
|
||||||
_, err := ur.GetByName(name)
|
_, err := ur.GetByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@ -97,7 +97,7 @@ func (ur userRepository) UpdatePassword(name, password string) error {
|
|||||||
|
|
||||||
// If the hash matches what we have in the database, an error will not be returned.
|
// If the hash matches what we have in the database, an error will not be returned.
|
||||||
// If the user does not exist or the hash does not match, an error will be returned
|
// If the user does not exist or the hash does not match, an error will be returned
|
||||||
func (ur userRepository) CheckUserHash(name, password string) error {
|
func (ur UserRepository) CheckUserHash(name, password string) error {
|
||||||
record, err := ur.GetByName(name)
|
record, err := ur.GetByName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -111,7 +111,7 @@ func (ur userRepository) CheckUserHash(name, password string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur userRepository) UpdateScopes(name, scope string) error {
|
func (ur UserRepository) UpdateScopes(name, scope string) error {
|
||||||
builder := sqlbuilder.NewUpdateBuilder()
|
builder := sqlbuilder.NewUpdateBuilder()
|
||||||
builder.Update("users")
|
builder.Update("users")
|
||||||
builder.Set(
|
builder.Set(
|
||||||
@ -129,7 +129,7 @@ func (ur userRepository) UpdateScopes(name, scope string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur userRepository) processRows(rows *sql.Rows) []domain.UserEntity {
|
func (ur UserRepository) processRows(rows *sql.Rows) []domain.UserEntity {
|
||||||
items := []domain.UserEntity{}
|
items := []domain.UserEntity{}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
|
@ -1,25 +1,6 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
|
|
||||||
"git.jamestombleson.com/jtom38/newsbot-api/internal/repository"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RepositoryService struct {
|
type RepositoryService struct {
|
||||||
Articles repository.ArticlesRepo
|
|
||||||
DiscordWebHooks repository.DiscordWebHookRepo
|
|
||||||
Sources repository.Sources
|
|
||||||
Users repository.Users
|
|
||||||
RefreshTokens repository.RefreshToken
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepositoryService(conn *sql.DB) RepositoryService {
|
|
||||||
return RepositoryService{
|
|
||||||
Articles: repository.NewArticleRepository(conn),
|
|
||||||
DiscordWebHooks: repository.NewDiscordWebHookRepository(conn),
|
|
||||||
Sources: repository.NewSourceRepository(conn),
|
|
||||||
Users: repository.NewUserRepository(conn),
|
|
||||||
RefreshTokens: repository.NewRefreshTokenRepository(conn),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import "git.jamestombleson.com/jtom38/newsbot-api/internal/domain"
|
|
||||||
|
|
||||||
func ArticlesToDto(items []domain.ArticleEntity) []domain.ArticleDto {
|
|
||||||
var dtos []domain.ArticleDto
|
|
||||||
for _, item := range items {
|
|
||||||
dtos = append(dtos, ArticleToDto(item))
|
|
||||||
}
|
|
||||||
return dtos
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArticleToDto(item domain.ArticleEntity) domain.ArticleDto {
|
|
||||||
return domain.ArticleDto{
|
|
||||||
ID: item.ID,
|
|
||||||
SourceID: item.SourceID,
|
|
||||||
Tags: item.Tags,
|
|
||||||
Title: item.Title,
|
|
||||||
Url: item.Url,
|
|
||||||
PubDate: item.PubDate,
|
|
||||||
IsVideo: item.IsVideo,
|
|
||||||
Thumbnail: item.Thumbnail,
|
|
||||||
Description: item.Description,
|
|
||||||
AuthorName: item.AuthorName,
|
|
||||||
AuthorImageUrl: item.AuthorImageUrl,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SourcesToDto(items []domain.SourceEntity) []domain.SourceDto {
|
|
||||||
var dtos []domain.SourceDto
|
|
||||||
for _, item := range items {
|
|
||||||
dtos = append(dtos, SourceToDto(item))
|
|
||||||
}
|
|
||||||
return dtos
|
|
||||||
}
|
|
||||||
|
|
||||||
func SourceToDto(item domain.SourceEntity) domain.SourceDto {
|
|
||||||
return domain.SourceDto{
|
|
||||||
ID: item.ID,
|
|
||||||
Source: item.Source,
|
|
||||||
DisplayName: item.DisplayName,
|
|
||||||
Url: item.Url,
|
|
||||||
Tags: item.Tags,
|
|
||||||
Enabled: item.Enabled,
|
|
||||||
}
|
|
||||||
}
|
|
2
makefile
2
makefile
@ -19,7 +19,7 @@ migrate-dev-down: ## revert sql migrations to dev db
|
|||||||
|
|
||||||
swag: ## Generates the swagger documentation with the swag tool
|
swag: ## Generates the swagger documentation with the swag tool
|
||||||
~/go/bin/swag f
|
~/go/bin/swag f
|
||||||
~/go/bin/swag init -g cmd/server.go
|
~/go/bin/swag i
|
||||||
|
|
||||||
gensql: ## Generates SQL code with sqlc
|
gensql: ## Generates SQL code with sqlc
|
||||||
sqlc generate
|
sqlc generate
|
Loading…
Reference in New Issue
Block a user