Re-done the episode numbering variables to make it possible to store season numbers without a season (for things like xmltv etc...).

This commit is contained in:
Adam Sutton 2012-06-20 13:31:25 +01:00
parent a21f59b28c
commit e8609fc607
4 changed files with 129 additions and 50 deletions

View 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;
@ -580,7 +580,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,

View 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;

125
src/epg.c
View file

@ -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) &&

View file

@ -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 );