From: Jaroslav Kysela Date: Fri, 12 Jan 2018 09:11:15 +0000 (+0100) Subject: DVR: add code for the summary field, fixes #4816 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=10e3db3726124515711b1e36f26b7c2feb45fced;p=thirdparty%2Ftvheadend.git DVR: add code for the summary field, fixes #4816 --- diff --git a/docs/property/pathname.md b/docs/property/pathname.md index be6940dec..2cfea0ab8 100644 --- a/docs/property/pathname.md +++ b/docs/property/pathname.md @@ -6,8 +6,10 @@ Format | Description | Example :--------:|--------------------------------------------------|-------- `$t$n.$x` | Default format (title, unique number, extension) | Tennis - Wimbledon-1.mkv -`$s` | Event subtitle name | Sport `$t` | Event title name | Tennis - Wimbledon +`$s` | Event subtitle name or summary text | Live Tennis Broadcast from Wimbledon +`$u` | Event subtitle name | Tennis +`$m` | Event summary text | Live Tennis Broadcast from Wimbledon `$e` | Event episode name | S02-E06 `$c` | Channel name | SkySport `$g` | Content type | Movie : Science fiction diff --git a/docs/property/postprocessor.md b/docs/property/postprocessor.md index e41621081..a1b2b98d6 100644 --- a/docs/property/postprocessor.md +++ b/docs/property/postprocessor.md @@ -14,7 +14,9 @@ Format | Description | Example value `%O` | Owner of this recording | user `%C` | Who created this recording | user `%t` | Program title | News -`%s` | Program subtitle | Afternoon +`%s` | Program subtitle or summary | Afternoon fast news +`%u` | Program subtitle | Afternoon +`%m` | Program summary | Afternoon fast news `%p` | Program episode | S02.E07 `%d` | Program description | News and stories… `%g` | Program content type | Current affairs diff --git a/docs/property/preprocessor.md b/docs/property/preprocessor.md index 13463944f..aea2a582e 100644 --- a/docs/property/preprocessor.md +++ b/docs/property/preprocessor.md @@ -12,7 +12,9 @@ Format | Description | Example value `%O` | Owner of this recording | user `%C` | Who created this recording | user `%t` | Program title | News -`%s` | Program subtitle | Afternoon +`%s` | Program subtitle or summary | Afternoon fast news +`%u` | Program subtitle | Afternoon +`%m` | Program summary | Afternoon fast news `%p` | Program episode | S02.E07 `%d` | Program description | News and stories… `%S` | Start time stamp of recording, UNIX epoch | 1224421200 diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 33a54b4d7..412e2585e 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -212,6 +212,7 @@ typedef struct dvr_entry { directory setting from the configuration */ lang_str_t *de_title; /* Title in UTF-8 (from EPG) */ lang_str_t *de_subtitle; /* Subtitle in UTF-8 (from EPG) */ + lang_str_t *de_summary; /* Summary in UTF-8 (from EPG) */ lang_str_t *de_desc; /* Description in UTF-8 (from EPG) */ uint32_t de_content_type; /* Content type (from EPG) (only code) */ uint16_t de_copyright_year; /* Copyright year (from EPG) */ @@ -555,7 +556,7 @@ dvr_entry_t * dvr_entry_update( dvr_entry_t *de, int enabled, const char *dvr_config_uuid, channel_t *ch, const char *title, const char *subtitle, - const char *desc, const char *lang, + const char *summary, const char *desc, const char *lang, time_t start, time_t stop, time_t start_extra, time_t stop_extra, dvr_prio_t pri, int retention, int removal, diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 986e4cf71..1c7978259 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -218,11 +218,14 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) } if (e->category) { - if (dae->dae_cat1 && *dae->dae_cat1 && !string_list_contains_string(e->category, dae->dae_cat1)) + if (dae->dae_cat1 && *dae->dae_cat1 && + !string_list_contains_string(e->category, dae->dae_cat1)) return 0; - if (dae->dae_cat2 && *dae->dae_cat2 && !string_list_contains_string(e->category, dae->dae_cat2)) + if (dae->dae_cat2 && *dae->dae_cat2 && + !string_list_contains_string(e->category, dae->dae_cat2)) return 0; - if (dae->dae_cat3 && *dae->dae_cat3 && !string_list_contains_string(e->category, dae->dae_cat3)) + if (dae->dae_cat3 && *dae->dae_cat3 && + !string_list_contains_string(e->category, dae->dae_cat3)) return 0; } else if ((dae->dae_cat1 && *dae->dae_cat1) || (dae->dae_cat2 && *dae->dae_cat2) || diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 203f1b0de..d52453a4f 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -963,6 +963,7 @@ dvr_entry_create_from_htsmsg(htsmsg_t *conf, epg_broadcast_t *e) time_t t; char ubuf[UUID_HEX_SIZE]; epg_genre_t *genre; + int summary_used = 0; if (e) { htsmsg_add_u32(conf, "broadcast", e->id); @@ -980,10 +981,15 @@ dvr_entry_create_from_htsmsg(htsmsg_t *conf, epg_broadcast_t *e) lang_str_serialize(e->description, conf, "description"); else if (e->episode && e->episode->description) lang_str_serialize(e->episode->description, conf, "description"); - else if (e->summary) + else if (e->summary) { lang_str_serialize(e->summary, conf, "description"); - else if (e->episode && e->episode->summary) + summary_used = 1; + } else if (e->episode && e->episode->summary) lang_str_serialize(e->episode->summary, conf, "description"); + if (!summary_used && e->summary) + lang_str_serialize(e->summary, conf, "summary"); + else if (e->episode && e->episode->summary) + lang_str_serialize(e->episode->summary, conf, "summary"); if (e->episode && (s = dvr_entry_get_episode(e, tbuf, sizeof(tbuf)))) htsmsg_add_str(conf, "episode", s); if (e->episode && e->episode->copyright_year) @@ -1731,8 +1737,9 @@ dvr_entry_dec_ref(dvr_entry_t *de) free(de->de_creator); free(de->de_comment); if (de->de_title) lang_str_destroy(de->de_title); - if (de->de_subtitle) lang_str_destroy(de->de_subtitle); - if (de->de_desc) lang_str_destroy(de->de_desc); + if (de->de_subtitle) lang_str_destroy(de->de_subtitle); + if (de->de_summary) lang_str_destroy(de->de_summary); + if (de->de_desc) lang_str_destroy(de->de_desc); dvr_entry_assign_broadcast(de, NULL); free(de->de_channel_name); free(de->de_episode); @@ -1907,7 +1914,8 @@ static char *dvr_updated_str(char *buf, size_t buflen, int flags) static dvr_entry_t *_dvr_entry_update ( dvr_entry_t *de, int enabled, const char *dvr_config_uuid, epg_broadcast_t *e, channel_t *ch, - const char *title, const char *subtitle, const char *desc, + const char *title, const char *subtitle, + const char *summary, const char *desc, const char *lang, time_t start, time_t stop, time_t start_extra, time_t stop_extra, dvr_prio_t pri, int retention, int removal, @@ -1970,6 +1978,9 @@ static dvr_entry_t *_dvr_entry_update if (subtitle) { save |= lang_str_set(&de->de_subtitle, subtitle, lang) ? DVR_UPDATED_SUBTITLE : 0; } + if (summary) { + save |= lang_str_set(&de->de_summary, summary, lang) ? DVR_UPDATED_SUMMARY : 0; + } } goto dosave; } @@ -2038,6 +2049,13 @@ static dvr_entry_t *_dvr_entry_update save |= lang_str_set(&de->de_subtitle, subtitle, lang) ? DVR_UPDATED_SUBTITLE : 0; } + /* Summary */ + if (e && e->episode && e->episode->summary) { + save |= lang_str_set2(&de->de_summary, e->episode->summary) ? DVR_UPDATED_SUMMARY : 0; + } else if (summary) { + save |= lang_str_set(&de->de_summary, summary, lang) ? DVR_UPDATED_SUMMARY : 0; + } + /* EID */ if (e && e->dvb_eid != de->de_dvb_eid) { de->de_dvb_eid = e->dvb_eid; @@ -2109,13 +2127,13 @@ dvr_entry_update ( dvr_entry_t *de, int enabled, const char *dvr_config_uuid, channel_t *ch, const char *title, const char *subtitle, - const char *desc, const char *lang, + const char *summary, const char *desc, const char *lang, time_t start, time_t stop, time_t start_extra, time_t stop_extra, dvr_prio_t pri, int retention, int removal, int playcount, int playposition ) { return _dvr_entry_update(de, enabled, dvr_config_uuid, - NULL, ch, title, subtitle, desc, lang, + NULL, ch, title, subtitle, summary, desc, lang, start, stop, start_extra, stop_extra, pri, retention, removal, playcount, playposition); } @@ -2171,7 +2189,7 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) gmtime2local(e2->start, t1buf, sizeof(t1buf)), gmtime2local(e2->stop, t2buf, sizeof(t2buf))); _dvr_entry_update(de, -1, NULL, e2, NULL, NULL, NULL, NULL, NULL, - 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1); + NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1); return; } } @@ -2211,7 +2229,7 @@ void dvr_event_updated(epg_broadcast_t *e) return; LIST_FOREACH(de, &e->dvr_entries, de_bcast_link) { assert(de->de_bcast == e); - _dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL, + _dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1); found++; } @@ -2226,7 +2244,7 @@ void dvr_event_updated(epg_broadcast_t *e) "link to event %s on %s", epg_broadcast_get_title(e, NULL), channel_get_name(e->channel, channel_blank_name)); - _dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL, + _dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1); break; } @@ -3126,6 +3144,35 @@ dvr_entry_class_disp_subtitle_get(void *o) return &prop_ptr; } +static int +dvr_entry_class_disp_summary_set(void *o, const void *v) +{ + dvr_entry_t *de = (dvr_entry_t *)o; + const char *lang = idnode_lang(o); + const char *s = ""; + v = tvh_str_default(v, "UnknownSummary"); + if (de->de_subtitle) + s = lang_str_get(de->de_summary, lang); + if (strcmp(s, v)) { + lang_str_set(&de->de_summary, v, lang); + return 1; + } + return 0; +} + +static const void * +dvr_entry_class_disp_summary_get(void *o) +{ + dvr_entry_t *de = (dvr_entry_t *)o; + if (de->de_summary) + prop_ptr = lang_str_get(de->de_summary, idnode_lang(o)); + else + prop_ptr = NULL; + if (prop_ptr == NULL) + prop_ptr = ""; + return &prop_ptr; +} + static const void * dvr_entry_class_disp_description_get(void *o) { @@ -3547,6 +3594,23 @@ const idclass_t dvr_entry_class = { .set = dvr_entry_class_disp_subtitle_set, .opts = PO_NOSAVE, }, + { + .type = PT_LANGSTR, + .id = "summary", + .name = N_("Summary"), + .desc = N_("Summary of the program (if any)."), + .off = offsetof(dvr_entry_t, de_summary), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "disp_summary", + .name = N_("Summary"), + .desc = N_("Summary of the program (if any) (display only)."), + .get = dvr_entry_class_disp_summary_get, + .set = dvr_entry_class_disp_summary_set, + .opts = PO_NOSAVE, + }, { .type = PT_LANGSTR, .id = "description", diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 96ec2943f..ad05a3678 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -330,12 +330,27 @@ dvr_sub_title(const char *id, const char *fmt, const void *aux, char *tmp, size_ return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_title, NULL), tmp, tmplen); } +static const char * +dvr_sub_subtitle_or_summary(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) +{ + const dvr_entry_t *de = aux; + const char *s = lang_str_get(de->de_subtitle, NULL); + if (s == NULL) s = lang_str_get(de->de_summary, NULL); + return dvr_do_prefix(id, fmt, s, tmp, tmplen); +} + static const char * dvr_sub_subtitle(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) { return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_subtitle, NULL), tmp, tmplen); } +static const char * +dvr_sub_summary(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) +{ + return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_summary, NULL), tmp, tmplen); +} + static const char * dvr_sub_description(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) { @@ -368,8 +383,19 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char *tmp = 0; const char *title = lang_str_get(de->de_title, NULL); const char *subtitle = lang_str_get(de->de_subtitle, NULL); + const char *summary = lang_str_get(de->de_summary, NULL); const char *desc = lang_str_get(de->de_desc, NULL); + /* Pick summary as subtitle if appropriate */ + if (summary) { + if (subtitle == NULL) { + subtitle = summary; + } else if (strlen(subtitle) < strlen(summary)) { + if (strlen(subtitle) < 10) + subtitle = summary; + } + } + if (subtitle && desc && strcmp(subtitle, desc) == 0) { /* Subtitle and description are identical so assume they are from * bad OTA EIT. Some OTA EIT often has a (long) summary which is @@ -379,16 +405,16 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char subtitle = NULL; } - char title_buf[512] = { 0 }; - char subtitle_buf[512] = { 0 }; + char *title_buf = title ? alloca(strlen(title) + 1) : NULL; + char *subtitle_buf = subtitle ? alloca(strlen(subtitle) + 1) : NULL; /* Copy a cleaned version in to our buffers. * Since dvr_clean_directory_separator _can_ modify source if source!=dest * it means we have to remove our const when we call it. */ if (title) - dvr_clean_directory_separator((char*)title, title_buf, sizeof title_buf); + dvr_clean_directory_separator((char*)title, title_buf, sizeof(title_buf)); if (subtitle) - dvr_clean_directory_separator((char*)subtitle, subtitle_buf, sizeof subtitle_buf); + dvr_clean_directory_separator((char*)subtitle, subtitle_buf, sizeof(subtitle_buf)); int is_movie = 0; /* Override options on the format tag. This is useful because my OTA @@ -402,9 +428,7 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char if (de->de_bcast && de->de_bcast->category) { /* We've parsed categories from xmltv. So check if it has the movie category. */ is_movie = - string_list_contains_string(de->de_bcast->category, "Movie") || string_list_contains_string(de->de_bcast->category, "movie") || - string_list_contains_string(de->de_bcast->category, "Film") || string_list_contains_string(de->de_bcast->category, "film"); } else { /* No xmltv categories parsed. So have to use less-accurate genre instead. */ @@ -625,13 +649,27 @@ static htsstr_substitute_t dvr_subs_entry[] = { { .id = "?.t", .getval = dvr_sub_title }, { .id = "?,t", .getval = dvr_sub_title }, { .id = "?;t", .getval = dvr_sub_title }, - { .id = "?s", .getval = dvr_sub_subtitle }, - { .id = "? s", .getval = dvr_sub_subtitle }, - { .id = "?-s", .getval = dvr_sub_subtitle }, - { .id = "?_s", .getval = dvr_sub_subtitle }, - { .id = "?.s", .getval = dvr_sub_subtitle }, - { .id = "?,s", .getval = dvr_sub_subtitle }, - { .id = "?;s", .getval = dvr_sub_subtitle }, + { .id = "?s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "? s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "?-s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "?_s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "?.s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "?,s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "?;s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "?u", .getval = dvr_sub_subtitle }, + { .id = "? u", .getval = dvr_sub_subtitle }, + { .id = "?-u", .getval = dvr_sub_subtitle }, + { .id = "?_u", .getval = dvr_sub_subtitle }, + { .id = "?.u", .getval = dvr_sub_subtitle }, + { .id = "?,u", .getval = dvr_sub_subtitle }, + { .id = "?;u", .getval = dvr_sub_subtitle }, + { .id = "?m", .getval = dvr_sub_summary }, + { .id = "? m", .getval = dvr_sub_summary }, + { .id = "?-m", .getval = dvr_sub_summary }, + { .id = "?_m", .getval = dvr_sub_summary }, + { .id = "?.m", .getval = dvr_sub_summary }, + { .id = "?,m", .getval = dvr_sub_summary }, + { .id = "?;m", .getval = dvr_sub_summary }, { .id = "e", .getval = dvr_sub_episode }, { .id = " e", .getval = dvr_sub_episode }, { .id = "-e", .getval = dvr_sub_episode }, @@ -765,7 +803,9 @@ static htsstr_substitute_t dvr_subs_tally[] = { static htsstr_substitute_t dvr_subs_postproc_entry[] = { { .id = "t", .getval = dvr_sub_title }, - { .id = "s", .getval = dvr_sub_subtitle }, + { .id = "s", .getval = dvr_sub_subtitle_or_summary }, + { .id = "u", .getval = dvr_sub_subtitle }, + { .id = "m", .getval = dvr_sub_summary }, { .id = "p", .getval = dvr_sub_episode }, { .id = "d", .getval = dvr_sub_description }, { .id = "g", .getval = dvr_sub_genre }, diff --git a/src/htsp_server.c b/src/htsp_server.c index 991b74cad..12bb2e99e 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -1955,6 +1955,9 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) s = htsmsg_get_str(in, "subtitle"); if (s) lang_str_serialize_one(conf, "subtitle", s, lang); + s = htsmsg_get_str(in, "summary"); + if (s) + lang_str_serialize_one(conf, "summary", s, lang); s = htsmsg_get_str(in, "description"); if (s) lang_str_serialize_one(conf, "description", s, lang); @@ -2024,7 +2027,7 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) uint32_t u32; dvr_entry_t *de; time_t start, stop, start_extra, stop_extra, priority; - const char *dvr_config_name, *title, *subtitle, *desc, *lang; + const char *dvr_config_name, *title, *subtitle, *summary, *desc, *lang; channel_t *channel = NULL; int enabled, retention, removal, playcount = -1, playposition = -1; @@ -2052,6 +2055,7 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) priority = htsmsg_get_u32_or_default(in, "priority", DVR_PRIO_NOTSET); title = htsmsg_get_str(in, "title"); subtitle = htsmsg_get_str(in, "subtitle"); + summary = htsmsg_get_str(in, "summary"); desc = htsmsg_get_str(in, "description"); lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language; @@ -2080,7 +2084,7 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) playposition = u32 > INT_MAX ? INT_MAX : u32; de = dvr_entry_update(de, enabled, dvr_config_name, channel, title, subtitle, - desc, lang, start, stop, start_extra, stop_extra, + summary, desc, lang, start, stop, start_extra, stop_extra, priority, retention, removal, playcount, playposition); return htsp_success(); diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index c56f6526f..5f75f8e3a 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -12,24 +12,25 @@ tvheadend.dvrDetails = function(uuid) { var chicon = params[0].value; var title = params[1].value; var subtitle = params[2].value; - var episode = params[3].value; - var start_real = params[4].value; - var stop_real = params[5].value; - var duration = params[6].value; - var desc = params[7].value; - var status = params[8].value; - var filesize = params[9].value; - var comment = params[10].value; - var duplicate = params[11].value; - var autorec_caption = params[12].value; - var timerec_caption = params[13].value; - var image = params[14].value; - var copyright_year = params[15].value; - var credits = params[16].value; - var keyword = params[17].value; - var category = params[18].value; - var first_aired = params[19].value; - var genre = params[20].value; + var summary = params[3].value; + var episode = params[4].value; + var start_real = params[5].value; + var stop_real = params[6].value; + var duration = params[7].value; + var desc = params[8].value; + var status = params[9].value; + var filesize = params[10].value; + var comment = params[11].value; + var duplicate = params[12].value; + var autorec_caption = params[13].value; + var timerec_caption = params[14].value; + var image = params[15].value; + var copyright_year = params[16].value; + var credits = params[17].value; + var keyword = params[18].value; + var category = params[19].value; + var first_aired = params[20].value; + var genre = params[21].value; var content = ''; var but; @@ -75,6 +76,8 @@ tvheadend.dvrDetails = function(uuid) { } content += '
'; + if (summary && (!subtitle || subtitle != summary)) + content += '
' + summary + '
'; if (desc) { content += '
' + desc + '
'; content += '
'; @@ -141,7 +144,7 @@ tvheadend.dvrDetails = function(uuid) { url: 'api/idnode/load', params: { uuid: uuid, - list: 'channel_icon,disp_title,disp_subtitle,episode,start_real,stop_real,' + + list: 'channel_icon,disp_title,disp_subtitle,disp_summary,episode,start_real,stop_real,' + 'duration,disp_description,status,filesize,comment,duplicate,' + 'autorec_caption,timerec_caption,image,copyright_year,credits,keyword,category,' + 'first_aired,genre', @@ -416,10 +419,8 @@ tvheadend.dvr_upcoming = function(panel, index) { } }, del: true, - list: 'category,enabled,duplicate,disp_title,disp_subtitle,episode,channel,' + - 'image,' + - 'copyright_year,' + - 'start_real,stop_real,duration,pri,filesize,' + + list: 'category,enabled,duplicate,disp_title,disp_subtitle,disp_summary,episode,' + + 'channel,image,copyright_year,start_real,stop_real,duration,pri,filesize,' + 'sched_status,errors,data_errors,config_name,owner,creator,comment,genre', columns: { disp_title: { @@ -428,6 +429,9 @@ tvheadend.dvr_upcoming = function(panel, index) { disp_subtitle: { renderer: tvheadend.displayWithDuplicateRenderer() }, + disp_summary: { + renderer: tvheadend.displayWithDuplicateRenderer() + }, filesize: { renderer: tvheadend.filesizeRenderer() }, @@ -593,9 +597,8 @@ tvheadend.dvr_finished = function(panel, index) { } }, del: false, - list: 'disp_title,disp_subtitle,episode,channelname,' + - 'start_real,stop_real,duration,filesize,' + - 'copyright_year,' + + list: 'disp_title,disp_subtitle,disp_summary,episode,channelname,' + + 'start_real,stop_real,duration,filesize,copyright_year,' + 'sched_status,errors,data_errors,playcount,url,config_name,owner,creator,comment,', columns: { disp_title: { @@ -710,10 +713,8 @@ tvheadend.dvr_failed = function(panel, index) { del: true, delquestion: _('Do you really want to delete the selected recordings?') + '

' + _('The associated file will be removed from storage.'), - list: 'disp_title,disp_subtitle,episode,channelname,' + - 'image,' + - 'copyright_year,' + - 'start_real,stop_real,duration,filesize,status,' + + list: 'disp_title,disp_subtitle,disp_summary,episode,channelname,' + + 'image,copyright_year,start_real,stop_real,duration,filesize,status,' + 'sched_status,errors,data_errors,playcount,url,config_name,owner,creator,comment', columns: { disp_title: { @@ -787,10 +788,8 @@ tvheadend.dvr_removed = function(panel, index) { uilevel: 'expert', edit: { params: { list: tvheadend.admin ? "retention,owner,comment" : "retention,comment" } }, del: true, - list: 'disp_title,disp_subtitle,episode,channelname,' + - 'image,' + - 'copyright_year,' + - 'start_real,stop_real,duration,status,' + + list: 'disp_title,disp_subtitle,disp_summary,episode,channelname,image,' + + 'copyright_year,start_real,stop_real,duration,status,' + 'sched_status,errors,data_errors,url,config_name,owner,creator,comment', columns: { disp_title: {