Updated to include compat genre support (more will have to wait), DVR code fully updated to use new EPG code. Updated related code and added useful extra inputs to dvr event creation that should make XBMC devs happy.
This commit is contained in:
parent
f6f8becb2d
commit
066b58f6c7
11 changed files with 249 additions and 268 deletions
|
@ -545,7 +545,7 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
|||
case DVB_DESC_CONTENT:
|
||||
if(dlen >= 2) {
|
||||
if (genre_idx < 10)
|
||||
genre[genre_idx++] = (*ptr) >> 4;
|
||||
genre[genre_idx++] = (*ptr);
|
||||
}
|
||||
break;
|
||||
case DVB_DESC_EXT_EVENT:
|
||||
|
|
|
@ -121,6 +121,7 @@ typedef struct dvr_entry {
|
|||
char *de_ititle; /* Internal title optionally with channelname
|
||||
date and time pre/post/fixed */
|
||||
char *de_desc; /* Description in UTF-8 (from EPG) */
|
||||
uint8_t de_content_type; /* Content type (from EPG) */
|
||||
|
||||
dvr_prio_t de_pri;
|
||||
|
||||
|
@ -190,8 +191,6 @@ typedef struct dvr_autorec_entry {
|
|||
char *dae_creator;
|
||||
char *dae_comment;
|
||||
|
||||
// TODO: EPG linking for proper series recording
|
||||
|
||||
char *dae_title;
|
||||
regex_t dae_title_preg;
|
||||
|
||||
|
@ -238,13 +237,17 @@ const char *dvr_entry_schedstatus(dvr_entry_t *de);
|
|||
void dvr_entry_create_by_autorec(epg_broadcast_t *e, dvr_autorec_entry_t *dae);
|
||||
|
||||
dvr_entry_t *dvr_entry_create_by_event(const char *dvr_config_name,
|
||||
epg_broadcast_t *e, const char *creator,
|
||||
epg_broadcast_t *e,
|
||||
time_t start_extra, time_t stop_extra,
|
||||
const char *creator,
|
||||
dvr_autorec_entry_t *dae,
|
||||
dvr_prio_t pri);
|
||||
|
||||
dvr_entry_t *dvr_entry_create(const char *dvr_config_name,
|
||||
channel_t *ch, time_t start, time_t stop,
|
||||
time_t start_extra, time_t stop_extra,
|
||||
const char *title, const char *description,
|
||||
uint8_t content_type,
|
||||
const char *creator, dvr_autorec_entry_t *dae,
|
||||
dvr_prio_t pri);
|
||||
|
||||
|
@ -262,6 +265,8 @@ void dvr_rec_unsubscribe(dvr_entry_t *de, int stopcode);
|
|||
|
||||
void dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e);
|
||||
|
||||
void dvr_event_updated(epg_broadcast_t *e);
|
||||
|
||||
dvr_entry_t *dvr_entry_find_by_id(int id);
|
||||
|
||||
dvr_entry_t *dvr_entry_find_by_event(epg_broadcast_t *e);
|
||||
|
|
|
@ -92,11 +92,16 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if TODO_GENRE_SUPPORT
|
||||
if(dae->dae_content_type != 0 &&
|
||||
dae->dae_content_type != e->e_content_type)
|
||||
return 0;
|
||||
#endif
|
||||
if(dae->dae_content_type != 0) {
|
||||
int i, ok = 0;
|
||||
for (i = 0; i < e->episode->genre_cnt; i++) {
|
||||
if (e->episode->genre[i] == dae->dae_content_type) {
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) return 0;
|
||||
}
|
||||
|
||||
if(dae->dae_brand)
|
||||
if (!e->episode->brand || dae->dae_brand != e->episode->brand) return 0;
|
||||
|
@ -542,11 +547,7 @@ void dvr_autorec_add_series_link
|
|||
_dvr_autorec_add(dvr_config_name, event->episode->title,
|
||||
event->channel, NULL, 0,
|
||||
event->episode->brand,
|
||||
#ifdef TODO_SEASON_SUPPORT
|
||||
event->episode->season,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
creator, comment);
|
||||
}
|
||||
|
||||
|
@ -563,37 +564,27 @@ dvr_autorec_check_event(epg_broadcast_t *e)
|
|||
TAILQ_FOREACH(dae, &autorec_entries, dae_link)
|
||||
if(autorec_cmp(dae, e)) {
|
||||
existingde = dvr_entry_find_by_event_fuzzy(e);
|
||||
if (existingde != NULL) {
|
||||
tvhlog(LOG_DEBUG, "dvr", "Updating existing DVR entry for %s", e->episode->title);
|
||||
// TODO: do we want to do this?
|
||||
dvr_entry_update(existingde, e->episode->title, e->start, e->stop);
|
||||
} else
|
||||
if (existingde == NULL)
|
||||
dvr_entry_create_by_autorec(e, dae);
|
||||
}
|
||||
// Note: no longer updating event here as it will be done from EPG
|
||||
// anyway
|
||||
}
|
||||
|
||||
void dvr_autorec_check_brand(epg_brand_t *b)
|
||||
{
|
||||
#ifdef TODO_BRAND_UPDATED_SUPPORT
|
||||
epg_objet
|
||||
dvr_autorec_entry_t *dae;
|
||||
TAILQ_FOREACH(dae, &autorec_entries, dae_link) {
|
||||
if (dae->dae_brand == b) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Note: for the most part this will only be relevant should an episode
|
||||
// to which a broadcast is linked suddenly get added to a new brand
|
||||
// this is pretty damn unlikely!
|
||||
#endif
|
||||
}
|
||||
|
||||
void dvr_autorec_check_season(epg_season_t *s)
|
||||
{
|
||||
#ifdef TODO_SEASON_SUPPORT
|
||||
TAILQ_FOREACH(dae, &autorec_entries, dae_link) {
|
||||
if (dae->dae_season == s) {
|
||||
}
|
||||
}
|
||||
// Note: I guess new episodes might have been added, but again its likely
|
||||
// this will already have been picked up by the check_event call
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
155
src/dvr/dvr_db.c
155
src/dvr/dvr_db.c
|
@ -247,7 +247,9 @@ dvr_entry_link(dvr_entry_t *de)
|
|||
static dvr_entry_t *_dvr_entry_create (
|
||||
const char *config_name, epg_broadcast_t *e,
|
||||
channel_t *ch, time_t start, time_t stop,
|
||||
time_t start_extra, time_t stop_extra,
|
||||
const char *title, const char *description,
|
||||
uint8_t content_type,
|
||||
const char *creator, dvr_autorec_entry_t *dae,
|
||||
dvr_prio_t pri)
|
||||
{
|
||||
|
@ -270,11 +272,15 @@ static dvr_entry_t *_dvr_entry_create (
|
|||
de->de_start = start;
|
||||
de->de_stop = stop;
|
||||
de->de_pri = pri;
|
||||
if (ch->ch_dvr_extra_time_pre)
|
||||
if (start_extra)
|
||||
de->de_start_extra = start_extra;
|
||||
else if (ch->ch_dvr_extra_time_pre)
|
||||
de->de_start_extra = ch->ch_dvr_extra_time_pre;
|
||||
else
|
||||
de->de_start_extra = cfg->dvr_extra_time_pre;
|
||||
if (ch->ch_dvr_extra_time_post)
|
||||
if (stop_extra)
|
||||
de->de_stop_extra = stop_extra;
|
||||
else if (ch->ch_dvr_extra_time_post)
|
||||
de->de_stop_extra = ch->ch_dvr_extra_time_post;
|
||||
else
|
||||
de->de_stop_extra = cfg->dvr_extra_time_post;
|
||||
|
@ -282,10 +288,9 @@ static dvr_entry_t *_dvr_entry_create (
|
|||
de->de_creator = strdup(creator);
|
||||
de->de_title = strdup(title);
|
||||
de->de_desc = description ? strdup(description) : NULL;
|
||||
|
||||
#if TODO_GENRE_SUPPORT
|
||||
de->de_content_type = content_type;
|
||||
#endif
|
||||
de->de_bcast = e;
|
||||
if (e) e->_.getref((epg_object_t*)e);
|
||||
|
||||
dvr_entry_link(de);
|
||||
|
||||
|
@ -314,11 +319,15 @@ static dvr_entry_t *_dvr_entry_create (
|
|||
dvr_entry_t *
|
||||
dvr_entry_create(const char *config_name,
|
||||
channel_t *ch, time_t start, time_t stop,
|
||||
const char *title, const char *description,
|
||||
const char *creator, dvr_autorec_entry_t *dae, dvr_prio_t pri)
|
||||
time_t start_extra, time_t stop_extra,
|
||||
const char *title, const char *description,
|
||||
uint8_t content_type,
|
||||
const char *creator, dvr_autorec_entry_t *dae,
|
||||
dvr_prio_t pri)
|
||||
{
|
||||
return _dvr_entry_create(config_name, NULL,
|
||||
ch, start, stop, title, description,
|
||||
ch, start, stop, start_extra, stop_extra,
|
||||
title, description, content_type,
|
||||
creator, dae, pri);
|
||||
}
|
||||
|
||||
|
@ -327,7 +336,9 @@ dvr_entry_create(const char *config_name,
|
|||
*/
|
||||
dvr_entry_t *
|
||||
dvr_entry_create_by_event(const char *config_name,
|
||||
epg_broadcast_t *e, const char *creator,
|
||||
epg_broadcast_t *e,
|
||||
time_t start_extra, time_t stop_extra,
|
||||
const char *creator,
|
||||
dvr_autorec_entry_t *dae, dvr_prio_t pri)
|
||||
{
|
||||
if(!e->channel || !e->episode->title)
|
||||
|
@ -335,9 +346,11 @@ dvr_entry_create_by_event(const char *config_name,
|
|||
|
||||
return _dvr_entry_create(config_name, e,
|
||||
e->channel, e->start, e->stop,
|
||||
start_extra, stop_extra,
|
||||
e->episode->title,
|
||||
e->episode->description ? e->episode->description
|
||||
: e->episode->summary,
|
||||
e->episode->genre_cnt ? e->episode->genre[0] : 0,
|
||||
creator, dae, pri);
|
||||
}
|
||||
|
||||
|
@ -355,7 +368,7 @@ dvr_entry_create_by_autorec(epg_broadcast_t *e, dvr_autorec_entry_t *dae)
|
|||
} else {
|
||||
snprintf(buf, sizeof(buf), "Auto recording");
|
||||
}
|
||||
dvr_entry_create_by_event(dae->dae_config_name, e, buf, dae, dae->dae_pri);
|
||||
dvr_entry_create_by_event(dae->dae_config_name, e, 0, 0, buf, dae, dae->dae_pri);
|
||||
}
|
||||
|
||||
|
||||
|
@ -380,6 +393,7 @@ dvr_entry_dec_ref(dvr_entry_t *de)
|
|||
free(de->de_title);
|
||||
free(de->de_ititle);
|
||||
free(de->de_desc);
|
||||
if(de->de_bcast) de->de_bcast->_.putref((epg_object_t*)de->de_bcast);
|
||||
|
||||
free(de);
|
||||
}
|
||||
|
@ -415,11 +429,10 @@ dvr_entry_remove(dvr_entry_t *de)
|
|||
static void
|
||||
dvr_db_load_one(htsmsg_t *c, int id)
|
||||
{
|
||||
#if TODO
|
||||
dvr_entry_t *de;
|
||||
const char *s, *title, *creator;
|
||||
channel_t *ch;
|
||||
uint32_t start, stop;
|
||||
uint32_t start, stop, bcid;
|
||||
int d;
|
||||
dvr_config_t *cfg;
|
||||
|
||||
|
@ -458,12 +471,18 @@ dvr_db_load_one(htsmsg_t *c, int id)
|
|||
de->de_pri = dvr_pri2val(htsmsg_get_str(c, "pri"));
|
||||
|
||||
if(htsmsg_get_s32(c, "start_extra", &d))
|
||||
de->de_start_extra = cfg->dvr_extra_time_pre;
|
||||
if (ch->ch_dvr_extra_time_pre)
|
||||
de->de_start_extra = ch->ch_dvr_extra_time_pre;
|
||||
else
|
||||
de->de_start_extra = cfg->dvr_extra_time_pre;
|
||||
else
|
||||
de->de_start_extra = d;
|
||||
|
||||
if(htsmsg_get_s32(c, "stop_extra", &d))
|
||||
de->de_stop_extra = cfg->dvr_extra_time_post;
|
||||
if (ch->ch_dvr_extra_time_post)
|
||||
de->de_stop_extra = ch->ch_dvr_extra_time_post;
|
||||
else
|
||||
de->de_stop_extra = cfg->dvr_extra_time_post;
|
||||
else
|
||||
de->de_stop_extra = d;
|
||||
|
||||
|
@ -486,19 +505,13 @@ dvr_db_load_one(htsmsg_t *c, int id)
|
|||
}
|
||||
}
|
||||
|
||||
if(!htsmsg_get_s32(c, "season", &d))
|
||||
de->de_episode.ee_season = d;
|
||||
if(!htsmsg_get_s32(c, "episode", &d))
|
||||
de->de_episode.ee_episode = d;
|
||||
if(!htsmsg_get_s32(c, "part", &d))
|
||||
de->de_episode.ee_part = d;
|
||||
|
||||
de->de_content_type = htsmsg_get_u32_or_default(c, "contenttype", 0);
|
||||
|
||||
tvh_str_set(&de->de_episode.ee_onscreen, htsmsg_get_str(c, "episodename"));
|
||||
if (!htsmsg_get_u32(c, "broadcast", &bcid))
|
||||
de->de_bcast = epg_broadcast_find_by_id(bcid, ch);
|
||||
|
||||
dvr_entry_link(de);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -529,7 +542,6 @@ dvr_db_load(void)
|
|||
static void
|
||||
dvr_entry_save(dvr_entry_t *de)
|
||||
{
|
||||
#if TODO
|
||||
htsmsg_t *m = htsmsg_create_map();
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
@ -566,21 +578,14 @@ dvr_entry_save(dvr_entry_t *de)
|
|||
if(de->de_autorec != NULL)
|
||||
htsmsg_add_str(m, "autorec", de->de_autorec->dae_id);
|
||||
|
||||
if(de->de_episode.ee_season)
|
||||
htsmsg_add_u32(m, "season", de->de_episode.ee_season);
|
||||
if(de->de_episode.ee_episode)
|
||||
htsmsg_add_u32(m, "episode", de->de_episode.ee_episode);
|
||||
if(de->de_episode.ee_part)
|
||||
htsmsg_add_u32(m, "part", de->de_episode.ee_part);
|
||||
if(de->de_episode.ee_onscreen)
|
||||
htsmsg_add_str(m, "episodename", de->de_episode.ee_onscreen);
|
||||
|
||||
if(de->de_content_type)
|
||||
htsmsg_add_u32(m, "contenttype", de->de_content_type);
|
||||
|
||||
if(de->de_bcast)
|
||||
htsmsg_add_u32(m, "broadcast", de->de_bcast->_.id);
|
||||
|
||||
hts_settings_save(m, "dvr/log/%d", de->de_id);
|
||||
htsmsg_destroy(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -595,25 +600,71 @@ dvr_timer_expire(void *aux)
|
|||
|
||||
}
|
||||
|
||||
static dvr_entry_t *_dvr_entry_update
|
||||
( dvr_entry_t *de, epg_broadcast_t *e, const char *de_title,
|
||||
int de_start, int de_stop )
|
||||
{
|
||||
int save = 0;
|
||||
const char *title;
|
||||
int start, stop;
|
||||
|
||||
if (e) {
|
||||
title = e->episode->title;
|
||||
start = e->start;
|
||||
stop = e->stop;
|
||||
} else {
|
||||
title = de_title;
|
||||
start = de_start;
|
||||
stop = de_stop;
|
||||
}
|
||||
|
||||
if (!de->de_title || strcmp(de->de_title, title)) {
|
||||
free(de->de_title);
|
||||
de->de_title = strdup(title);
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if (stop != de->de_stop) {
|
||||
de->de_stop = stop;
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if (start != de->de_start) {
|
||||
de->de_start = start;
|
||||
save = 1;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
if (e->episode->genre_cnt && e->episode->genre_cnt != de->de_content_type) {
|
||||
de->de_content_type = e->episode->genre[0];
|
||||
save = 1;
|
||||
}
|
||||
if (de->de_bcast != e) {
|
||||
de->de_bcast->_.putref((epg_object_t*)de->de_bcast);
|
||||
de->de_bcast = e;
|
||||
e->_.getref((epg_object_t*)e);
|
||||
save = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
dvr_entry_save(de);
|
||||
htsp_dvr_entry_update(de);
|
||||
dvr_entry_notify(de);
|
||||
|
||||
tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\": Updated Timer", de->de_title, de->de_channel->ch_name);
|
||||
}
|
||||
|
||||
return de;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
dvr_entry_t *
|
||||
dvr_entry_update(dvr_entry_t *de, const char* de_title, int de_start, int de_stop)
|
||||
{
|
||||
if(de->de_title) free(de->de_title);
|
||||
|
||||
de->de_title = strdup(de_title);
|
||||
de->de_start = de_start;
|
||||
de->de_stop = de_stop;
|
||||
|
||||
dvr_entry_save(de);
|
||||
htsp_dvr_entry_update(de);
|
||||
dvr_entry_notify(de);
|
||||
|
||||
tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\": Updated Timer", de->de_title, de->de_channel->ch_name);
|
||||
|
||||
return de;
|
||||
return _dvr_entry_update(de, NULL, de_title, de_start, de_stop);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -634,11 +685,15 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e)
|
|||
if (ude == NULL && de->de_sched_state == DVR_SCHEDULED)
|
||||
dvr_entry_cancel(de);
|
||||
else if(new_e->episode->title != NULL)
|
||||
dvr_entry_update(de, new_e->episode->title, new_e->start, new_e->stop);
|
||||
// TODO: need to actually replace the event?
|
||||
_dvr_entry_update(de, new_e, NULL, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void dvr_event_updated ( epg_broadcast_t *e )
|
||||
{
|
||||
dvr_entry_t *de;
|
||||
de = dvr_entry_find_by_event(e);
|
||||
if (de) _dvr_entry_update(de, e, NULL, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -213,6 +213,8 @@ pvr_generate_filename(dvr_entry_t *de)
|
|||
free(chname);
|
||||
}
|
||||
|
||||
// TODO: per-brand, per-season
|
||||
|
||||
/* Append per-title directory */
|
||||
|
||||
if(cfg->dvr_flags & DVR_DIR_PER_TITLE) {
|
||||
|
@ -533,6 +535,7 @@ dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc)
|
|||
fmap['e'] = tvh_strdupa(streaming_code2txt(de->de_last_error));
|
||||
fmap['S'] = start; /* start time, unix epoch */
|
||||
fmap['E'] = stop; /* stop time, unix epoch */
|
||||
// TODO: brand, season
|
||||
|
||||
/* format arguments */
|
||||
for(i = 0; args[i]; i++) {
|
||||
|
|
192
src/dvr/mkmux.c
192
src/dvr/mkmux.c
|
@ -441,7 +441,6 @@ build_tag_string(const char *name, const char *value,
|
|||
/**
|
||||
*
|
||||
*/
|
||||
#if TODO_EP_NUMBER
|
||||
static htsbuf_queue_t *
|
||||
build_tag_int(const char *name, int value,
|
||||
int targettype, const char *targettypename)
|
||||
|
@ -450,7 +449,6 @@ build_tag_int(const char *name, int value,
|
|||
snprintf(str, sizeof(str), "%d", value);
|
||||
return build_tag_string(name, str, targettype, targettypename);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -462,6 +460,74 @@ addtag(htsbuf_queue_t *q, htsbuf_queue_t *t)
|
|||
ebml_append_master(q, 0x7373, t);
|
||||
}
|
||||
|
||||
static htsbuf_queue_t *
|
||||
_mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc)
|
||||
{
|
||||
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
|
||||
char datestr[64];
|
||||
struct tm tm;
|
||||
const char *ctype = NULL;
|
||||
localtime_r(de ? &de->de_start : &ebc->start, &tm);
|
||||
epg_episode_t *ee = NULL;
|
||||
channel_t *ch;
|
||||
|
||||
if (ebc) ee = ebc->episode;
|
||||
else if (de->de_bcast) ee = de->de_bcast->episode;
|
||||
|
||||
if (de) ch = de->de_channel;
|
||||
else ch = ebc->channel;
|
||||
|
||||
snprintf(datestr, sizeof(datestr),
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
|
||||
addtag(q, build_tag_string("DATE_BROADCASTED", datestr, 0, NULL));
|
||||
|
||||
addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL));
|
||||
|
||||
if(de && de->de_content_type) {
|
||||
ctype = epg_genre_get_name(de->de_content_type, 0);
|
||||
} else if (ee && ee->genre_cnt) {
|
||||
ctype = epg_genre_get_name(ee->genre[0], 0);
|
||||
}
|
||||
if(ctype != NULL)
|
||||
addtag(q, build_tag_string("CONTENT_TYPE", ctype, 0, NULL));
|
||||
|
||||
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)
|
||||
addtag(q, build_tag_string("SUMMARY", ee->description, 0, NULL));
|
||||
else if (ee && ee->summary)
|
||||
addtag(q, build_tag_string("SUMMARY", ee->summary, 0, NULL));
|
||||
|
||||
if (ee) {
|
||||
if(ee->number)
|
||||
addtag(q, build_tag_int("PART_NUMBER", ee->number,
|
||||
0, NULL));
|
||||
if(ee->season && ee->season->number)
|
||||
addtag(q, build_tag_int("PART_NUMBER", ee->season->number,
|
||||
60, "SEASON"));
|
||||
if(ee->part_number)
|
||||
addtag(q, build_tag_int("PART_NUMBER", ee->part_number,
|
||||
40, "PART"));
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -469,133 +535,15 @@ addtag(htsbuf_queue_t *q, htsbuf_queue_t *t)
|
|||
static htsbuf_queue_t *
|
||||
mk_build_metadata(const dvr_entry_t *de)
|
||||
{
|
||||
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
|
||||
char datestr[64];
|
||||
struct tm tm;
|
||||
#if TODO_GENRE_SUPPORT
|
||||
const char *ctype;
|
||||
#endif
|
||||
localtime_r(&de->de_start, &tm);
|
||||
|
||||
snprintf(datestr, sizeof(datestr),
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
|
||||
addtag(q, build_tag_string("DATE_BROADCASTED", datestr, 0, NULL));
|
||||
|
||||
addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL));
|
||||
|
||||
|
||||
#if TODO_GENRE_SUPPORT
|
||||
if(de->de_content_type) {
|
||||
ctype = epg_content_group_get_name(de->de_content_type);
|
||||
if(ctype != NULL)
|
||||
addtag(q, build_tag_string("CONTENT_TYPE", ctype, 0, NULL));
|
||||
}
|
||||
#endif
|
||||
|
||||
if(de->de_channel != NULL)
|
||||
addtag(q, build_tag_string("TVCHANNEL", de->de_channel->ch_name, 0, NULL));
|
||||
|
||||
#if TODO_EP_NUMBER
|
||||
if(de->de_episode.ee_onscreen)
|
||||
addtag(q, build_tag_string("SYNOPSIS",
|
||||
de->de_episode.ee_onscreen, 0, NULL));
|
||||
#endif
|
||||
|
||||
if(de->de_desc != NULL)
|
||||
addtag(q, build_tag_string("SUMMARY", de->de_desc, 0, NULL));
|
||||
|
||||
#if TODO_EP_NUMBER
|
||||
if(de->de_episode.ee_season)
|
||||
addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_season,
|
||||
60, "SEASON"));
|
||||
|
||||
if(de->de_episode.ee_episode)
|
||||
addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_episode,
|
||||
0, NULL));
|
||||
|
||||
if(de->de_episode.ee_part)
|
||||
addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_part,
|
||||
40, "PART"));
|
||||
#endif
|
||||
|
||||
return q;
|
||||
return _mk_build_metadata(de, NULL);
|
||||
}
|
||||
|
||||
|
||||
static htsbuf_queue_t *
|
||||
mk_build_metadata2(const epg_broadcast_t *e)
|
||||
{
|
||||
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
|
||||
epg_episode_t *ee = e->episode;
|
||||
char datestr[64];
|
||||
struct tm tm;
|
||||
#if TODO_GENRE_SUPPORT
|
||||
const char *ctype;
|
||||
#endif
|
||||
localtime_r(&e->start, &tm);
|
||||
|
||||
snprintf(datestr, sizeof(datestr),
|
||||
"%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec);
|
||||
|
||||
addtag(q, build_tag_string("DATE_BROADCASTED", datestr, 0, NULL));
|
||||
|
||||
addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL));
|
||||
|
||||
|
||||
#if TODO_GENRE_SUPPORT
|
||||
if(e->e_content_type) {
|
||||
ctype = epg_content_group_get_name(e->e_content_type);
|
||||
if(ctype != NULL)
|
||||
addtag(q, build_tag_string("CONTENT_TYPE", ctype, 0, NULL));
|
||||
}
|
||||
#endif
|
||||
|
||||
if(e->channel != NULL)
|
||||
addtag(q, build_tag_string("TVCHANNEL", e->channel->ch_name, 0, NULL));
|
||||
|
||||
if(ee->title != NULL)
|
||||
addtag(q, build_tag_string("TITLE", ee->title, 0, NULL));
|
||||
|
||||
if(ee->description)
|
||||
addtag(q, build_tag_string("SUMMARY", ee->description, 0, NULL));
|
||||
else if(ee->summary)
|
||||
addtag(q, build_tag_string("SUMMARY", ee->summary, 0, NULL));
|
||||
|
||||
#if TODO_EP_NUMBER
|
||||
if(e->e_episode.ee_onscreen)
|
||||
addtag(q, build_tag_string("SYNOPSIS",
|
||||
e->e_episode.ee_onscreen, 0, NULL));
|
||||
|
||||
if(e->e_episode.ee_season)
|
||||
addtag(q, build_tag_int("PART_NUMBER", e->e_episode.ee_season,
|
||||
60, "SEASON"));
|
||||
|
||||
if(e->e_episode.ee_episode)
|
||||
addtag(q, build_tag_int("PART_NUMBER", e->e_episode.ee_episode,
|
||||
0, NULL));
|
||||
|
||||
if(e->e_episode.ee_part)
|
||||
addtag(q, build_tag_int("PART_NUMBER", e->e_episode.ee_part,
|
||||
40, "PART"));
|
||||
#endif
|
||||
|
||||
return q;
|
||||
return _mk_build_metadata(NULL, e);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
17
src/epg.c
17
src/epg.c
|
@ -1174,6 +1174,7 @@ static void _epg_broadcast_destroy ( epg_object_t *eo )
|
|||
|
||||
static void _epg_broadcast_updated ( epg_object_t *eo )
|
||||
{
|
||||
dvr_event_updated((epg_broadcast_t*)eo);
|
||||
dvr_autorec_check_event((epg_broadcast_t*)eo);
|
||||
}
|
||||
|
||||
|
@ -1480,7 +1481,7 @@ uint8_t epg_genre_find_by_name ( const char *name )
|
|||
for ( a = 1; a < 11; a++ ) {
|
||||
for ( b = 0; b < 16; b++ ) {
|
||||
if (_genre_str_match(name, _epg_genre_names[a][b]))
|
||||
return (a | (b << 4));
|
||||
return (a << 4) | b;
|
||||
}
|
||||
}
|
||||
return 0; // undefined
|
||||
|
@ -1489,8 +1490,8 @@ uint8_t epg_genre_find_by_name ( const char *name )
|
|||
const char *epg_genre_get_name ( uint8_t genre, int full )
|
||||
{
|
||||
int a, b = 0;
|
||||
a = genre & 0xF;
|
||||
if (full) b = (genre >> 4) & 0xF;
|
||||
a = (genre >> 4) & 0xF;
|
||||
if (full) b = (genre & 0xF);
|
||||
return _epg_genre_names[a][b];
|
||||
}
|
||||
|
||||
|
@ -1504,9 +1505,7 @@ static void _eqr_add
|
|||
{
|
||||
/* Ignore */
|
||||
if ( e->stop < start ) return;
|
||||
#if TODO_GENRE_SUPPORT
|
||||
if ( genre && e->genre != genre ) return;
|
||||
#endif
|
||||
if ( genre && e->episode->genre_cnt && e->episode->genre[0] != genre ) return;
|
||||
if ( !e->episode->title ) return;
|
||||
if ( preg && regexec(preg, e->episode->title, 0, NULL, 0) ) return;
|
||||
|
||||
|
@ -1580,10 +1579,8 @@ void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag,
|
|||
{
|
||||
channel_t *ch = channel ? channel_find_by_name(channel, 0, 0) : NULL;
|
||||
channel_tag_t *ct = tag ? channel_tag_find_by_name(tag, 0) : NULL;
|
||||
#if TODO_GENRE_SUPPORT
|
||||
uint8_t ge = genre ? epg_content_group_find_by_name(genre) : 0;
|
||||
#endif
|
||||
epg_query0(eqr, ch, ct, 0, title);
|
||||
uint8_t ge = genre ? epg_genre_find_by_name(genre) : 0;
|
||||
epg_query0(eqr, ch, ct, ge, title);
|
||||
}
|
||||
|
||||
void epg_query_free(epg_query_result_t *eqr)
|
||||
|
|
54
src/htsp.c
54
src/htsp.c
|
@ -526,13 +526,15 @@ htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
static htsmsg_t *
|
||||
htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
|
||||
{
|
||||
#if TODO_DVR
|
||||
htsmsg_t *out;
|
||||
uint32_t eventid;
|
||||
event_t *e;
|
||||
epg_broadcast_t *e;
|
||||
dvr_entry_t *de;
|
||||
dvr_entry_sched_state_t dvr_status;
|
||||
const char *dvr_config_name;
|
||||
time_t start_extra = 0, stop_extra = 0;
|
||||
uint32_t u32;
|
||||
channel_t *ch = NULL;
|
||||
|
||||
if((dvr_config_name = htsmsg_get_str(in, "configName")) == NULL)
|
||||
dvr_config_name = "";
|
||||
|
@ -540,16 +542,25 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
if(htsmsg_get_u32(in, "eventId", &eventid))
|
||||
eventid = -1;
|
||||
|
||||
if ((e = epg_event_find_by_id(eventid)) == NULL)
|
||||
if(!htsmsg_get_u32(in, "startExtra", &u32))
|
||||
start_extra = u32;
|
||||
if(!htsmsg_get_u32(in, "stopExtra", &u32))
|
||||
stop_extra = u32;
|
||||
if(!htsmsg_get_u32(in, "channelId", &u32))
|
||||
ch = channel_find_by_identifier(u32);
|
||||
|
||||
if ((e = epg_broadcast_find_by_id(eventid, ch)) == NULL)
|
||||
{
|
||||
uint32_t iChannelId, iStartTime, iStopTime, iPriority;
|
||||
channel_t *channel;
|
||||
uint32_t iStartTime, iStopTime, iPriority;
|
||||
const char *strTitle = NULL, *strDescription = NULL, *strCreator = NULL;
|
||||
|
||||
// no event, must have a channel
|
||||
if (!ch)
|
||||
return htsp_error("Channel does not exist");
|
||||
|
||||
// no event found with this event id.
|
||||
// check if there is at least a start time, stop time, channel id and title set
|
||||
if (htsmsg_get_u32(in, "channelId", &iChannelId) ||
|
||||
htsmsg_get_u32(in, "start", &iStartTime) ||
|
||||
// check if there is at least a start time, stop time and title set
|
||||
if (htsmsg_get_u32(in, "start", &iStartTime) ||
|
||||
htsmsg_get_u32(in, "stop", &iStopTime) ||
|
||||
(strTitle = htsmsg_get_str(in, "title")) == NULL)
|
||||
{
|
||||
|
@ -557,10 +568,6 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
return htsp_error("Invalid arguments");
|
||||
}
|
||||
|
||||
// invalid channel
|
||||
if ((channel = channel_find_by_identifier(iChannelId)) == NULL)
|
||||
return htsp_error("Channel does not exist");
|
||||
|
||||
// get the optional attributes
|
||||
if (htsmsg_get_u32(in, "priority", &iPriority))
|
||||
iPriority = DVR_PRIO_NORMAL;
|
||||
|
@ -572,12 +579,12 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
strCreator = htsp->htsp_username ? htsp->htsp_username : "anonymous";
|
||||
|
||||
// create the dvr entry
|
||||
de = dvr_entry_create(dvr_config_name, channel, iStartTime, iStopTime, strTitle, strDescription, strCreator, NULL, NULL, 0, iPriority);
|
||||
de = dvr_entry_create(dvr_config_name, ch, iStartTime, iStopTime, start_extra, stop_extra, strTitle, strDescription, 0, strCreator, NULL, iPriority);
|
||||
}
|
||||
else
|
||||
{
|
||||
//create the dvr entry
|
||||
de = dvr_entry_create_by_event(dvr_config_name,e,
|
||||
de = dvr_entry_create_by_event(dvr_config_name,e, start_extra, stop_extra,
|
||||
htsp->htsp_username ?
|
||||
htsp->htsp_username : "anonymous",
|
||||
NULL, DVR_PRIO_NORMAL);
|
||||
|
@ -602,8 +609,6 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
|
|||
break;
|
||||
}
|
||||
return out;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -748,9 +753,7 @@ htsp_build_event(epg_broadcast_t *e)
|
|||
{
|
||||
htsmsg_t *out;
|
||||
epg_broadcast_t *n;
|
||||
#if TODO_DVR
|
||||
dvr_entry_t *de;
|
||||
#endif
|
||||
|
||||
out = htsmsg_create_map();
|
||||
|
||||
|
@ -764,23 +767,14 @@ htsp_build_event(epg_broadcast_t *e)
|
|||
htsmsg_add_str(out, "description", e->episode->description);
|
||||
else if(e->episode->summary != NULL)
|
||||
htsmsg_add_str(out, "description", e->episode->summary);
|
||||
#if TODO_REMOVE_THESE
|
||||
if(e->e_ext_desc != NULL)
|
||||
htsmsg_add_str(out, "ext_desc", e->e_ext_desc);
|
||||
if(e->e_ext_item != NULL)
|
||||
htsmsg_add_str(out, "ext_item", e->e_ext_item);
|
||||
if(e->e_ext_text != NULL)
|
||||
htsmsg_add_str(out, "ext_text", e->e_ext_text);
|
||||
#endif
|
||||
|
||||
if(e->episode->genre)
|
||||
htsmsg_add_u32(out, "contentType", e->episode->genre);
|
||||
// TODO: only supports one entry!
|
||||
if(e->episode->genre_cnt)
|
||||
htsmsg_add_u32(out, "contentType", e->episode->genre[0]);
|
||||
|
||||
#if TODO_DVR
|
||||
if((de = dvr_entry_find_by_event(e)) != NULL) {
|
||||
htsmsg_add_u32(out, "dvrId", de->de_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
n = epg_broadcast_get_next(e);
|
||||
if(n != NULL)
|
||||
|
|
|
@ -414,25 +414,21 @@ static int
|
|||
extjs_ecglist(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
htsbuf_queue_t *hq = &hc->hc_reply;
|
||||
htsmsg_t *out, *array;//TODO:, *c;
|
||||
#if TODO_GENRE
|
||||
htsmsg_t *out, *array, *c;
|
||||
const char *s;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
out = htsmsg_create_map();
|
||||
array = htsmsg_create_list();
|
||||
|
||||
#if TODO_GENRE
|
||||
for(i = 0; i < 16; i++) {
|
||||
if((s = epg_content_group_get_name(i)) == NULL)
|
||||
if((s = epg_genre_get_name(i<<4, 0)) == NULL)
|
||||
continue;
|
||||
|
||||
c = htsmsg_create_map();
|
||||
htsmsg_add_str(c, "name", s);
|
||||
htsmsg_add_msg(array, NULL, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
htsmsg_add_msg(out, "entries", array);
|
||||
|
||||
|
@ -722,10 +718,9 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
|
|||
htsmsg_add_u32(m, "end", e->stop);
|
||||
htsmsg_add_u32(m, "duration", e->stop - e->start);
|
||||
|
||||
#if TODO_INCLUDE_GENRE_SUPORT
|
||||
if((s = epg_content_group_get_name(e->e_content_type)) != NULL)
|
||||
htsmsg_add_str(m, "contentgrp", s);
|
||||
#endif
|
||||
if(ee->genre_cnt)
|
||||
if((s = epg_genre_get_name(ee->genre[0], 0)))
|
||||
htsmsg_add_str(m, "contentgrp", s);
|
||||
|
||||
dvr_entry_t *de;
|
||||
if((de = dvr_entry_find_by_event(e)) != NULL)
|
||||
|
@ -787,7 +782,6 @@ extjs_epgrelated(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
/* Related */
|
||||
} else if (!strcmp(type, "related")) {
|
||||
// TODO: broadcasts?
|
||||
if (ee->brand) {
|
||||
RB_FOREACH(ee2, &ee->brand->episodes, blink) {
|
||||
if (ee2 == ee) continue;
|
||||
|
@ -906,7 +900,8 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
if (!strcmp(op, "recordEvent"))
|
||||
dvr_entry_create_by_event(config_name,
|
||||
e, hc->hc_representative, NULL, DVR_PRIO_NORMAL);
|
||||
e, 0, 0,
|
||||
hc->hc_representative, NULL, DVR_PRIO_NORMAL);
|
||||
else
|
||||
dvr_autorec_add_series_link(config_name, e, hc->hc_representative, "Created from EPG query");
|
||||
|
||||
|
@ -991,25 +986,22 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
|
|||
}
|
||||
|
||||
dvr_entry_create(config_name,
|
||||
ch, start, stop, title, NULL, hc->hc_representative,
|
||||
ch, start, stop, 0, 0, title, NULL, 0,
|
||||
hc->hc_representative,
|
||||
NULL, dvr_pri2val(pri));
|
||||
|
||||
out = htsmsg_create_map();
|
||||
htsmsg_add_u32(out, "success", 1);
|
||||
|
||||
} else if(!strcmp(op, "createAutoRec")) {
|
||||
#if TODO_DVR_AUTOREC
|
||||
const char *cgrp = http_arg_get(&hc->hc_req_args, "contentgrp");
|
||||
|
||||
|
||||
|
||||
dvr_autorec_add(http_arg_get(&hc->hc_req_args, "config_name"),
|
||||
http_arg_get(&hc->hc_req_args, "title"),
|
||||
http_arg_get(&hc->hc_req_args, "channel"),
|
||||
http_arg_get(&hc->hc_req_args, "tag"),
|
||||
cgrp ? epg_content_group_find_by_name(cgrp) : 0,
|
||||
cgrp ? epg_genre_find_by_name(cgrp) : 0,
|
||||
hc->hc_representative, "Created from EPG query");
|
||||
#endif
|
||||
|
||||
out = htsmsg_create_map();
|
||||
htsmsg_add_u32(out, "success", 1);
|
||||
|
@ -1128,6 +1120,7 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque)
|
|||
int start = 0, end, limit, i;
|
||||
const char *s;
|
||||
off_t fsize;
|
||||
char buf[100];
|
||||
|
||||
if((s = http_arg_get(&hc->hc_req_args, "start")) != NULL)
|
||||
start = atoi(s);
|
||||
|
@ -1176,10 +1169,9 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if(de->de_desc != NULL)
|
||||
htsmsg_add_str(m, "description", de->de_desc);
|
||||
|
||||
#if TODO_DVR
|
||||
if(de->de_episode.onscreen)
|
||||
htsmsg_add_str(m, "episode", de->de_episode.onscreen);
|
||||
#endif
|
||||
if (de->de_bcast && de->de_bcast->episode)
|
||||
if (epg_episode_number_format(de->de_bcast->episode, buf, 100, NULL, "Season %d", ".", "Episode %d", "/%d"))
|
||||
htsmsg_add_str(m, "episode", buf);
|
||||
|
||||
htsmsg_add_u32(m, "id", de->de_id);
|
||||
htsmsg_add_u32(m, "start", de->de_start);
|
||||
|
|
|
@ -119,11 +119,9 @@ page_simple(http_connection_t *hc,
|
|||
days[day.tm_wday], day.tm_mday, day.tm_mon + 1);
|
||||
}
|
||||
|
||||
#if TODO_DVR
|
||||
de = dvr_entry_find_by_event(e);
|
||||
rstatus = de != NULL ? val2str(de->de_sched_state,
|
||||
recstatustxt) : NULL;
|
||||
#endif
|
||||
|
||||
htsbuf_qprintf(hq,
|
||||
"<a href=\"/eventinfo/%d\">"
|
||||
|
@ -212,7 +210,7 @@ page_einfo(http_connection_t *hc, const char *remain, void *opaque)
|
|||
de = dvr_entry_find_by_event(e);
|
||||
|
||||
if((http_arg_get(&hc->hc_req_args, "rec")) != NULL) {
|
||||
de = dvr_entry_create_by_event("", e, hc->hc_username ?: "anonymous", NULL,
|
||||
de = dvr_entry_create_by_event("", e, 0, 0, hc->hc_username ?: "anonymous", NULL,
|
||||
DVR_PRIO_NORMAL);
|
||||
} else if(de != NULL && (http_arg_get(&hc->hc_req_args, "cancel")) != NULL) {
|
||||
de = dvr_entry_cancel(de);
|
||||
|
|
|
@ -185,9 +185,7 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, th_subscription_t
|
|||
|
||||
if(e && event_id != e->_.id) {
|
||||
event_id = e->_.id;
|
||||
#if TODO_EVENT
|
||||
run = !mk_mux_append_meta(mkm, e);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue