aboutsummaryrefslogtreecommitdiff
path: root/cmd/mi/models
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-05-22 12:32:28 -0400
committerXe Iaso <me@xeiaso.net>2024-05-22 12:34:27 -0400
commit035a53c46055458ccf2e90172fb1166848eaa254 (patch)
tree2e4b48129926143af753be2742ce1f8998e98f37 /cmd/mi/models
parent531fae570d0fdb89a519d3e4e1c80a7ff8b6e665 (diff)
downloadx-035a53c46055458ccf2e90172fb1166848eaa254.tar.xz
x-035a53c46055458ccf2e90172fb1166848eaa254.zip
cmd/mi: introduce announcer to replace the current one in mimi
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/mi/models')
-rw-r--r--cmd/mi/models/blogpost.go46
-rw-r--r--cmd/mi/models/dao.go36
2 files changed, 80 insertions, 2 deletions
diff --git a/cmd/mi/models/blogpost.go b/cmd/mi/models/blogpost.go
new file mode 100644
index 0000000..ad5bd81
--- /dev/null
+++ b/cmd/mi/models/blogpost.go
@@ -0,0 +1,46 @@
+package models
+
+import (
+ "context"
+ "time"
+
+ "gorm.io/gorm"
+ "within.website/x/proto/external/jsonfeed"
+)
+
+// Blogpost is a single blogpost from a JSON Feed.
+//
+// This is tracked in the database so that the Announcer service can avoid double-posting.
+type Blogpost struct {
+ gorm.Model // adds CreatedAt, UpdatedAt, DeletedAt
+ ID string `gorm:"uniqueIndex"` // unique identifier for the blogpost
+ URL string `gorm:"uniqueIndex"` // URL of the blogpost
+ Title string // title of the blogpost
+ BodyHTML string // HTML body of the blogpost
+ PublishedAt time.Time // when the blogpost was published
+}
+
+func (d *DAO) HasBlogpost(ctx context.Context, postURL string) (bool, error) {
+ var count int64
+ if err := d.db.WithContext(ctx).Model(&Blogpost{}).Where("url = ?", postURL).Count(&count).Error; err != nil {
+ return false, err
+ }
+
+ return count > 0, nil
+}
+
+func (d *DAO) InsertBlogpost(ctx context.Context, post *jsonfeed.Item) (*Blogpost, error) {
+ bp := &Blogpost{
+ ID: post.GetId(),
+ URL: post.GetUrl(),
+ Title: post.GetTitle(),
+ BodyHTML: post.GetContentHtml(),
+ PublishedAt: post.GetDatePublished().AsTime(),
+ }
+
+ if err := d.db.WithContext(ctx).Create(bp).Error; err != nil {
+ return nil, err
+ }
+
+ return bp, nil
+}
diff --git a/cmd/mi/models/dao.go b/cmd/mi/models/dao.go
index 9830bfe..9849c6d 100644
--- a/cmd/mi/models/dao.go
+++ b/cmd/mi/models/dao.go
@@ -4,9 +4,13 @@ import (
"context"
"crypto/rand"
"errors"
+ "log/slog"
+ "os"
"time"
"github.com/oklog/ulid/v2"
+ slogGorm "github.com/orandin/slog-gorm"
+ "gorm.io/driver/sqlite"
"gorm.io/gorm"
)
@@ -18,8 +22,36 @@ type DAO struct {
db *gorm.DB
}
-func New(db *gorm.DB) *DAO {
- return &DAO{db: db}
+func (d *DAO) DB() *gorm.DB {
+ return d.db
+}
+
+func (d *DAO) Ping(ctx context.Context) error {
+ if err := d.db.WithContext(ctx).Exec("select 1+1").Error; err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func New(dbLoc string) (*DAO, error) {
+ db, err := gorm.Open(sqlite.Open(dbLoc), &gorm.Config{
+ Logger: slogGorm.New(
+ slogGorm.WithErrorField("err"),
+ slogGorm.WithRecordNotFoundError(),
+ ),
+ })
+ if err != nil {
+ slog.Error("failed to connect to database", "err", err)
+ os.Exit(1)
+ }
+
+ if err := db.AutoMigrate(&Member{}, &Switch{}, &Blogpost{}); err != nil {
+ slog.Error("failed to migrate schema", "err", err)
+ os.Exit(1)
+ }
+
+ return &DAO{db: db}, nil
}
func (d *DAO) Members(ctx context.Context) ([]Member, error) {