]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
xmltv: Parse copyright year from xmltv and display in GUI. (#4441).
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Wed, 20 Sep 2017 10:44:10 +0000 (11:44 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 9 Oct 2017 14:15:05 +0000 (16:15 +0200)
src/api/api_epg.c
src/epg.c
src/epg.h
src/epggrab/module/xmltv.c
src/htsp_server.c
src/webui/static/app/epg.js

index c9c5e17ff23b32a1643e170392fc7c2e7a88e612..8a39d6e36e56b240819fc65659ccfc222bf5b2ba 100644 (file)
@@ -185,6 +185,9 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, access_t *perm, const cha
     if (ee->age_rating)
       htsmsg_add_u32(m, "ageRating", ee->age_rating);
 
+    if (ee->copyright_year)
+      htsmsg_add_u32(m, "copyrightYear", ee->copyright_year);
+
     /* Content Type */
     m2 = NULL;
     LIST_FOREACH(eg, &ee->genre, link) {
index 301fd8ed4c95eb3c437a227cca027c66b44c5a14..d6ca56d702686fe4c64d04a4ff819d836887955d 100644 (file)
--- a/src/epg.c
+++ b/src/epg.c
@@ -1030,6 +1030,8 @@ int epg_episode_change_finish
     save |= epg_episode_set_age_rating(episode, 0, NULL);
   if (!(changes & EPG_CHANGED_FIRST_AIRED))
     save |= epg_episode_set_first_aired(episode, 0, NULL);
+  if (!(changes & EPG_CHANGED_COPYRIGHT_YEAR))
+    save |= epg_episode_set_copyright_year(episode, 0, NULL);
   return save;
 }
 
@@ -1216,6 +1218,14 @@ int epg_episode_set_star_rating
                             changed, EPG_CHANGED_STAR_RATING);
 }
 
