]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Re-done the episode numbering variables to make it possible to store season numbers...
authorAdam Sutton <dev@adamsutton.me.uk>
Wed, 20 Jun 2012 12:31:25 +0000 (13:31 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Wed, 20 Jun 2012 12:31:25 +0000 (13:31 +0100)
src/dvr/dvr_autorec.c
src/dvr/mkmux.c
src/epg.c
src/epg.h

index c94c78cae3a7f1fa83141805dcebebcb3dbafa90..b18a8321bc032cf900f4a374998330b527cc7d50 100644 (file)
@@ -137,7 +137,7 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e)
 
   // Note: dae_epnum is unset then all values are 0 and this will
   //       always return 1
-  epg_episode_number_full(e->episode, &epnum);
+  epg_episode_get_epnum(e->episode, &epnum);
   if(epg_episode_number_cmp(&dae->dae_epnum, &epnum) < 0)
     return 0;
 
@@ -567,7 +567,7 @@ void dvr_autorec_add_series_link
     atime = (t.tm_hour * 60) + t.tm_min;
   }
   if (cfg->dvr_sl_more_recent) {
-    epg_episode_number_full(ee, &epnum);
+    epg_episode_get_epnum(ee, &epnum);
     epnump = &epnum;
   }
   _dvr_autorec_add(dvr_config_name, event->episode->title,
index faaa7477213bc4062d2d7c71e9123c10c5eabad5..37fbc750658b63aab91cee724747c17c99b74c03 100644 (file)
@@ -501,12 +501,6 @@ _mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc)
   if(ch)
     addtag(q, build_tag_string("TVCHANNEL", ch->ch_name, 0, NULL));
 
-#if TODO_EP_NUMBER_ONSCREEN
-  if(ee && ee->onscreen)
-    addtag(q, build_tag_string("SYNOPSIS", 
-                            ee->onscreen, 0, NULL));
-#endif
-
   if(de && de->de_desc)
     addtag(q, build_tag_string("SUMMARY", de->de_desc, 0, NULL));
   else if (ee && ee->description)
@@ -515,15 +509,20 @@ _mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc)
     addtag(q, build_tag_string("SUMMARY", ee->summary, 0, NULL));
 
   if (ee) {
-    if(ee->number)
-      addtag(q, build_tag_int("PART_NUMBER", ee->number,
+    epg_episode_num_t num;
+    epg_episode_get_epnum(ee, &num);
+    if(num.e_num)
+      addtag(q, build_tag_int("PART_NUMBER", num.e_num,
                               0, NULL));
-    if(ee->season && ee->season->number)
-      addtag(q, build_tag_int("PART_NUMBER", ee->season->number,
+    if(num.s_num)
+      addtag(q, build_tag_int("PART_NUMBER", num.s_num,
                               60, "SEASON"));
-    if(ee->part_number)
-      addtag(q, build_tag_int("PART_NUMBER", ee->part_number,
+    if(num.p_num)
+      addtag(q, build_tag_int("PART_NUMBER", num.p_num,
                               40, "PART"));
+    if (num.text)
+      addtag(q, build_tag_string("SYNOPSIS", 
+                              num.text, 0, NULL));
   }
 
   return q;
index 7f1fec79b229cacf3d30567b849954510409da2a..f62390abaf9d7d691ac9eeb147cbf0a24271ad8e 100644 (file)
--- a/src/epg.c
+++ b/src/epg.c
@@ -80,16 +80,23 @@ static int _season_order ( const void *_a, const void *_b )
   return a->number - b->number;
 }
 
+// Note: this will do nothing with text episode numbering
 static int _episode_order ( const void *_a, const void *_b )
 {
-  int r;
+  int r, as, bs;
   const epg_episode_t *a = (const epg_episode_t*)_a;
   const epg_episode_t *b = (const epg_episode_t*)_b;
-  r = _season_order(a->season, b->season);
+  if (!a) return -1;
+  if (!b) return 1;
+  if (a->season) as = a->season->number;
+  else           as = a->epnum.s_num;
+  if (b->season) bs = b->season->number;
+  else           bs = b->epnum.s_num;
+  r = as - bs;
   if (r) return r;
-  if (!a || !a->number) return 1;
-  if (!b || !b->number) return -1;
-  return a->number - b->number;
+  r = a->epnum.e_num - b->epnum.e_num;
+  if (r) return r;
+  return a->epnum.p_num - b->epnum.p_num;
 }
 
 /* **************************************************************************
@@ -817,6 +824,53 @@ epg_season_t *epg_season_deserialize ( htsmsg_t *m, int create, int *save )
  * Episode
  * *************************************************************************/
 
+static htsmsg_t *epg_episode_num_serialize ( epg_episode_num_t *num )
+{
+  htsmsg_t *m;
+  if (!num) return NULL;
+  m = htsmsg_create_map();
+  if (num->e_num)
+    htsmsg_add_u32(m, "e_num", num->e_num);
+  if (num->e_cnt)
+    htsmsg_add_u32(m, "e_cnt", num->e_cnt);
+  if (num->s_num)
+    htsmsg_add_u32(m, "s_num", num->e_num);
+  if (num->s_cnt)
+    htsmsg_add_u32(m, "s_cnt", num->e_cnt);
+  if (num->p_num)
+    htsmsg_add_u32(m, "p_num", num->e_num);
+  if (num->p_cnt)
+    htsmsg_add_u32(m, "p_cnt", num->e_cnt);
+  if (num->text)
+    htsmsg_add_str(m, "text", num->text);
+  return m;
+}
+
+static epg_episode_num_t *epg_episode_num_deserialize 
+  ( htsmsg_t *m, epg_episode_num_t *num )
+{
+  const char *str;
+  uint32_t u32;
+  if (!m) return NULL;
+  if (!num) num = calloc(1, sizeof(epg_episode_num_t));
+  if (!htsmsg_get_u32(m, "e_num", &u32))
+    num->e_num = u32;
+  if (!htsmsg_get_u32(m, "e_cnt", &u32))
+    num->e_cnt = u32;
+  if (!htsmsg_get_u32(m, "s_num", &u32))
+    num->s_num = u32;
+  if (!htsmsg_get_u32(m, "s_cnt", &u32))
+    num->s_cnt = u32;
+  if (!htsmsg_get_u32(m, "p_num", &u32))
+    num->p_num = u32;
+  if (!htsmsg_get_u32(m, "p_cnt", &u32))
+    num->p_cnt = u32;
+  if ((str = htsmsg_get_str(m, "text")))
+    num->text = strdup(str);
+  
+  return num;
+}
+
 static void _epg_episode_destroy ( epg_object_t *eo )
 {
   epg_episode_t *ee = (epg_episode_t*)eo;
@@ -839,6 +893,7 @@ static void _epg_episode_destroy ( epg_object_t *eo )
   if (ee->description) free(ee->description);
   if (ee->genre)       free(ee->genre);
   if (ee->image)       free(ee->image);
+  if (ee->epnum.text)  free(ee->epnum.text);
   free(ee);
 }
 
@@ -901,8 +956,8 @@ int epg_episode_set_number ( epg_episode_t *episode, uint16_t number )
 {
   int save = 0;
   if ( !episode || !number ) return 0;
-  if ( episode->number != number ) {
-    episode->number = number;
+  if ( episode->epnum.e_num != number ) {
+    episode->epnum.e_num = number;
     _epg_object_set_updated((epg_object_t*)episode);
     save = 1;
   }
@@ -913,19 +968,40 @@ int epg_episode_set_part ( epg_episode_t *episode, uint16_t part, uint16_t count
 {
   int save = 0;
   if ( !episode || !part ) return 0;
-  if ( episode->part_number != part ) {
-    episode->part_number = part;
+  if ( episode->epnum.p_num != part ) {
+    episode->epnum.p_num = part;
     _epg_object_set_updated((epg_object_t*)episode);
     save = 1;
   }
-  if ( count && episode->part_count != count ) {
-    episode->part_count = count;
+  if ( count && episode->epnum.p_cnt != count ) {
+    episode->epnum.p_cnt = count;
     _epg_object_set_updated((epg_object_t*)episode);
     save = 1;
   }
   return save;
 }
 
+int epg_episode_set_epnum ( epg_episode_t *episode, epg_episode_num_t *num )
+{
+  int save = 0;
+  if (!episode || !num || (!num->e_num && !num->text)) return 0;
+  if      ( episode->epnum.e_num != num->e_num ) save = 1;
+  else if ( episode->epnum.e_cnt != num->e_cnt ) save = 1;
+  else if ( episode->epnum.s_num != num->s_num ) save = 1;
+  else if ( episode->epnum.s_cnt != num->s_cnt ) save = 1;
+  else if ( episode->epnum.p_num != num->p_num ) save = 1;
+  else if ( episode->epnum.p_cnt != num->p_cnt ) save = 1;
+  else if ( !episode->epnum.text || 
+            (num->text && strcmp(num->text, episode->epnum.text)) ) save = 1;
+  if (save) {
+    if (episode->epnum.text) free(episode->epnum.text);
+    episode->epnum = *num;
+    if (episode->epnum.text) strdup(episode->epnum.text);
+    save = 1;
+  }
+  return save;
+}
+
 int epg_episode_set_brand ( epg_episode_t *episode, epg_brand_t *brand )
 {
   int save = 0;
@@ -1030,7 +1106,7 @@ size_t epg_episode_number_format
   size_t i = 0;
   if (!episode) return 0;
   epg_episode_num_t num;
-  epg_episode_number_full(episode, &num);
+  epg_episode_get_epnum(episode, &num);
   if ( num.e_num ) {
     if (pre) i += snprintf(&buf[i], len-i, "%s", pre);
     if ( sfmt && num.s_num ) {
@@ -1042,17 +1118,17 @@ size_t epg_episode_number_format
     i += snprintf(&buf[i], len-i, efmt, num.e_num);
     if ( cfmt && num.e_cnt )
       i+= snprintf(&buf[i], len-i, cfmt, num.e_cnt);
+  } else if ( num.text ) {
+    strncpy(buf, num.text, len);
+    i = MAX(strlen(num.text), len);
   }
   return i;
 }
 
-void epg_episode_number_full ( epg_episode_t *ee, epg_episode_num_t *num )
+void epg_episode_get_epnum ( epg_episode_t *ee, epg_episode_num_t *num )
 {
   if (!ee || !num) return;
-  memset(num, 0, sizeof(epg_episode_num_t));
-  num->e_num = ee->number;
-  num->p_num = ee->part_number;
-  num->p_cnt = ee->part_count;
+  *num = ee->epnum;
   if (ee->season) {
     num->e_cnt = ee->season->episode_count;
     num->s_num = ee->season->number;
@@ -1102,12 +1178,7 @@ htsmsg_t *epg_episode_serialize ( epg_episode_t *episode )
     htsmsg_add_str(m, "summary", episode->summary);
   if (episode->description)
     htsmsg_add_str(m, "description", episode->description);
-  if (episode->number)
-    htsmsg_add_u32(m, "number", episode->number);
-  if (episode->part_count && episode->part_count) {
-    htsmsg_add_u32(m, "part-number", episode->part_number);
-    htsmsg_add_u32(m, "part-count", episode->part_count);
-  }
+  htsmsg_add_msg(m, "epnum", epg_episode_num_serialize(&episode->epnum)); 
   if (episode->brand)
     htsmsg_add_str(m, "brand", episode->brand->uri);
   if (episode->season)
@@ -1123,6 +1194,8 @@ epg_episode_t *epg_episode_deserialize ( htsmsg_t *m, int create, int *save )
   epg_brand_t *eb;
   uint32_t u32, u32a;
   const char *str;
+  epg_episode_num_t num;
+  htsmsg_t *sub;
   
   if ( !_epg_object_deserialize(m, *skel) ) return NULL;
   if ( !(ee = epg_episode_find_by_uri((*skel)->uri, create, save)) ) return NULL;
@@ -1135,6 +1208,12 @@ epg_episode_t *epg_episode_deserialize ( htsmsg_t *m, int create, int *save )
     *save |= epg_episode_set_summary(ee, str);
   if ( (str = htsmsg_get_str(m, "description")) )
     *save |= epg_episode_set_description(ee, str);
+  if ( (sub = htsmsg_get_map(m, "epnum")) ) {
+    epg_episode_num_deserialize(sub, &num);
+    *save |= epg_episode_set_epnum(ee, &num);
+    if (num.text) free(num.text);
+  }
+  // Note: retained for compat
   if ( !htsmsg_get_u32(m, "number", &u32) )
     *save |= epg_episode_set_number(ee, u32);
   if ( !htsmsg_get_u32(m, "part-number", &u32) &&
index 2714d344732e14f369ccf63a7e62753f53469c91..a978067cef848f4e11e85c044366d0f1ae33af37 100644 (file)
--- a/src/epg.h
+++ b/src/epg.h
@@ -181,12 +181,13 @@ epg_season_t *epg_season_deserialize ( htsmsg_t *m, int create, int *save );
  */
 typedef struct epg_episode_num
 {
-  uint16_t s_num;  ///< Series number
-  uint16_t s_cnt;  ///< Series count
-  uint16_t e_num;  ///< Episode number
-  uint16_t e_cnt;  ///< Episode count
-  uint16_t p_num;  ///< Part number
-  uint16_t p_cnt;  ///< Part count
+  uint16_t s_num; ///< Series number
+  uint16_t s_cnt; ///< Series count
+  uint16_t e_num; ///< Episode number
+  uint16_t e_cnt; ///< Episode count
+  uint16_t p_num; ///< Part number
+  uint16_t p_cnt; ///< Part count
+  char     *text; ///< Arbitary text description of episode num
 } epg_episode_num_t;
 
 /* Object */
@@ -200,9 +201,8 @@ struct epg_episode
   char                      *description;   ///< An extended description
   uint8_t                   *genre;         ///< Episode genre(s)
   int                        genre_cnt;     ///< Genre count
-  uint16_t                   number;        ///< The episode number
-  uint16_t                   part_number;   ///< For multipart episodes
-  uint16_t                   part_count;    ///< For multipart episodes
+  epg_episode_num_t          epnum;         ///< Episode numbering
+  // Note: do not use epnum directly! use the accessor routine
   char                      *image;         ///< Episode image
 
   // TODO: certification and rating
@@ -231,11 +231,11 @@ int epg_episode_set_description  ( epg_episode_t *e, const char *description )
   __attribute__((warn_unused_result));
 int epg_episode_set_number       ( epg_episode_t *e, uint16_t number )
   __attribute__((warn_unused_result));
-int epg_episode_set_onscreen     ( epg_episode_t *e, const char *onscreen )
-  __attribute__((warn_unused_result));
 int epg_episode_set_part         ( epg_episode_t *e, 
                                    uint16_t number, uint16_t count )
   __attribute__((warn_unused_result));
+int epg_episode_set_epnum        ( epg_episode_t *e, epg_episode_num_t *num )
+  __attribute__((warn_unused_result));
 int epg_episode_set_brand        ( epg_episode_t *e, epg_brand_t *b )
   __attribute__((warn_unused_result));
 int epg_episode_set_season       ( epg_episode_t *e, epg_season_t *s )
@@ -247,6 +247,9 @@ int epg_episode_set_genre_str    ( epg_episode_t *e, const char **s )
 int epg_episode_set_image        ( epg_episode_t *e, const char *i )
   __attribute__((warn_unused_result));
 
+// Note: this does NOT strdup the text field
+void epg_episode_get_epnum
+  ( epg_episode_t *e, epg_episode_num_t *epnum );
 /* EpNum format helper */
 // output string will be:
 // if (episode_num) 
@@ -262,8 +265,6 @@ size_t epg_episode_number_format
     const char *pre,  const char *sfmt,
     const char *sep,  const char *efmt,
     const char *cfmt );
-void epg_episode_number_full
-  ( epg_episode_t *e, epg_episode_num_t *epnum );
 int  epg_episode_number_cmp
   ( epg_episode_num_t *a, epg_episode_num_t *b );