Skip to content

Commit

Permalink
fixes timestamp filtering of episode actions
Browse files Browse the repository at this point in the history
The timestamp is being stored in the DB as an integer, but in a
field of type varchar(255). So the DB cannot be used to sort of filter,
because it would sort the integers alphabetically.

The workaround is to load all of the results into memory and then
throw away any that don't meet the optional `since=` filter.

fixes oxtyped#39
  • Loading branch information
mhrivnak committed Dec 14, 2024
1 parent bcd3409 commit c2a1b3b
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 22 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,16 @@ $ gpodder2go serve --no-auth

Alternatively, you can switch to use [Antennapod](https://antennapod.org/) which has implemented the login spec which gpodder2go currently supports.

### Supports
### Supported Clients

- [Antennapod](https://antennapod.org/)
#### [Antennapod](https://antennapod.org/)

These features are all working with Antennapod:
- Authentication API
- Subscriptions API
- Episode Actions API
- Device API
- Device Synchronization API

### Development

Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/spf13/cobra v1.4.0
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
modernc.org/sqlite v1.26.0
github.com/relvacode/iso8601 v1.3.0
)

require (
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/relvacode/iso8601 v1.3.0 h1:HguUjsGpIMh/zsTczGN3DVJFxTU/GX+MMmzcKoMO7ko=
github.com/relvacode/iso8601 v1.3.0/go.mod h1:FlNp+jz+TXpyRqgmM7tnzHHzBnz776kmAH2h3sZCn0I=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
Expand Down
32 changes: 16 additions & 16 deletions pkg/data/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,11 @@ func (s *SQLite) RetrieveDevices(username string) ([]Device, error) {

func (l *SQLite) AddEpisodeActionHistory(username string, e EpisodeAction) error {
db := l.db
tx, err := db.Begin()
if err != nil {
return err
}

_, err = tx.Exec("INSERT INTO episode_actions(device_id, podcast, episode, action, position, started, total, timestamp) VALUES (?,?,?,?,?,?,?,?)", e.Device, e.Podcast, e.Episode, e.Action, e.Position, e.Started, e.Total, e.Timestamp.Unix())
_, err := db.Exec("INSERT INTO episode_actions(device_id, podcast, episode, action, position, started, total, timestamp) VALUES (?,?,?,?,?,?,?,?)", e.Device, e.Podcast, e.Episode, e.Action, e.Position, e.Started, e.Total, e.Timestamp.Unix())
if err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}

Expand All @@ -161,14 +155,8 @@ func (l *SQLite) RetrieveEpisodeActionHistory(username string, deviceId string,

query := "SELECT a.podcast, a.episode, a.device_id, a.action, a.position, a.started, a.total, a.timestamp"
query = query + " FROM episode_actions as a, devices as d, users as u"
query = query + " WHERE a.device_id = d.name AND d.user_id = u.id AND u.username = ?"
var args []interface{}
args = append(args, username)
if !since.IsZero() {
query = query + " AND a.timestamp > ?"
args = append(args, since)
}
query = query + " ORDER BY a.id"
query = query + " WHERE a.device_id = d.name AND d.user_id = u.id AND u.username = ? ORDER BY a.id"
args := []interface{}{username}
rows, err := db.Query(query, args...)
if err != nil {
return nil, err
Expand Down Expand Up @@ -200,8 +188,20 @@ func (l *SQLite) RetrieveEpisodeActionHistory(username string, deviceId string,
timestamp.Time = time.Unix(g, 0)
a.Timestamp = timestamp

actions = append(actions, a)
// For some reason, the timestamp for episode actions has been stored as
// an integer, but in a field of type varchar(255). (that's why you see
// the ParseInt call above). So we cannot use a DB query to sort or
// filter by timestamp, because the DB would sort the integers
// alphabetically. Someone should probably fix that by making a
// migration to change the timestamp type in the DB, and then let the DB
// handle the filtering.
if !since.IsZero() {
if a.Timestamp.Before(since) {
continue
}
}

actions = append(actions, a)
}

return actions, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/data/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type Subscription struct {
Devices []int `json:"devices"`
Podcast string `json:"podcast"`
Action string `json:"action"`
Timestamp CustomTimestamp `json:"timestamp"`
Timestamp CustomTimestamp `json:"timestamp"` // sqlite stores this as a varchar(255)
}

type Device struct {
Expand Down

0 comments on commit c2a1b3b

Please sign in to comment.