add structure for ai short summaries

This commit is contained in:
2025-01-07 15:26:26 +01:00
parent 321ccfe44d
commit 706ebe25a0
5 changed files with 43 additions and 24 deletions

View File

@@ -0,0 +1,9 @@
-- +goose Up
-- +goose StatementBegin
ALTER TABLE articles ADD COLUMN aisummary TEXT DEFAULT '';
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE articles DROP COLUMN IF EXISTS aisummary;
-- +goose StatementEnd

View File

@@ -1,13 +1,16 @@
{{ define "content" }} {{ define "content" }}
<div class="content"> <div class="content container">
{{ range . }} {{ range . }}
<div class="card p-2 m-4" style=""> <div class="card p-2 m-4">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{{ .Title }}</h5> <h5 class="card-title">{{ .Title }}</h5>
<h6 class="card-subtitle mb-2 text-body-secondary"> <h6 class="card-subtitle mb-2 text-body-secondary">
<span class="badge text-bg-secondary">{{ .ShortSource }}</span> <span class="badge text-bg-secondary">{{ .ShortSource }}</span>
<span class="badge text-bg-secondary">{{ .PublishDate }}</span> <span class="badge text-bg-secondary">{{ .PublishDate }}</span>
{{if .AiSummarized}}
<span class="badge text-bg-success">ai summary</span>
{{end}}
</h6> </h6>
<p class="card-text">{{ .Summary }}</p> <p class="card-text">{{ .Summary }}</p>
<a href="{{ .SourceUrl }}" class="card-link">Link</a> <a href="{{ .SourceUrl }}" class="card-link">Link</a>

View File

@@ -9,7 +9,7 @@ import (
// List the latest articles using the base template. // List the latest articles using the base template.
func (app *App) Index(w http.ResponseWriter, req *http.Request) { func (app *App) Index(w http.ResponseWriter, req *http.Request) {
// get articles // get articles
articles, err := app.articles.All(10) articles, err := app.articles.All(30)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return

View File

@@ -13,22 +13,28 @@ type Article struct {
FetchDate time.Time FetchDate time.Time
Title string Title string
Content string Content string
AiSummary string
} }
// TODO docstring // TODO docstring
type ArticleViewModel struct { type ArticleViewModel struct {
Title string Title string
PublishDate string PublishDate string
SourceUrl string SourceUrl string
ShortSource string ShortSource string
Summary string Summary string
AiSummarized bool
} }
// TODO docstring // TODO docstring
func (a *Article) ViewModel() *ArticleViewModel { func (a *Article) ViewModel() *ArticleViewModel {
summary := a.Content summary := a.AiSummary
if len(a.Content) > 300 { if summary == "" {
summary = summary[:300] if len(a.Content) > 200 {
summary = a.Content[:200]
} else {
summary = a.Content
}
} }
short_url := "" short_url := ""
@@ -38,10 +44,11 @@ func (a *Article) ViewModel() *ArticleViewModel {
} }
return &ArticleViewModel{ return &ArticleViewModel{
Title: a.Title, Title: a.Title,
PublishDate: a.PublishDate.Local().Format("02.01.2006"), PublishDate: a.PublishDate.Local().Format("02.01.2006"),
SourceUrl: a.SourceUrl, SourceUrl: a.SourceUrl,
ShortSource: short_url, ShortSource: short_url,
Summary: summary, Summary: summary,
AiSummarized: a.AiSummary != "",
} }
} }

View File

@@ -13,7 +13,7 @@ type ArticleModel struct {
// the connection to the database fails. // the connection to the database fails.
func (m *ArticleModel) All(limit int) ([]model.Article, error) { func (m *ArticleModel) All(limit int) ([]model.Article, error) {
stmt := ` stmt := `
SELECT id, title, sourceUrl, content, publishDate, fetchDate SELECT id, title, sourceUrl, content, publishDate, fetchDate, aisummary
FROM articles FROM articles
ORDER BY publishDate DESC ORDER BY publishDate DESC
LIMIT $1 LIMIT $1
@@ -26,7 +26,7 @@ func (m *ArticleModel) All(limit int) ([]model.Article, error) {
articles := []model.Article{} articles := []model.Article{}
for rows.Next() { for rows.Next() {
a := model.Article{} a := model.Article{}
err := rows.Scan(&a.Identifier, &a.Title, &a.SourceUrl, &a.Content, &a.PublishDate, &a.FetchDate) err := rows.Scan(&a.Identifier, &a.Title, &a.SourceUrl, &a.Content, &a.PublishDate, &a.FetchDate, &a.AiSummary)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -80,19 +80,19 @@ func (m *ArticleModel) Search(query string) ([]model.Article, error) {
// query fails. // query fails.
func (m *ArticleModel) Insert(a *model.Article) error { func (m *ArticleModel) Insert(a *model.Article) error {
// insert article // insert article
stmt := `INSERT INTO articles (title, sourceUrl, content, publishDate, fetchDate) stmt := `INSERT INTO articles (title, sourceUrl, content, publishDate, fetchDate, aisummary)
VALUES ($1, $2, $3, $4, $5) VALUES ($1, $2, $3, $4, $5, $6)
` `
_, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Content, a.PublishDate, a.FetchDate) _, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Content, a.PublishDate, a.FetchDate, a.AiSummary)
return err return err
} }
// TODO docstring // TODO docstring
func (m *ArticleModel) Update(a *model.Article) error { func (m *ArticleModel) Update(a *model.Article) error {
stmt := `UPDATE articles stmt := `UPDATE articles
SET title = $1, sourceUrl = $2, content = $4, publishDate = $5, fetchDate = $6 SET title = $1, sourceUrl = $2, content = $4, publishDate = $5, fetchDate = $6, aisummary = $7
WHERE id = $7 WHERE id = $8
` `
_, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Content, a.PublishDate, a.FetchDate, a.Identifier) _, err := m.DB.Exec(stmt, a.Title, a.SourceUrl, a.Content, a.PublishDate, a.FetchDate, a.AiSummary, a.Identifier)
return err return err
} }