diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index b0767a14..b3781783 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -73,6 +73,8 @@ typedef struct dvr_config { int dvr_dup_detect_episode; struct dvr_entry_list dvr_entries; + struct dvr_autorec_entry_list dvr_autorec_entries; + struct dvr_timerec_entry_list dvr_timerec_entries; struct access_entry_list dvr_accesses; @@ -235,7 +237,8 @@ typedef struct dvr_autorec_entry { TAILQ_ENTRY(dvr_autorec_entry) dae_link; char *dae_name; - char *dae_config_name; + dvr_config_t *dae_config; + LIST_ENTRY(dvr_autorec_entry) dae_config_link; int dae_enabled; char *dae_creator; @@ -286,7 +289,8 @@ typedef struct dvr_timerec_entry { TAILQ_ENTRY(dvr_timerec_entry) dte_link; char *dte_name; - char *dte_config_name; + dvr_config_t *dte_config; + LIST_ENTRY(dvr_timerec_entry) dte_config_link; int dte_enabled; char *dte_creator; @@ -514,6 +518,8 @@ void dvr_autorec_check_brand(epg_brand_t *b); void dvr_autorec_check_season(epg_season_t *s); void dvr_autorec_check_serieslink(epg_serieslink_t *s); +void autorec_destroy_by_config(dvr_config_t *cfg, int delconf); + void autorec_destroy_by_channel(channel_t *ch, int delconf); void autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf); @@ -542,6 +548,8 @@ void dvr_timerec_save(dvr_timerec_entry_t *dae); void dvr_timerec_check(dvr_timerec_entry_t *dae); +void timerec_destroy_by_config(dvr_config_t *cfg, int delconf); + void timerec_destroy_by_channel(channel_t *ch, int delconf); void timerec_destroy_by_id(const char *id, int delconf); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 8367166f..3a5c641c 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -103,7 +103,8 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) } // Note: ignore channel test if we allow quality unlocking - cfg = dvr_config_find_by_name_default(dae->dae_config_name); + if ((cfg = dae->dae_config) == NULL) + return 0; if (cfg->dvr_sl_quality_lock) if(dae->dae_channel != NULL && dae->dae_channel != e->channel) @@ -175,6 +176,8 @@ dvr_autorec_create(const char *uuid, htsmsg_t *conf) dae->dae_weekdays = 0x7f; dae->dae_pri = DVR_PRIO_NORMAL; dae->dae_start = -1; + dae->dae_config = dvr_config_find_by_name_default(""); + LIST_INSERT_HEAD(&dae->dae_config->dvr_autorec_entries, dae, dae_config_link); TAILQ_INSERT_TAIL(&autorec_entries, dae, dae_link); @@ -280,8 +283,10 @@ autorec_entry_destroy(dvr_autorec_entry_t *dae, int delconf) TAILQ_REMOVE(&autorec_entries, dae, dae_link); idnode_unlink(&dae->dae_id); + if(dae->dae_config) + LIST_REMOVE(dae, dae_config_link); + free(dae->dae_name); - free(dae->dae_config_name); free(dae->dae_creator); free(dae->dae_comment); @@ -525,17 +530,32 @@ dvr_autorec_entry_class_config_name_set(void *o, const void *v) dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; dvr_config_t *cfg = v ? dvr_config_find_by_uuid(v) : NULL; if (cfg == NULL) cfg = v ? dvr_config_find_by_name_default(v): NULL; - if (cfg == NULL && dae->dae_config_name) { - free(dae->dae_config_name); + if (cfg == NULL && dae->dae_config) { + dae->dae_config = NULL; + LIST_REMOVE(dae, dae_config_link); return 1; - } else if (strcmp(dae->dae_config_name ?: "", cfg ? cfg->dvr_config_name : "")) { - free(dae->dae_config_name); - dae->dae_config_name = strdup(cfg->dvr_config_name); + } else if (cfg != dae->dae_config) { + if (dae->dae_config) + LIST_REMOVE(dae, dae_config_link); + LIST_INSERT_HEAD(&cfg->dvr_autorec_entries, dae, dae_config_link); + dae->dae_config = cfg; return 1; } return 0; } +static const void * +dvr_autorec_entry_class_config_name_get(void *o) +{ + static const char *ret; + dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; + if (dae->dae_config) + ret = idnode_uuid_as_str(&dae->dae_config->dvr_id); + else + ret = ""; + return &ret; +} + static int dvr_autorec_entry_class_weekdays_set(void *o, const void *v) { @@ -856,8 +876,8 @@ const idclass_t dvr_autorec_entry_class = { .id = "config_name", .name = "DVR Configuration", .set = dvr_autorec_entry_class_config_name_set, + .get = dvr_autorec_entry_class_config_name_get, .list = dvr_entry_class_config_name_list, - .off = offsetof(dvr_autorec_entry_t, dae_config_name), }, { .type = PT_STR, @@ -1039,3 +1059,24 @@ autorec_destroy_by_id(const char *id, int delconf) if (dae) autorec_entry_destroy(dae, delconf); } + +/** + * + */ +void +autorec_destroy_by_config(dvr_config_t *kcfg, int delconf) +{ + dvr_autorec_entry_t *dae; + dvr_config_t *cfg = NULL; + + while((dae = LIST_FIRST(&kcfg->dvr_autorec_entries)) != NULL) { + LIST_REMOVE(dae, dae_config_link); + if (cfg == NULL && delconf) + cfg = dvr_config_find_by_name_default(""); + if (cfg) + LIST_INSERT_HEAD(&cfg->dvr_autorec_entries, dae, dae_config_link); + dae->dae_config = cfg; + if (delconf) + dvr_autorec_save(dae); + } +} diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 64740ff7..ee33e611 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -623,7 +623,9 @@ 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, dae->dae_start_extra, dae->dae_stop_extra, buf, dae, dae->dae_pri, dae->dae_retention); + dvr_entry_create_by_event(idnode_uuid_as_str(&dae->dae_config->dvr_id), e, + dae->dae_start_extra, dae->dae_stop_extra, + buf, dae, dae->dae_pri, dae->dae_retention); } /** @@ -2037,6 +2039,8 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf) cfg = calloc(1, sizeof(dvr_config_t)); LIST_INIT(&cfg->dvr_entries); + LIST_INIT(&cfg->dvr_autorec_entries); + LIST_INIT(&cfg->dvr_timerec_entries); LIST_INIT(&cfg->dvr_accesses); if (idnode_insert(&cfg->dvr_id, uuid, &dvr_config_class, 0)) { @@ -2105,6 +2109,8 @@ dvr_config_destroy(dvr_config_t *cfg, int delconf) dvr_entry_destroy_by_config(cfg, delconf); access_destroy_by_dvr_config(cfg, delconf); + autorec_destroy_by_config(cfg, delconf); + timerec_destroy_by_config(cfg, delconf); free(cfg->dvr_charset_id); free(cfg->dvr_charset); diff --git a/src/dvr/dvr_timerec.c b/src/dvr/dvr_timerec.c index 3e9cda42..065eb3a7 100644 --- a/src/dvr/dvr_timerec.c +++ b/src/dvr/dvr_timerec.c @@ -153,7 +153,8 @@ dvr_timerec_check(dvr_timerec_entry_t *dte) snprintf(buf, sizeof(buf), "Time recording%s%s", dte->dte_creator ? " by: " : "", dte->dte_creator ?: ""); - de = dvr_entry_create_(dte->dte_config_name, NULL, dte->dte_channel, + de = dvr_entry_create_(idnode_uuid_as_str(&dte->dte_config->dvr_id), + NULL, dte->dte_channel, start, stop, 0, 0, title, NULL, NULL, NULL, buf, NULL, dte, dte->dte_pri, dte->dte_retention); @@ -186,6 +187,8 @@ dvr_timerec_create(const char *uuid, htsmsg_t *conf) dte->dte_pri = DVR_PRIO_NORMAL; dte->dte_start = -1; dte->dte_stop = -1; + dte->dte_config = dvr_config_find_by_name_default(""); + LIST_INSERT_HEAD(&dte->dte_config->dvr_timerec_entries, dte, dte_config_link); TAILQ_INSERT_TAIL(&timerec_entries, dte, dte_link); @@ -208,8 +211,10 @@ timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf) TAILQ_REMOVE(&timerec_entries, dte, dte_link); idnode_unlink(&dte->dte_id); + if(dte->dte_config != NULL) + LIST_REMOVE(dte, dte_config_link); + free(dte->dte_name); - free(dte->dte_config_name); free(dte->dte_creator); free(dte->dte_comment); @@ -374,17 +379,32 @@ dvr_timerec_entry_class_config_name_set(void *o, const void *v) dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; dvr_config_t *cfg = v ? dvr_config_find_by_uuid(v) : NULL; if (cfg == NULL) cfg = v ? dvr_config_find_by_name_default(v): NULL; - if (cfg == NULL && dte->dte_config_name) { - free(dte->dte_config_name); + if (cfg == NULL && dte->dte_config) { + dte->dte_config = NULL; + LIST_REMOVE(dte, dte_config_link); return 1; - } else if (strcmp(dte->dte_config_name ?: "", cfg ? cfg->dvr_config_name : "")) { - free(dte->dte_config_name); - dte->dte_config_name = strdup(cfg->dvr_config_name); + } else if (cfg != dte->dte_config) { + if (dte->dte_config) + LIST_REMOVE(dte, dte_config_link); + LIST_INSERT_HEAD(&cfg->dvr_timerec_entries, dte, dte_config_link); + dte->dte_config = cfg; return 1; } return 0; } +static const void * +dvr_timerec_entry_class_config_name_get(void *o) +{ + static const char *buf; + dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; + if (dte->dte_config) + buf = idnode_uuid_as_str(&dte->dte_config->dvr_id); + else + buf = ""; + return &buf; +} + static int dvr_timerec_entry_class_weekdays_set(void *o, const void *v) { @@ -506,8 +526,8 @@ const idclass_t dvr_timerec_entry_class = { .id = "config_name", .name = "DVR Configuration", .set = dvr_timerec_entry_class_config_name_set, + .get = dvr_timerec_entry_class_config_name_get, .list = dvr_entry_class_config_name_list, - .off = offsetof(dvr_timerec_entry_t, dte_config_name), }, { .type = PT_STR, @@ -593,7 +613,7 @@ timerec_destroy_by_channel(channel_t *ch, int delconf) timerec_entry_destroy(dte, delconf); } -/* +/** * */ void @@ -605,3 +625,24 @@ timerec_destroy_by_id(const char *id, int delconf) if (dte) timerec_entry_destroy(dte, delconf); } + +/** + * + */ +void +timerec_destroy_by_config(dvr_config_t *kcfg, int delconf) +{ + dvr_timerec_entry_t *dte; + dvr_config_t *cfg = NULL; + + while((dte = LIST_FIRST(&kcfg->dvr_timerec_entries)) != NULL) { + LIST_REMOVE(dte, dte_config_link); + if (cfg == NULL && delconf) + cfg = dvr_config_find_by_name_default(""); + if (cfg) + LIST_INSERT_HEAD(&cfg->dvr_timerec_entries, dte, dte_config_link); + dte->dte_config = cfg; + if (delconf) + dvr_timerec_save(dte); + } +}