Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
DVR: implement "keep forever" and "keep until space needed"
  • Loading branch information
Glenn-1990 authored and perexg committed Dec 3, 2015
1 parent 94e171e commit f9c0c6a
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/api/api_dvr.c
Expand Up @@ -240,7 +240,7 @@ api_dvr_entry_create_by_event
e, 0, 0,
perm->aa_username,
perm->aa_representative,
NULL, DVR_PRIO_NORMAL, 0, 0, comment);
NULL, DVR_PRIO_NORMAL, DVR_RET_DVRCONFIG, DVR_RET_DVRCONFIG, comment);
if (de)
dvr_entry_save(de);
}
Expand Down
30 changes: 29 additions & 1 deletion src/dvr/dvr.h
Expand Up @@ -54,6 +54,7 @@ typedef struct dvr_config {
uint32_t dvr_extra_time_post;
uint32_t dvr_update_window;
int dvr_running;
uint32_t dvr_cleanup_threshold;

muxer_config_t dvr_muxcnf;

Expand Down Expand Up @@ -119,7 +120,24 @@ typedef enum {
DVR_RS_EPG_WAIT,
DVR_RS_FINISHED
} dvr_rs_state_t;


typedef enum {
DVR_RET_DVRCONFIG = 0,
DVR_RET_1DAY = 1,
DVR_RET_3DAY = 3,
DVR_RET_5DAY = 5,
DVR_RET_1WEEK = 7,
DVR_RET_2WEEK = 14,
DVR_RET_3WEEK = 21,
DVR_RET_1MONTH = 30,
DVR_RET_2MONTH = 60,
DVR_RET_3MONTH = 90,
DVR_RET_6MONTH = 180,
DVR_RET_1YEAR = 365,
DVR_RET_ONREMOVE = UINT32_MAX-1, // for retention only
DVR_RET_SPACENEED = UINT32_MAX-1, // for removal only
DVR_RET_FOREVER = UINT32_MAX
} dvr_retention_t;

typedef struct dvr_entry {

Expand Down Expand Up @@ -430,6 +448,10 @@ static inline int dvr_entry_is_valid(dvr_entry_t *de)

int dvr_entry_get_mc(dvr_entry_t *de);

const char *dvr_entry_get_retention_string ( dvr_entry_t *de );

const char *dvr_entry_get_removal_string ( dvr_entry_t *de );

uint32_t dvr_entry_get_retention_days( dvr_entry_t *de );

uint32_t dvr_entry_get_removal_days( dvr_entry_t *de );
Expand Down Expand Up @@ -531,6 +553,8 @@ const char *dvr_get_filename(dvr_entry_t *de);

int64_t dvr_get_filesize(dvr_entry_t *de);

int64_t dvr_entry_claenup(dvr_entry_t *de, int64_t requiredBytes);

void dvr_entry_set_rerecord(dvr_entry_t *de, int cmd);

dvr_entry_t *dvr_entry_stop(dvr_entry_t *de);
Expand All @@ -543,10 +567,14 @@ void dvr_entry_delete(dvr_entry_t *de, int no_missed_time_resched);

void dvr_entry_cancel_delete(dvr_entry_t *de, int rerecord);

void dvr_entry_destroy(dvr_entry_t *de, int delconf);

htsmsg_t *dvr_entry_class_mc_list (void *o, const char *lang);
htsmsg_t *dvr_entry_class_pri_list(void *o, const char *lang);
htsmsg_t *dvr_entry_class_config_name_list(void *o, const char *lang);
htsmsg_t *dvr_entry_class_duration_list(void *o, const char *not_set, int max, int step, const char *lang);
htsmsg_t *dvr_entry_class_retention_list ( void *o, const char *lang );
htsmsg_t *dvr_entry_class_removal_list ( void *o, const char *lang );

int dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly);

Expand Down
16 changes: 13 additions & 3 deletions src/dvr/dvr_autorec.c
Expand Up @@ -1092,15 +1092,19 @@ const idclass_t dvr_autorec_entry_class = {
{
.type = PT_U32,
.id = "retention",
.name = N_("DVR log retention (days)"),
.name = N_("DVR log retention"),
.def.i = DVR_RET_DVRCONFIG,
.off = offsetof(dvr_autorec_entry_t, dae_retention),
.list = dvr_entry_class_retention_list,
.opts = PO_HIDDEN | PO_EXPERT,
},
{
.type = PT_U32,
.id = "removal",
.name = N_("DVR file retention period (days)"),
.name = N_("DVR file retention period"),
.def.i = DVR_RET_DVRCONFIG,
.off = offsetof(dvr_autorec_entry_t, dae_removal),
.list = dvr_entry_class_removal_list,
.opts = PO_HIDDEN | PO_EXPERT,
},
{
Expand Down Expand Up @@ -1389,8 +1393,14 @@ dvr_autorec_get_extra_time_post( dvr_autorec_entry_t *dae )
uint32_t
dvr_autorec_get_retention_days( dvr_autorec_entry_t *dae )
{
if (dae->dae_retention > 0)
if (dae->dae_retention > 0) {
/* As we need the db entry when deleting the file on disk */
if (dvr_autorec_get_removal_days(dae) != DVR_RET_FOREVER &&
dvr_autorec_get_removal_days(dae) > dae->dae_retention)
return DVR_RET_ONREMOVE;

return dae->dae_retention;
}
return dvr_retention_cleanup(dae->dae_config->dvr_retention_days);
}

Expand Down
70 changes: 64 additions & 6 deletions src/dvr/dvr_config.c
Expand Up @@ -177,14 +177,16 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf)

cfg->dvr_enabled = 1;
cfg->dvr_config_name = strdup(name);
cfg->dvr_retention_days = 31;
cfg->dvr_retention_days = DVR_RET_ONREMOVE;
cfg->dvr_removal_days = DVR_RET_FOREVER;
cfg->dvr_clone = 1;
cfg->dvr_tag_files = 1;
cfg->dvr_skip_commercials = 1;
dvr_charset_update(cfg, intlconv_filesystem_charset());
cfg->dvr_warm_time = 30;
cfg->dvr_update_window = 24 * 3600;
cfg->dvr_pathname = strdup("$t$n.$x");
cfg->dvr_cleanup_threshold = 2000;

/* Muxer config */
cfg->dvr_muxcnf.m_cache = MC_CACHE_DONTKEEP;
Expand Down Expand Up @@ -514,8 +516,11 @@ dvr_config_save(dvr_config_t *cfg)
lock_assert(&global_lock);

dvr_config_storage_check(cfg);
if (cfg->dvr_removal_days > cfg->dvr_retention_days)
cfg->dvr_removal_days = cfg->dvr_retention_days;
if (cfg->dvr_cleanup_threshold < 100)
cfg->dvr_cleanup_threshold = 100; // as checking is only periodically, lower is not save
if (cfg->dvr_removal_days != DVR_RET_FOREVER &&
cfg->dvr_removal_days > cfg->dvr_retention_days)
cfg->dvr_retention_days = DVR_RET_ONREMOVE;
idnode_save(&cfg->dvr_id, m);
hts_settings_save(m, "dvr/config/%s", idnode_uuid_as_sstr(&cfg->dvr_id));
htsmsg_destroy(m);
Expand Down Expand Up @@ -694,6 +699,48 @@ dvr_config_class_cache_list(void *o, const char *lang)
return strtab2htsmsg(tab, 1, lang);
}

static htsmsg_t *
dvr_config_class_removal_list ( void *o, const char *lang )
{
static const struct strtab_u32 tab[] = {
{ N_("1 day"), DVR_RET_1DAY },
{ N_("3 days"), DVR_RET_3DAY },
{ N_("5 days"), DVR_RET_5DAY },
{ N_("1 week"), DVR_RET_1WEEK },
{ N_("2 weeks"), DVR_RET_2WEEK },
{ N_("3 weeks"), DVR_RET_3WEEK },
{ N_("1 month"), DVR_RET_1MONTH },
{ N_("2 months"), DVR_RET_2MONTH },
{ N_("3 months"), DVR_RET_3MONTH },
{ N_("6 months"), DVR_RET_6MONTH },
{ N_("1 year"), DVR_RET_1YEAR },
{ N_("Until space needed"), DVR_RET_SPACENEED },
{ N_("Forever"), DVR_RET_FOREVER },
};
return strtab2htsmsg_u32(tab, 1, lang);
}

static htsmsg_t *
dvr_config_class_retention_list ( void *o, const char *lang )
{
static const struct strtab_u32 tab[] = {
{ N_("1 day"), DVR_RET_1DAY },
{ N_("3 days"), DVR_RET_3DAY },
{ N_("5 days"), DVR_RET_5DAY },
{ N_("1 week"), DVR_RET_1WEEK },
{ N_("2 weeks"), DVR_RET_2WEEK },
{ N_("3 weeks"), DVR_RET_3WEEK },
{ N_("1 month"), DVR_RET_1MONTH },
{ N_("2 months"), DVR_RET_2MONTH },
{ N_("3 months"), DVR_RET_3MONTH },
{ N_("6 months"), DVR_RET_6MONTH },
{ N_("1 year"), DVR_RET_1YEAR },
{ N_("On file removal"), DVR_RET_ONREMOVE },
{ N_("Forever"), DVR_RET_FOREVER },
};
return strtab2htsmsg_u32(tab, 1, lang);
}

static htsmsg_t *
dvr_config_class_extra_list(void *o, const char *lang)
{
Expand Down Expand Up @@ -813,16 +860,19 @@ const idclass_t dvr_config_class = {
{
.type = PT_U32,
.id = "retention-days",
.name = N_("DVR log retention period (days)"),
.name = N_("DVR log retention period"),
.off = offsetof(dvr_config_t, dvr_retention_days),
.def.u32 = 31,
.def.u32 = DVR_RET_ONREMOVE,
.list = dvr_config_class_retention_list,
.group = 1,
},
{
.type = PT_U32,
.id = "removal-days",
.name = N_("DVR file retention period (days)"),
.name = N_("DVR file retention period"),
.off = offsetof(dvr_config_t, dvr_removal_days),
.def.u32 = DVR_RET_FOREVER,
.list = dvr_config_class_removal_list,
.group = 1,
},
{
Expand Down Expand Up @@ -927,6 +977,14 @@ const idclass_t dvr_config_class = {
.off = offsetof(dvr_config_t, dvr_storage),
.group = 2,
},
{
.type = PT_U32,
.id = "storage-cleanup",
.name = N_("\"Until space needed\" cleanup below (MB)"),
.off = offsetof(dvr_config_t, dvr_cleanup_threshold),
.def.i = 2000, //2000 MB
.group = 2,
},
{
.type = PT_PERM,
.id = "file-permissions",
Expand Down

0 comments on commit f9c0c6a

Please sign in to comment.