Skip to content

Commit 5a687d8

Browse files
committed
bug fix duplicate posts & refactor
1 parent e44d3ed commit 5a687d8

File tree

6 files changed

+59
-25
lines changed

6 files changed

+59
-25
lines changed

autoposter.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (a *AutoPoster) Run() {
4747
continue
4848
}
4949

50-
savedPosts, err := a.db.GetPostsByTwitterID(acct.TwitterID)
50+
savedPosts, err := a.db.GetSavedPostsByTwitterID(acct.TwitterID)
5151
if err != nil {
5252
PrintErrWithTimeout(err, a.timeout)
5353
continue
@@ -59,10 +59,8 @@ func (a *AutoPoster) Run() {
5959
freshPosts = posts
6060
} else {
6161
for _, post := range posts {
62-
for _, savedPost := range savedPosts {
63-
if post.Url != savedPost.Url {
64-
freshPosts = append(freshPosts, post)
65-
}
62+
if !post.InSaved(savedPosts) {
63+
freshPosts = append(freshPosts, post)
6664
}
6765
}
6866
}
@@ -82,7 +80,7 @@ func (a *AutoPoster) Run() {
8280
continue
8381
}
8482

85-
if err := a.db.InsertPost(p.ToSaved(acct.TwitterID)); err != nil {
83+
if err := a.db.InsertSavedPost(p.ToSaved(acct.TwitterID)); err != nil {
8684
PrintErr(err)
8785
}
8886

db.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func NewDB(driverName string, dataSourceName string) (*DB, error) {
3535
create table if not exists %s (
3636
id text not null primary key,
3737
twitter_id text not null,
38-
url text not null,
38+
url text not null unique,
3939
title text not null
4040
);
4141
`, PostsTableName)
@@ -52,33 +52,33 @@ func NewDB(driverName string, dataSourceName string) (*DB, error) {
5252
}, nil
5353
}
5454

55-
func (db DB) InsertPost(sp SavedPost) error {
56-
query := fmt.Sprintf(`
55+
func (db DB) InsertSavedPost(sp SavedPost) error {
56+
row := db.Client.QueryRow(fmt.Sprintf(`select * from %s where url = "%s"`, PostsTableName, sp.Url))
57+
if row.Scan() != sql.ErrNoRows {
58+
return fmt.Errorf(`SavedPost with url "%s" already present in db`, sp.Url)
59+
}
60+
61+
insertQuery := fmt.Sprintf(`
5762
insert into %s (id, twitter_id, url, title)
5863
values (?, ?, ?, ?);
5964
`, PostsTableName)
6065

61-
// Remove query string to ensure proper url match via autoposter
62-
url, err := stripQueryString(sp.Url)
63-
if err != nil {
64-
return err
65-
}
66-
67-
if _, err := db.Client.Exec(query, sp.ID, sp.TwitterID, url, sp.Title); err != nil {
66+
if _, err := db.Client.Exec(insertQuery, sp.ID, sp.TwitterID, sp.Url, sp.Title); err != nil {
6867
return err
6968
}
7069

7170
return nil
7271
}
7372

74-
func (db DB) GetPostsByTwitterID(twitterID string) ([]SavedPost, error) {
73+
func (db DB) GetSavedPostsByTwitterID(twitterID string) ([]SavedPost, error) {
74+
var savedPosts []SavedPost
75+
7576
rows, err := db.Client.Query(fmt.Sprintf(`select * from %s where twitter_id = "%s"`, PostsTableName, twitterID))
7677
if err != nil {
77-
return []SavedPost{}, err
78+
return savedPosts, err
7879
}
7980
defer rows.Close()
8081

81-
var savedPosts []SavedPost
8282
for rows.Next() {
8383
sp, err := scanIntoSavedPost(rows)
8484
if err != nil {

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
const (
99
ConfigFilePath string = "config.json"
1010
// TODO: Impliment a max and min timeout to reduce chance of bot detection,
11-
// and also make it configurable.
11+
// and also make it configurable via flags.
1212
Timeout time.Duration = time.Minute * 18
1313
)
1414

post.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ type Post struct {
77
Title string
88
}
99

10-
func NewPost(url string, title string) *Post {
10+
func NewPost(url string, title string) (*Post, error) {
11+
// Remove query string to ensure proper url match in autoposter
12+
url, err := stripQueryString(url)
13+
if err != nil {
14+
return nil, err
15+
}
16+
1117
return &Post{
1218
Url: url,
1319
Title: title,
14-
}
20+
}, nil
1521
}
1622

1723
func (p Post) ToSaved(twitterID string) SavedPost {
@@ -21,3 +27,17 @@ func (p Post) ToSaved(twitterID string) SavedPost {
2127
Post: p,
2228
}
2329
}
30+
31+
// TODO: refactor to combine In() and InSaved()
32+
33+
func (p Post) In(posts []Post) bool {
34+
return Some(posts, func(post Post) bool {
35+
return post.Url == p.Url
36+
})
37+
}
38+
39+
func (p Post) InSaved(savedPosts []SavedPost) bool {
40+
return Some(savedPosts, func(savedPost SavedPost) bool {
41+
return savedPost.Url == p.Url
42+
})
43+
}

source.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,14 @@ func (r RssFeedSource) FetchPosts() ([]Post, error) {
4747
}
4848

4949
for _, item := range feed.Items {
50-
posts = append(posts, *NewPost(item.Link, item.Title))
50+
post, err := NewPost(item.Link, item.Title)
51+
if err != nil {
52+
continue
53+
}
54+
55+
if !post.In(posts) {
56+
posts = append(posts, *post)
57+
}
5158
}
5259

5360
return posts, nil

util.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ import (
66
"time"
77
)
88

9+
func Some[T any](arr []T, f func(T) bool) bool {
10+
for _, t := range arr {
11+
if f(t) {
12+
return true
13+
}
14+
}
15+
return false
16+
}
17+
918
func stripQueryString(u string) (string, error) {
1019
parsedUrl, err := url.Parse(u)
1120
if err != nil {
@@ -19,15 +28,15 @@ func stripQueryString(u string) (string, error) {
1928

2029
func PrintWithTimestamp(s string) {
2130
timestamp := time.Now().Format(time.UnixDate)
22-
fmt.Printf("[%s] error: %s\n", timestamp, s)
31+
fmt.Printf("[%s] %s\n\n", timestamp, s)
2332
}
2433

2534
func PrintWithTimestampf(format string, a ...any) {
2635
PrintWithTimestamp(fmt.Sprintf(format, a...))
2736
}
2837

2938
func PrintErr(err error) {
30-
PrintWithTimestamp(err.Error())
39+
PrintWithTimestampf("Error: %s", err.Error())
3140
}
3241

3342
func PrintErrWithTimeout(err error, timeout time.Duration) {

0 commit comments

Comments
 (0)