Added: downloading and returning wikipedia articles
This commit is contained in:
11
internal/article/dto.go
Normal file
11
internal/article/dto.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package article
|
||||
|
||||
type ArticleDTO struct {
|
||||
Uuid string
|
||||
Title string
|
||||
Content string
|
||||
}
|
||||
|
||||
type ArticleQueryDTO struct {
|
||||
Title string
|
||||
}
|
||||
12
internal/article/error.go
Normal file
12
internal/article/error.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package article
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrArticleDownloadFailed = errors.New("article: download failed")
|
||||
ErrArticleQueryFailed = errors.New("article: article query failed")
|
||||
ErrArticleCreateFailed = errors.New("article: create failed")
|
||||
ErrArticleDeleteAllFailed = errors.New("article: failed to delete all articles")
|
||||
|
||||
ErrArticleTitleInvalidLength = errors.New("article: invalid article length")
|
||||
)
|
||||
9
internal/article/irepository.go
Normal file
9
internal/article/irepository.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package article
|
||||
|
||||
import "database/sql"
|
||||
|
||||
type IArticleRepository interface {
|
||||
CreateArticle(tx *sql.Tx, data ArticleCreateModel) error
|
||||
GetArticlesByTitle(tx *sql.Tx, title string) ([]ArticleModel, error)
|
||||
DeleteAllArticles(tx *sql.Tx) error
|
||||
}
|
||||
6
internal/article/iservice.go
Normal file
6
internal/article/iservice.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package article
|
||||
|
||||
type IArticleService interface {
|
||||
DownloadArticles() error
|
||||
QueryArticles(ArticleQueryDTO) ([]ArticleDTO, error)
|
||||
}
|
||||
13
internal/article/model.go
Normal file
13
internal/article/model.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package article
|
||||
|
||||
type ArticleModel struct {
|
||||
Uuid string
|
||||
Title string
|
||||
Content string
|
||||
}
|
||||
|
||||
type ArticleCreateModel struct {
|
||||
Uuid string
|
||||
Title string
|
||||
Content string
|
||||
}
|
||||
60
internal/article/repository.go
Normal file
60
internal/article/repository.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package article
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ArticleRepository struct{}
|
||||
|
||||
func NewArticleRepository() IArticleRepository {
|
||||
return &ArticleRepository{}
|
||||
}
|
||||
|
||||
func (ArticleRepository) CreateArticle(tx *sql.Tx, data ArticleCreateModel) error {
|
||||
query := `
|
||||
INSERT INTO articles(uuid, title, content)
|
||||
VALUES ($1, $2, $3);
|
||||
`
|
||||
|
||||
_, err := tx.Exec(query, data.Uuid, data.Title, data.Content)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ArticleRepository) GetArticlesByTitle(tx *sql.Tx, title string) ([]ArticleModel, error) {
|
||||
fmt.Println(title, " ------------------")
|
||||
query := `
|
||||
SELECT uuid, title, content
|
||||
FROM articles
|
||||
WHERE title LIKE $1 || '%'
|
||||
LIMIT 10;
|
||||
`
|
||||
|
||||
rows, err := tx.Query(query, title)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
articles := []ArticleModel{}
|
||||
for rows.Next() {
|
||||
var a ArticleModel
|
||||
|
||||
err = rows.Scan(&a.Uuid, &a.Title, &a.Content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
articles = append(articles, a)
|
||||
}
|
||||
|
||||
fmt.Println(articles)
|
||||
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
func (ArticleRepository) DeleteAllArticles(tx *sql.Tx) error {
|
||||
query := `DELETE FROM articles;`
|
||||
|
||||
_, err := tx.Exec(query)
|
||||
return err
|
||||
}
|
||||
107
internal/article/service.go
Normal file
107
internal/article/service.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package article
|
||||
|
||||
import (
|
||||
"log"
|
||||
"scrap/internal/db"
|
||||
"scrap/internal/wikipediadl"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type ArticleService struct {
|
||||
txRepo db.ITxRepository
|
||||
articleRepo IArticleRepository
|
||||
}
|
||||
|
||||
func NewArticleService(
|
||||
txRepo db.ITxRepository,
|
||||
articleRepo IArticleRepository,
|
||||
) IArticleService {
|
||||
return &ArticleService{
|
||||
txRepo: txRepo,
|
||||
articleRepo: articleRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (a ArticleService) QueryArticles(data ArticleQueryDTO) ([]ArticleDTO, error) {
|
||||
tx, err := a.txRepo.Begin()
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer a.txRepo.RollbackOnError(tx, &err)
|
||||
|
||||
articleTitleLength := len(data.Title)
|
||||
if articleTitleLength < 1 || articleTitleLength > 255 {
|
||||
return nil, ErrArticleTitleInvalidLength
|
||||
}
|
||||
|
||||
articles, err := a.articleRepo.GetArticlesByTitle(tx, data.Title)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return nil, ErrArticleQueryFailed
|
||||
}
|
||||
|
||||
articlesOut := make([]ArticleDTO, 0, len(articles))
|
||||
for _, am := range articles {
|
||||
a := ArticleDTO{
|
||||
Uuid: am.Uuid,
|
||||
Title: am.Title,
|
||||
Content: am.Content,
|
||||
}
|
||||
|
||||
articlesOut = append(articlesOut, a)
|
||||
}
|
||||
|
||||
return articlesOut, nil
|
||||
}
|
||||
|
||||
func (a ArticleService) DownloadArticles() error {
|
||||
tx, err := a.txRepo.Begin()
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return db.ErrTxBeginFailed
|
||||
}
|
||||
|
||||
defer a.txRepo.RollbackOnError(tx, &err)
|
||||
|
||||
if err = a.articleRepo.DeleteAllArticles(tx); err != nil {
|
||||
log.Println(err.Error())
|
||||
return ErrArticleDeleteAllFailed
|
||||
}
|
||||
|
||||
articleBundles, err := wikipediadl.FetchArticleBundles()
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return ErrArticleDownloadFailed
|
||||
}
|
||||
|
||||
for _, ab := range articleBundles {
|
||||
articles, err := wikipediadl.ExtractArticles(ab)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return ErrArticleDownloadFailed
|
||||
}
|
||||
|
||||
for _, article := range articles {
|
||||
articleData := ArticleCreateModel{
|
||||
Uuid: uuid.NewString(),
|
||||
Title: article.Title,
|
||||
Content: article.Revision.Text,
|
||||
}
|
||||
|
||||
if err = a.articleRepo.CreateArticle(tx, articleData); err != nil {
|
||||
log.Println(err.Error(), "tutaj ---------")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err = a.txRepo.Commit(tx); err != nil {
|
||||
log.Println(err.Error())
|
||||
return db.ErrTxCommitFailed
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user