[rhythmbox] podcast: use track numbers to record the order of episodes in rss feeds



commit 52a6421f822eeea6a48f437dfb349aeca0053900
Author: Jonathan Matthew <jonathan d14n org>
Date:   Fri Dec 31 23:03:05 2021 +1000

    podcast: use track numbers to record the order of episodes in rss feeds
    
    This improves use of feeds where multiple episodes are published with the
    same publication date in a specific order.  Previously episodes with the
    same date would be sorted by title, which would generally not maintain
    the order from the feed.
    
    Episodes that are no longer in the feed but still exist because they
    have been downloaded have track numbers assigned in sequence starting
    after the last episode in the feed, so ordering is preserved there too.

 podcast/rb-podcast-add-dialog.c |  3 +++
 podcast/rb-podcast-manager.c    | 43 +++++++++++++++++++++++++++++++++++++++++
 podcast/rb-podcast-manager.h    |  1 +
 podcast/rb-podcast-source.c     |  7 +++++++
 4 files changed, 54 insertions(+)
---
diff --git a/podcast/rb-podcast-add-dialog.c b/podcast/rb-podcast-add-dialog.c
index 4349befc5..4b8d15d03 100644
--- a/podcast/rb-podcast-add-dialog.c
+++ b/podcast/rb-podcast-add-dialog.c
@@ -150,7 +150,9 @@ static void
 add_posts_for_feed (RBPodcastAddDialog *dialog, RBPodcastChannel *channel)
 {
        GList *l;
+       gulong position;
 
+       position = 1;
        for (l = channel->posts; l != NULL; l = l->next) {
                RBPodcastItem *item = (RBPodcastItem *) l->data;
 
@@ -166,6 +168,7 @@ add_posts_for_feed (RBPodcastAddDialog *dialog, RBPodcastChannel *channel)
                                             item->guid,
                                             (item->pub_date > 0 ? item->pub_date : channel->pub_date),
                                             item->duration,
+                                            position++,
                                             item->filesize);
        }
 
diff --git a/podcast/rb-podcast-manager.c b/podcast/rb-podcast-manager.c
index 04be55d4d..b479f7120 100644
--- a/podcast/rb-podcast-manager.c
+++ b/podcast/rb-podcast-manager.c
@@ -919,6 +919,7 @@ rb_podcast_manager_add_post (RhythmDB *db,
                             const char *guid,
                             gulong date,
                             gulong duration,
+                            gulong position,
                             guint64 filesize)
 {
        RhythmDBEntryType *entry_type;
@@ -999,6 +1000,11 @@ rb_podcast_manager_add_post (RhythmDB *db,
        rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_POST_TIME, &val);
        g_value_unset (&val);
 
+       g_value_init (&val, G_TYPE_ULONG);
+       g_value_set_ulong (&val, position);
+       rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &val);
+       g_value_unset (&val);
+
        if (guid != NULL) {
                g_value_init (&val, G_TYPE_STRING);
                g_value_set_string (&val, guid);
@@ -1349,6 +1355,31 @@ rb_podcast_manager_insert_feed_url (RBPodcastManager *pd, const char *url)
        g_value_unset (&last_update_val);
 }
 
