From 066b58f6c7f0817288dd88c373087487ebb8681e Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Fri, 8 Jun 2012 22:24:11 +0100 Subject: [PATCH] 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. --- src/dvb/dvb_tables.c | 2 +- src/dvr/dvr.h | 11 ++- src/dvr/dvr_autorec.c | 41 ++++----- src/dvr/dvr_db.c | 155 +++++++++++++++++++++++----------- src/dvr/dvr_rec.c | 3 + src/dvr/mkmux.c | 192 +++++++++++++++--------------------------- src/epg.c | 17 ++-- src/htsp.c | 54 ++++++------ src/webui/extjs.c | 36 +++----- src/webui/simpleui.c | 4 +- src/webui/webui.c | 2 - 11 files changed, 249 insertions(+), 268 deletions(-) diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index af039315..8bf02982 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -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: diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 5f28421c..bcd61a23 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -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); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index c6a7e100..367daecc 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -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 } diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 6da8fd76..43568dba 100644 --- a/src/dvr/dvr_db.c +++ b/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); } /** diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index cb4c9e40..03e57ac9 100755 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -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++) { diff --git a/src/dvr/mkmux.c b/src/dvr/mkmux.c index 2e8cfc67..faaa7477 100644 --- a/src/dvr/mkmux.c +++ b/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); } - /** * */ diff --git a/src/epg.c b/src/epg.c index 2c07d5d9..7c8c514f 100644 --- a/src/epg.c +++ b/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) diff --git a/src/htsp.c b/src/htsp.c index d3f7b036..02de6612 100644 --- a/src/htsp.c +++ b/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) diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 056ad043..55d00e28 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -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); diff --git a/src/webui/simpleui.c b/src/webui/simpleui.c index a4a33020..9d19f08e 100644 --- a/src/webui/simpleui.c +++ b/src/webui/simpleui.c @@ -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, "" @@ -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); diff --git a/src/webui/webui.c b/src/webui/webui.c index e1866731..7d44abac 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -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; }