From bb26496186f9dd0318818fe28cce2a04f9b6b23c Mon Sep 17 00:00:00 2001 From: Johan Rehnberg Date: Sun, 13 Oct 2013 20:15:15 +0200 Subject: [PATCH 1/3] programs with non zero and equal episode numbers are considered duplicates --- src/dvr/dvr_db.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index fd54d3a0..2129f232 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -427,11 +427,23 @@ dvr_entry_create_by_event(const char *config_name, creator, dae, pri); } +/** + * Considered a duplicate if it has episode numbers and it is equal to an existing recording + */ static int _dvr_duplicate_event ( epg_broadcast_t *e ) { dvr_entry_t *de; + epg_episode_num_t empty_epnum; + + memset(&empty_epnum, 0, sizeof(empty_epnum)); + if (epg_episode_number_cmp(&empty_epnum, &e->episode->epnum) == 0) + return 0; + LIST_FOREACH(de, &dvrentries, de_global_link) { - if (de->de_bcast && (de->de_bcast->episode == e->episode)) return 1; + if (de->de_bcast && epg_episode_number_cmp(&de->de_bcast->episode->epnum, &e->episode->epnum) == 0) + { + return 1; + } } return 0; } From 2450af0f43af41912fdd394be5622f77e5d531ec Mon Sep 17 00:00:00 2001 From: Johan Rehnberg Date: Sun, 27 Oct 2013 10:43:34 +0100 Subject: [PATCH 2/3] Restore original duplicate check and include title in extended check. --- src/dvr/dvr_db.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 2129f232..17949a73 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -428,21 +428,33 @@ dvr_entry_create_by_event(const char *config_name, } /** - * Considered a duplicate if it has episode numbers and it is equal to an existing recording + * */ static int _dvr_duplicate_event ( epg_broadcast_t *e ) { dvr_entry_t *de; epg_episode_num_t empty_epnum; + int has_epnum = 1; + /* do not do episode duplicate check below if no episode number */ memset(&empty_epnum, 0, sizeof(empty_epnum)); if (epg_episode_number_cmp(&empty_epnum, &e->episode->epnum) == 0) - return 0; + has_epnum = 0; LIST_FOREACH(de, &dvrentries, de_global_link) { - if (de->de_bcast && epg_episode_number_cmp(&de->de_bcast->episode->epnum, &e->episode->epnum) == 0) - { - return 1; + if (de->de_bcast) { + if (de->de_bcast->episode == e->episode) return 1; + + if (has_epnum) { + const char* de_title = lang_str_get(de->de_bcast->episode->title, NULL); + const char* e_title = lang_str_get(e->episode->title, NULL); + + /* duplicate if title and episode match */ + if (de_title && e_title && strcmp(de_title, e_title) == 0 + && epg_episode_number_cmp(&de->de_bcast->episode->epnum, &e->episode->epnum) == 0) { + return 1; + } + } } } return 0; From f2b049c8a4c53d0182ed1aa24ef40c4135e5bf1a Mon Sep 17 00:00:00 2001 From: Johan Rehnberg Date: Sun, 27 Oct 2013 12:19:09 +0100 Subject: [PATCH 3/3] Make episode duplicate detection configurable. --- docs/html/config_dvr.html | 4 ++++ src/dvr/dvr.h | 1 + src/dvr/dvr_db.c | 23 ++++++++++++++++------- src/webui/extjs.c | 3 +++ src/webui/static/app/dvr.js | 5 ++++- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/docs/html/config_dvr.html b/docs/html/config_dvr.html index 2b72e8a0..354b3297 100644 --- a/docs/html/config_dvr.html +++ b/docs/html/config_dvr.html @@ -78,6 +78,10 @@
If checked, commercials will be dropped from the recordings. At the moment, commercial detection only works for the swedish channel TV4. +
Episode duplicate detection +
If checked, broadcasts with matching title and matching non-zero episode number + are considered duplicates. +
Post-processor command
Command to run after finishing a recording. The command will be run in background and is executed even if a recording is aborted diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 59d285cc..a945e8f4 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -66,6 +66,7 @@ extern struct dvr_entry_list dvrentries; #define DVR_CLEAN_TITLE 0x100 #define DVR_TAG_FILES 0x200 #define DVR_SKIP_COMMERCIALS 0x400 +#define DVR_EPISODE_DUPLICATE_DETECTION 0x800 typedef enum { DVR_PRIO_IMPORTANT, diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 17949a73..c6168d87 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -436,7 +436,7 @@ static int _dvr_duplicate_event ( epg_broadcast_t *e ) epg_episode_num_t empty_epnum; int has_epnum = 1; - /* do not do episode duplicate check below if no episode number */ + /* skip episode duplicate check below if no episode number */ memset(&empty_epnum, 0, sizeof(empty_epnum)); if (epg_episode_number_cmp(&empty_epnum, &e->episode->epnum) == 0) has_epnum = 0; @@ -446,13 +446,18 @@ static int _dvr_duplicate_event ( epg_broadcast_t *e ) if (de->de_bcast->episode == e->episode) return 1; if (has_epnum) { - const char* de_title = lang_str_get(de->de_bcast->episode->title, NULL); - const char* e_title = lang_str_get(e->episode->title, NULL); + dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name); + int ep_dup_det = (cfg->dvr_flags & DVR_EPISODE_DUPLICATE_DETECTION); - /* duplicate if title and episode match */ - if (de_title && e_title && strcmp(de_title, e_title) == 0 - && epg_episode_number_cmp(&de->de_bcast->episode->epnum, &e->episode->epnum) == 0) { - return 1; + if (ep_dup_det) { + const char* de_title = lang_str_get(de->de_bcast->episode->title, NULL); + const char* e_title = lang_str_get(e->episode->title, NULL); + + /* duplicate if title and episode match */ + if (de_title && e_title && strcmp(de_title, e_title) == 0 + && epg_episode_number_cmp(&de->de_bcast->episode->epnum, &e->episode->epnum) == 0) { + return 1; + } } } } @@ -1145,6 +1150,9 @@ dvr_init(void) if(!htsmsg_get_u32(m, "skip-commercials", &u32) && !u32) cfg->dvr_flags &= ~DVR_SKIP_COMMERCIALS; + if(!htsmsg_get_u32(m, "episode-duplicate-detection", &u32) && u32) + cfg->dvr_flags |= DVR_EPISODE_DUPLICATE_DETECTION; + tvh_str_set(&cfg->dvr_postproc, htsmsg_get_str(m, "postproc")); } @@ -1311,6 +1319,7 @@ dvr_save(dvr_config_t *cfg) htsmsg_add_u32(m, "clean-title", !!(cfg->dvr_flags & DVR_CLEAN_TITLE)); htsmsg_add_u32(m, "tag-files", !!(cfg->dvr_flags & DVR_TAG_FILES)); htsmsg_add_u32(m, "skip-commercials", !!(cfg->dvr_flags & DVR_SKIP_COMMERCIALS)); + htsmsg_add_u32(m, "episode-duplicate-detection", !!(cfg->dvr_flags & DVR_EPISODE_DUPLICATE_DETECTION)); if(cfg->dvr_postproc != NULL) htsmsg_add_str(m, "postproc", cfg->dvr_postproc); diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 6ff9fbb8..86ffd2af 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -1306,6 +1306,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(r, "cleanTitle", !!(cfg->dvr_flags & DVR_CLEAN_TITLE)); htsmsg_add_u32(r, "tagFiles", !!(cfg->dvr_flags & DVR_TAG_FILES)); htsmsg_add_u32(r, "commSkip", !!(cfg->dvr_flags & DVR_SKIP_COMMERCIALS)); + htsmsg_add_u32(r, "episodeDuplicateDetection", !!(cfg->dvr_flags & DVR_EPISODE_DUPLICATE_DETECTION)); out = json_single_record(r, "dvrSettings"); @@ -1358,6 +1359,8 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque) flags |= DVR_TAG_FILES; if(http_arg_get(&hc->hc_req_args, "commSkip") != NULL) flags |= DVR_SKIP_COMMERCIALS; + if(http_arg_get(&hc->hc_req_args, "episodeDuplicateDetection") != NULL) + flags |= DVR_EPISODE_DUPLICATE_DETECTION; dvr_flags_set(cfg,flags); diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index 02021eb3..a4bb8e46 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -729,7 +729,7 @@ tvheadend.dvrsettings = function() { }, [ 'storage', 'postproc', 'retention', 'dayDirs', 'channelDirs', 'channelInTitle', 'container', 'dateInTitle', 'timeInTitle', 'preExtraTime', 'postExtraTime', 'whitespaceInTitle', 'titleDirs', - 'episodeInTitle', 'cleanTitle', 'tagFiles', 'commSkip' ]); + 'episodeInTitle', 'cleanTitle', 'tagFiles', 'commSkip', 'episodeDuplicateDetection' ]); var confcombo = new Ext.form.ComboBox({ store : tvheadend.configNames, @@ -822,6 +822,9 @@ tvheadend.dvrsettings = function() { }), new Ext.form.Checkbox({ fieldLabel : 'Skip commercials', name : 'commSkip' + }), new Ext.form.Checkbox({ + fieldLabel : 'Episode duplicate detection', + name : 'episodeDuplicateDetection' }), { width : 300, fieldLabel : 'Post-processor command',