mirror of
https://github.com/miniflux/v2.git
synced 2025-08-01 17:38:37 +00:00
Add generic webhook integration
This commit is contained in:
parent
32d33104a4
commit
48f6885f44
39 changed files with 527 additions and 324 deletions
|
@ -107,8 +107,10 @@ func (s *Storage) createEnclosure(tx *sql.Tx, enclosure *model.Enclosure) error
|
|||
VALUES
|
||||
($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (user_id, entry_id, md5(url)) DO NOTHING
|
||||
RETURNING
|
||||
id
|
||||
`
|
||||
_, err := tx.Exec(
|
||||
if err := tx.QueryRow(
|
||||
query,
|
||||
enclosureURL,
|
||||
enclosure.Size,
|
||||
|
@ -116,24 +118,22 @@ func (s *Storage) createEnclosure(tx *sql.Tx, enclosure *model.Enclosure) error
|
|||
enclosure.EntryID,
|
||||
enclosure.UserID,
|
||||
enclosure.MediaProgression,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf(`store: unable to create enclosure: %v`, err)
|
||||
).Scan(&enclosure.ID); err != nil && err != sql.ErrNoRows {
|
||||
return fmt.Errorf(`store: unable to create enclosure: %w`, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Storage) updateEnclosures(tx *sql.Tx, userID, entryID int64, enclosures model.EnclosureList) error {
|
||||
if len(enclosures) == 0 {
|
||||
func (s *Storage) updateEnclosures(tx *sql.Tx, entry *model.Entry) error {
|
||||
if len(entry.Enclosures) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sqlValues := []any{userID, entryID}
|
||||
sqlValues := []any{entry.UserID, entry.ID}
|
||||
sqlPlaceholders := []string{}
|
||||
|
||||
for _, enclosure := range enclosures {
|
||||
for _, enclosure := range entry.Enclosures {
|
||||
sqlPlaceholders = append(sqlPlaceholders, fmt.Sprintf(`$%d`, len(sqlValues)+1))
|
||||
sqlValues = append(sqlValues, strings.TrimSpace(enclosure.URL))
|
||||
|
||||
|
@ -143,11 +143,10 @@ func (s *Storage) updateEnclosures(tx *sql.Tx, userID, entryID int64, enclosures
|
|||
}
|
||||
|
||||
query := `
|
||||
DELETE FROM enclosures
|
||||
DELETE FROM
|
||||
enclosures
|
||||
WHERE
|
||||
user_id=$1 AND
|
||||
entry_id=$2 AND
|
||||
url NOT IN (%s)
|
||||
user_id=$1 AND entry_id=$2 AND url NOT IN (%s)
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, strings.Join(sqlPlaceholders, `,`))
|
||||
|
|
|
@ -138,7 +138,7 @@ func (s *Storage) createEntry(tx *sql.Tx, entry *model.Entry) error {
|
|||
$11
|
||||
)
|
||||
RETURNING
|
||||
id, status
|
||||
id, status, created_at, changed_at
|
||||
`
|
||||
err := tx.QueryRow(
|
||||
query,
|
||||
|
@ -153,7 +153,12 @@ func (s *Storage) createEntry(tx *sql.Tx, entry *model.Entry) error {
|
|||
entry.FeedID,
|
||||
entry.ReadingTime,
|
||||
pq.Array(removeDuplicates(entry.Tags)),
|
||||
).Scan(&entry.ID, &entry.Status)
|
||||
).Scan(
|
||||
&entry.ID,
|
||||
&entry.Status,
|
||||
&entry.CreatedAt,
|
||||
&entry.ChangedAt,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf(`store: unable to create entry %q (feed #%d): %v`, entry.URL, entry.FeedID, err)
|
||||
|
@ -215,7 +220,7 @@ func (s *Storage) updateEntry(tx *sql.Tx, entry *model.Entry) error {
|
|||
enclosure.EntryID = entry.ID
|
||||
}
|
||||
|
||||
return s.updateEnclosures(tx, entry.UserID, entry.ID, entry.Enclosures)
|
||||
return s.updateEnclosures(tx, entry)
|
||||
}
|
||||
|
||||
// entryExists checks if an entry already exists based on its hash when refreshing a feed.
|
||||
|
@ -264,7 +269,7 @@ func (s *Storage) cleanupEntries(feedID int64, entryHashes []string) error {
|
|||
}
|
||||
|
||||
// RefreshFeedEntries updates feed entries while refreshing a feed.
|
||||
func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries, updateExistingEntries bool) (err error) {
|
||||
func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries, updateExistingEntries bool) (newEntries model.Entries, err error) {
|
||||
var entryHashes []string
|
||||
|
||||
for _, entry := range entries {
|
||||
|
@ -273,15 +278,15 @@ func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries
|
|||
|
||||
tx, err := s.db.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf(`store: unable to start transaction: %v`, err)
|
||||
return nil, fmt.Errorf(`store: unable to start transaction: %v`, err)
|
||||
}
|
||||
|
||||
entryExists, err := s.entryExists(tx, entry)
|
||||
if err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
return fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
|
||||
return nil, fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
|
||||
}
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if entryExists {
|
||||
|
@ -290,17 +295,20 @@ func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries
|
|||
}
|
||||
} else {
|
||||
err = s.createEntry(tx, entry)
|
||||
if err == nil {
|
||||
newEntries = append(newEntries, entry)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
return fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
|
||||
return nil, fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
|
||||
}
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf(`store: unable to commit transaction: %v`, err)
|
||||
return nil, fmt.Errorf(`store: unable to commit transaction: %v`, err)
|
||||
}
|
||||
|
||||
entryHashes = append(entryHashes, entry.Hash)
|
||||
|
@ -312,7 +320,7 @@ func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries
|
|||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
return newEntries, nil
|
||||
}
|
||||
|
||||
// ArchiveEntries changes the status of entries to "removed" after the given number of days.
|
||||
|
|
|
@ -345,9 +345,9 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) {
|
|||
hide_globally=$24,
|
||||
url_rewrite_rules=$25,
|
||||
no_media_player=$26,
|
||||
apprise_service_urls=$29
|
||||
apprise_service_urls=$27
|
||||
WHERE
|
||||
id=$27 AND user_id=$28
|
||||
id=$28 AND user_id=$29
|
||||
`
|
||||
_, err = s.db.Exec(query,
|
||||
feed.FeedURL,
|
||||
|
@ -376,9 +376,9 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) {
|
|||
feed.HideGlobally,
|
||||
feed.UrlRewriteRules,
|
||||
feed.NoMediaPlayer,
|
||||
feed.AppriseServiceURLs,
|
||||
feed.ID,
|
||||
feed.UserID,
|
||||
feed.AppriseServiceURLs,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -167,7 +167,10 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
|
|||
shiori_password,
|
||||
shaarli_enabled,
|
||||
shaarli_url,
|
||||
shaarli_api_secret
|
||||
shaarli_api_secret,
|
||||
webhook_enabled,
|
||||
webhook_url,
|
||||
webhook_secret
|
||||
FROM
|
||||
integrations
|
||||
WHERE
|
||||
|
@ -234,6 +237,9 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
|
|||
&integration.ShaarliEnabled,
|
||||
&integration.ShaarliURL,
|
||||
&integration.ShaarliAPISecret,
|
||||
&integration.WebhookEnabled,
|
||||
&integration.WebhookURL,
|
||||
&integration.WebhookSecret,
|
||||
)
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
|
@ -308,9 +314,12 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
|
|||
shiori_password=$55,
|
||||
shaarli_enabled=$56,
|
||||
shaarli_url=$57,
|
||||
shaarli_api_secret=$58
|
||||
shaarli_api_secret=$58,
|
||||
webhook_enabled=$59,
|
||||
webhook_url=$60,
|
||||
webhook_secret=$61
|
||||
WHERE
|
||||
user_id=$59
|
||||
user_id=$62
|
||||
`
|
||||
_, err := s.db.Exec(
|
||||
query,
|
||||
|
@ -372,6 +381,9 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
|
|||
integration.ShaarliEnabled,
|
||||
integration.ShaarliURL,
|
||||
integration.ShaarliAPISecret,
|
||||
integration.WebhookEnabled,
|
||||
integration.WebhookURL,
|
||||
integration.WebhookSecret,
|
||||
integration.UserID,
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue