mirror of
https://github.com/zoriya/vex.git
synced 2025-12-06 07:06:09 +00:00
151 lines
3.5 KiB
Go
151 lines
3.5 KiB
Go
package vex
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/lib/pq"
|
|
)
|
|
|
|
type Feed struct {
|
|
Id uuid.UUID `json:"id"`
|
|
Name string `json:"name"`
|
|
Link string `json:"link"`
|
|
FaviconUrl string `json:"faviconUrl"`
|
|
Tags []string `json:"tags"`
|
|
SubmitterId uuid.UUID `json:"submitterId"`
|
|
Submitter *User `json:"submitter,omitempty"`
|
|
AddedDate time.Time `json:"addedDate"`
|
|
SyncErorr *string `json:"syncError,omitempty"`
|
|
etag string
|
|
lastFetchDate *time.Time
|
|
}
|
|
|
|
type FeedDao struct {
|
|
Id uuid.UUID
|
|
Name string
|
|
Link string
|
|
FaviconUrl string `db:"favicon_url"`
|
|
Tags pq.StringArray
|
|
SubmitterId uuid.UUID `db:"submitter_id"`
|
|
Submitter *User `db:"submitter"`
|
|
AddedDate time.Time `db:"added_date"`
|
|
SyncErorr *string `db:"sync_error"`
|
|
Etag string
|
|
LastFetchDate *time.Time `db:"last_fetch_date"`
|
|
}
|
|
|
|
func (f *FeedDao) ToFeed() Feed {
|
|
return Feed{
|
|
Id: f.Id,
|
|
Name: f.Name,
|
|
Link: f.Link,
|
|
FaviconUrl: f.FaviconUrl,
|
|
Tags: f.Tags,
|
|
SubmitterId: f.SubmitterId,
|
|
Submitter: f.Submitter,
|
|
AddedDate: f.AddedDate,
|
|
etag: f.Etag,
|
|
lastFetchDate: f.LastFetchDate,
|
|
}
|
|
}
|
|
|
|
func (f *Feed) ToDao() FeedDao {
|
|
return FeedDao{
|
|
Id: f.Id,
|
|
Name: f.Name,
|
|
Link: f.Link,
|
|
FaviconUrl: f.FaviconUrl,
|
|
Tags: f.Tags,
|
|
SubmitterId: f.SubmitterId,
|
|
Submitter: f.Submitter,
|
|
AddedDate: f.AddedDate,
|
|
Etag: f.etag,
|
|
LastFetchDate: f.lastFetchDate,
|
|
}
|
|
}
|
|
|
|
type FeedService struct {
|
|
database *sqlx.DB
|
|
reader *Reader
|
|
}
|
|
|
|
func NewFeedService(db *sqlx.DB, reader *Reader) FeedService {
|
|
return FeedService{
|
|
database: db,
|
|
reader: reader,
|
|
}
|
|
}
|
|
|
|
func (s FeedService) GetFeedData(link string) ([]Feed, error) {
|
|
parsed, err := s.reader.ReadFeed(link, "", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []Feed{
|
|
{
|
|
Id: uuid.New(),
|
|
Name: parsed.Title,
|
|
Link: link,
|
|
FaviconUrl: fmt.Sprintf("%s/favicon.ico", parsed.Link),
|
|
AddedDate: time.Now(),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (s FeedService) AddFeed(feed Feed) (Feed, error) {
|
|
_, err := s.database.NamedExec(
|
|
`insert into feeds (id, name, link, favicon_url, tags, submitter_id, added_date, etag, last_fetch_date)
|
|
values (:id, :name, :link, :favicon_url, :tags, :submitter_id, :added_date, :etag, :last_fetch_date)`,
|
|
feed.ToDao(),
|
|
)
|
|
if err != nil {
|
|
return Feed{}, err
|
|
}
|
|
|
|
return feed, nil
|
|
}
|
|
|
|
func (s FeedService) ListFeeds() ([]Feed, error) {
|
|
ret := []FeedDao{}
|
|
err := s.database.Select(
|
|
&ret,
|
|
`select f.*, u.id as "submitter.id", u.name as "submitter.name", u.email as "submitter.email", u.password as "submitter.password"
|
|
from feeds as f left
|
|
join users as u on u.id = f.submitter_id
|
|
order by added_date`,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return Map(ret, func(f FeedDao, _ int) Feed { return f.ToFeed() }), nil
|
|
}
|
|
|
|
func (s FeedService) UpdateSyncStatus(id uuid.UUID, etag string, lastFetchDate *time.Time) error {
|
|
_, err := s.database.NamedExec(
|
|
`update feeds set etag = :etag, last_fetch_date = :date, sync_error = :err
|
|
where id = :id`,
|
|
map[string]interface{}{
|
|
"id": id,
|
|
"etag": etag,
|
|
"date": lastFetchDate,
|
|
"err": nil,
|
|
},
|
|
)
|
|
return err
|
|
}
|
|
|
|
func (s FeedService) SaveSyncError(id uuid.UUID, error error) error {
|
|
_, err := s.database.NamedExec(
|
|
`update feeds set sync_error = :err
|
|
where id = :i`,
|
|
map[string]interface{}{
|
|
"id": id,
|
|
"err": error.Error(),
|
|
},
|
|
)
|
|
return err
|
|
}
|