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