+int epg_episode_set_copyright_year
+  ( epg_episode_t *episode, uint16_t year, uint32_t *changed )
+{
+  if (!episode) return 0;
+  return _epg_object_set_u16(episode, &episode->copyright_year, year,
+                            changed, EPG_CHANGED_COPYRIGHT_YEAR);
+}
+
 int epg_episode_set_age_rating
   ( epg_episode_t *episode, uint8_t age, uint32_t *changed )
 {
@@ -1354,6 +1364,8 @@ htsmsg_t *epg_episode_serialize ( epg_episode_t *episode )
     htsmsg_add_u32(m, "is_bw", 1);
   if (episode->star_rating)
     htsmsg_add_u32(m, "star_rating", episode->star_rating);
+  if (episode->copyright_year)
+    htsmsg_add_u32(m, "copyright_year", episode->copyright_year);
   if (episode->age_rating)
     htsmsg_add_u32(m, "age_rating", episode->age_rating);
   if (episode->first_aired)
@@ -1428,6 +1440,9 @@ epg_episode_t *epg_episode_deserialize ( htsmsg_t *m, int create, int *save )
   if (!htsmsg_get_u32(m, "star_rating", &u32))
     *save |= epg_episode_set_star_rating(ee, u32, &changes);
 
+  if (!htsmsg_get_u32(m, "copyright_year", &u32))
+    *save |= epg_episode_set_copyright_year(ee, u32, &changes);
+
   if (!htsmsg_get_u32(m, "age_rating", &u32))
     *save |= epg_episode_set_age_rating(ee, u32, &changes);
 
index 299dd28c9d6797c7ac269dda681d13461afdbf68..e775f096491fa912b49bce3ce599b239b6836b3d 100644 (file)
--- a/src/epg.h
+++ b/src/epg.h
@@ -304,6 +304,7 @@ epg_season_t *epg_season_deserialize ( htsmsg_t *m, int create, int *save );
 #define EPG_CHANGED_FIRST_AIRED  (1<<(EPG_CHANGED_SLAST+12))
 #define EPG_CHANGED_BRAND        (1<<(EPG_CHANGED_SLAST+13))
 #define EPG_CHANGED_SEASON       (1<<(EPG_CHANGED_SLAST+14))
+#define EPG_CHANGED_COPYRIGHT_YEAR (1<<(EPG_CHANGED_SLAST+15))
 
 /* Episode numbering object - this is for some back-compat and also
  * to allow episode information to be "collated" into easy to use object
@@ -337,7 +338,11 @@ struct epg_episode
   uint8_t                    star_rating;    ///< Star rating
   uint8_t                    age_rating;     ///< Age certificate
   time_t                     first_aired;    ///< Original airdate
-
+  uint16_t                   copyright_year; ///< xmltv DTD gives a tag "date" (separate to previously-shown/first aired).
+                                             ///< This is the date programme was "finished...probably the copyright date."
+                                             ///< We'll call it copyright_year since words like "complete" and "finished"
+                                             ///< sound too similar to dvr recorded functionality. We'll only store the
+                                             ///< year since we only get year not month and day.
   LIST_ENTRY(epg_episode)    blink;         ///< Brand link
   LIST_ENTRY(epg_episode)    slink;         ///< Season link
   epg_brand_t               *brand;         ///< (Grand-)Parent brand
@@ -409,6 +414,9 @@ int epg_episode_set_first_aired
 int epg_episode_set_star_rating
   ( epg_episode_t *e, uint8_t stars, uint32_t *changed )
   __attribute__((warn_unused_result));
+int epg_episode_set_copyright_year
+  ( epg_episode_t *e, uint16_t stars, uint32_t *changed )
+  __attribute__((warn_unused_result));
 int epg_episode_set_age_rating
   ( epg_episode_t *e, uint8_t age, uint32_t *changed )
   __attribute__((warn_unused_result));
index b96bb669f47c20c9cfbb86d445b88564b8acc250..f02b6c1ea0449d17ea3bb208081be16871a7755e 100644 (file)
@@ -351,6 +351,36 @@ static int _xmltv_parse_previously_shown
   return ret;
 }
 
+/*
+ * Date finished, typically copyright date.
+ */
+static int _xmltv_parse_date_finished
+  ( epg_episode_t *ee,
+    htsmsg_t *tag, uint32_t *changes )
+{
+  if (!ee || !tag) return 0;
+  const char *str = htsmsg_xml_get_cdata_str(tag, "date");
+  if (str) {
+      /* Technically the date could contain information about month
+       * and even second it was completed.  We only want the four
+       * digit year.
+       */
+      const size_t len = strlen(str);
+      if (len >= 4) {
+          char year_buf[32];
+          strncpy(year_buf, str, 4);
+          year_buf[5] = 0;
+          const uint16_t year = atoi(year_buf);
+          /* Sanity check the year before copying it over. */
+          if (year && year > 1800 && year < 2500) {
+              return epg_episode_set_copyright_year(ee, year, changes);
+          }
+      }
+  }
+  return 0;
+}
+
+
 /*
  * Star rating
  *   <star-rating>
@@ -724,6 +754,8 @@ static int _xmltv_parse_programme_tags
 
     save3 |= _xmltv_parse_star_rating(ee, tags, &changes3);
 
+    save3 |= _xmltv_parse_date_finished(ee, tags, &changes3);
+
     save3 |= _xmltv_parse_age_rating(ee, tags, &changes3);
 
     if (icon)
index 667f70dade15e443b432479410da27f1c21848f0..ab14cc37d62ed5e28af8788e6c00c853b18713d2 100644 (file)
@@ -1259,6 +1259,8 @@ htsp_build_event
       htsmsg_add_u32(out, "ageRating", ee->age_rating);
     if (ee->star_rating)
       htsmsg_add_u32(out, "starRating", ee->star_rating);
+    if (ee->copyright_year)
+      htsmsg_add_u32(out, "copyrightYear", ee->copyright_year);
     if (ee->first_aired)
       htsmsg_add_s64(out, "firstAired", ee->first_aired);
     epg_episode_get_epnum(ee, &epnum);
index 09180afc2c56b5923433b8d5532fccda3f82c467..325361a2920ba137a0ebe6ef53f31737b6047bfb 100644 (file)
@@ -106,6 +106,8 @@ tvheadend.epgDetails = function(event) {
     content += '<div class="x-epg-title">' + event.title;
     if (event.subtitle)
         content += "&nbsp;:&nbsp;" + event.subtitle;
+    if (event.copyrightYear)
+        content += "&nbsp;(" + event.copyrightYear + ")";
     content += '</div>';
     if (event.episodeOnscreen)
         content += '<div class="x-epg-title">' + event.episodeOnscreen + '</div>';
@@ -482,6 +484,7 @@ tvheadend.epg = function() {
             { name: 'category' },
             { name: 'keyword' },
             { name: 'ageRating' },
+            { name: 'copyrightYear' },
             { name: 'genre' },
             { name: 'dvrUuid' },
             { name: 'dvrState' },