+static gint
+existing_entry_sort (gconstpointer a, gconstpointer b)
+{
+       gulong ta, tb;
+
+       /* sort by track numbers (ascending), or by date (descending) if not available yet */
+       ta = rhythmdb_entry_get_ulong ((RhythmDBEntry *)a, RHYTHMDB_PROP_TRACK_NUMBER);
+       tb = rhythmdb_entry_get_ulong ((RhythmDBEntry *)b, RHYTHMDB_PROP_TRACK_NUMBER);
+       if (ta < tb)
+               return -1;
+       else if (ta > tb)
+               return 1;
+       else if (ta != 0)
+               return 0;
+
+       ta = rhythmdb_entry_get_ulong ((RhythmDBEntry *)a, RHYTHMDB_PROP_POST_TIME);
+       tb = rhythmdb_entry_get_ulong ((RhythmDBEntry *)b, RHYTHMDB_PROP_POST_TIME);
+       if (ta > tb)
+               return -1;
+       else if (ta < tb)
+               return 1;
+       else
+               return 0;
+}
+
 void
 rb_podcast_manager_add_parsed_feed (RBPodcastManager *pd, RBPodcastChannel *data)
 {
@@ -1364,6 +1395,7 @@ rb_podcast_manager_add_parsed_feed (RBPodcastManager *pd, RBPodcastChannel *data
        GValue error_val = { 0, };
        gulong last_post = 0;
        gulong new_last_post;
+       gulong position;
        const char *title;
        GList *download_entries = NULL;
        gboolean new_feed, updated;
@@ -1409,6 +1441,7 @@ rb_podcast_manager_add_parsed_feed (RBPodcastManager *pd, RBPodcastChannel *data
                                          data->url,
                                        RHYTHMDB_QUERY_END);
                existing_entries = g_list_copy (rhythmdb_query_result_list_get_results (results));
+               existing_entries = g_list_sort (existing_entries, existing_entry_sort);
        } else {
                rb_debug ("Adding podcast feed: %s", data->url);
                entry = rhythmdb_entry_new (db,
@@ -1504,6 +1537,7 @@ rb_podcast_manager_add_parsed_feed (RBPodcastManager *pd, RBPodcastChannel *data
        /* insert episodes */
        new_last_post = last_post;
        updated = FALSE;
+       position = 1;
        for (l = data->posts; l != NULL; l = g_list_next (l)) {
                RBPodcastItem *item = (RBPodcastItem *) l->data;
                RhythmDBEntry *post_entry;
@@ -1553,6 +1587,7 @@ rb_podcast_manager_add_parsed_feed (RBPodcastManager *pd, RBPodcastChannel *data
                            item->guid,
                            item->pub_date > 0 ? item->pub_date : data->pub_date,
                            item->duration,
+                           position++,
                            item->filesize);
 
                if (post_entry)
@@ -1623,6 +1658,14 @@ rb_podcast_manager_add_parsed_feed (RBPodcastManager *pd, RBPodcastChannel *data
                        rb_debug ("entry %s is no longer present in the feed and has not been downloaded",
                                  get_remote_location (entry));
                        rhythmdb_entry_delete (db, entry);
+               } else {
+                       GValue v = {0, };
+
+                       /* assign track numbers to remaining entries in the same order */
+                       g_value_init (&v, G_TYPE_ULONG);
+                       g_value_set_ulong (&v, position++);
+                       rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &v);
+                       g_value_unset (&v);
                }
        }
        g_clear_object (&results);
diff --git a/podcast/rb-podcast-manager.h b/podcast/rb-podcast-manager.h
index 28f3f3e81..806be9f75 100644
--- a/podcast/rb-podcast-manager.h
+++ b/podcast/rb-podcast-manager.h
@@ -86,6 +86,7 @@ RhythmDBEntry *         rb_podcast_manager_add_post           (RhythmDB *db,
                                                                 const char *guid,
                                                                 gulong date,
                                                                 gulong duration,
+                                                                gulong position,
                                                                 guint64 filesize);
 
 gboolean               rb_podcast_manager_entry_downloaded     (RhythmDBEntry *entry);
diff --git a/podcast/rb-podcast-source.c b/podcast/rb-podcast-source.c
index 8baf54bae..341c1f77d 100644
--- a/podcast/rb-podcast-source.c
+++ b/podcast/rb-podcast-source.c
@@ -821,6 +821,13 @@ podcast_post_feed_sort_func (RhythmDBEntry *a,
        if (ret != 0)
                return ret;
 
+       /* position in the feed (if available) */
+       a_val = rhythmdb_entry_get_ulong (a, RHYTHMDB_PROP_TRACK_NUMBER);
+       b_val = rhythmdb_entry_get_ulong (b, RHYTHMDB_PROP_TRACK_NUMBER);
+
+       if (a_val != b_val)
+               return (a_val < b_val) ? 1 : -1;
+
        a_val = rhythmdb_entry_get_ulong (a, RHYTHMDB_PROP_POST_TIME);
        b_val = rhythmdb_entry_get_ulong (b, RHYTHMDB_PROP_POST_TIME);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]