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:
parent
a21f59b28c
commit
e8609fc607
4 changed files with 129 additions and 50 deletions
|
@ -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,
|
||||
|
|
|
@ -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
125
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) &&
|
||||
|
|
27
src/epg.h
27
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 );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue