Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[htsp] allow clients to get/set dvr priority and retention
  • Loading branch information
Glenn-1990 authored and perexg committed Sep 14, 2014
1 parent 1c2051d commit 492a988
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/api/api_dvr.c
Expand Up @@ -226,7 +226,7 @@ api_dvr_entry_create_by_event
if ((e = epg_broadcast_find_by_id(atoi(s), NULL))) {
de = dvr_entry_create_by_event(api_dvr_config_name(perm, config_uuid),
e, 0, 0, perm->aa_representative,
NULL, DVR_PRIO_NORMAL);
NULL, DVR_PRIO_NORMAL, 0);
if (de)
dvr_entry_save(de);
}
Expand Down
21 changes: 13 additions & 8 deletions src/dvr/dvr.h
Expand Up @@ -83,11 +83,12 @@ extern struct dvr_config_list dvrconfigs;
extern struct dvr_entry_list dvrentries;

typedef enum {
DVR_PRIO_IMPORTANT,
DVR_PRIO_HIGH,
DVR_PRIO_NORMAL,
DVR_PRIO_LOW,
DVR_PRIO_UNIMPORTANT,
DVR_PRIO_IMPORTANT = 0,
DVR_PRIO_HIGH = 1,
DVR_PRIO_NORMAL = 2,
DVR_PRIO_LOW = 3,
DVR_PRIO_UNIMPORTANT = 4,
DVR_PRIO_NOTSET = 5,
} dvr_prio_t;


Expand Down Expand Up @@ -159,6 +160,7 @@ typedef struct dvr_entry {
int de_pri;
int de_dont_reschedule;
int de_mc;
int de_retention;

/**
* EPG information / links
Expand Down Expand Up @@ -307,6 +309,8 @@ static inline int dvr_entry_is_valid(dvr_entry_t *de)

int dvr_entry_get_mc(dvr_entry_t *de);

int dvr_entry_get_retention( dvr_entry_t *de );

void dvr_entry_save(dvr_entry_t *de);

const char *dvr_entry_status(dvr_entry_t *de);
Expand All @@ -327,7 +331,7 @@ dvr_entry_create_by_event( const char *dvr_config_uuid,
time_t start_extra, time_t stop_extra,
const char *creator,
dvr_autorec_entry_t *dae,
dvr_prio_t pri );
dvr_prio_t pri, int retention );

dvr_entry_t *
dvr_entry_create_htsp( const char *dvr_config_uuid,
Expand All @@ -336,13 +340,14 @@ dvr_entry_create_htsp( const char *dvr_config_uuid,
const char *title, const char *description,
const char *lang, epg_genre_t *content_type,
const char *creator, dvr_autorec_entry_t *dae,
dvr_prio_t pri );
dvr_prio_t pri, int retention );

dvr_entry_t *
dvr_entry_update( dvr_entry_t *de,
const char* de_title, const char *de_desc, const char *lang,
time_t de_start, time_t de_stop,
time_t de_start_extra, time_t de_stop_extra );
time_t de_start_extra, time_t de_stop_extra,
dvr_prio_t pri, int retention );

void dvr_init(void);
void dvr_config_init(void);
Expand Down
72 changes: 51 additions & 21 deletions src/dvr/dvr_db.c
Expand Up @@ -93,6 +93,14 @@ dvr_entry_get_mc( dvr_entry_t *de )
return de->de_config->dvr_mc;
}

int
dvr_entry_get_retention( dvr_entry_t *de )
{
if (de->de_retention >= 0)
return de->de_retention;
return de->de_config->dvr_retention_days;
}

/*
* DBUS next dvr start notifications
*/
Expand Down Expand Up @@ -293,7 +301,6 @@ static void
dvr_entry_set_timer(dvr_entry_t *de)
{
time_t now, start, stop;
dvr_config_t *cfg = de->de_config;

time(&now);

Expand All @@ -307,7 +314,7 @@ dvr_entry_set_timer(dvr_entry_t *de)
else
_dvr_entry_completed(de);
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
de->de_stop + cfg->dvr_retention_days * 86400);
de->de_stop + dvr_entry_get_retention(de) * 86400);

} else if (de->de_sched_state == DVR_RECORDING) {

Expand Down Expand Up @@ -431,7 +438,7 @@ _dvr_entry_create(const char *config_uuid, epg_broadcast_t *e,
const char *title, const char *description,
const char *lang, epg_genre_t *content_type,
const char *creator, dvr_autorec_entry_t *dae,
dvr_prio_t pri)
dvr_prio_t pri, int retention)
{
dvr_entry_t *de;
char tbuf[64];
Expand All @@ -445,6 +452,7 @@ _dvr_entry_create(const char *config_uuid, epg_broadcast_t *e,
htsmsg_add_s64(conf, "stop", stop);
htsmsg_add_str(conf, "channel", idnode_uuid_as_str(&ch->ch_id));
htsmsg_add_u32(conf, "pri", pri);
htsmsg_add_u32(conf, "retention", retention);
htsmsg_add_str(conf, "config_name", config_uuid ?: "");
htsmsg_add_s64(conf, "start_extra", start_extra);
htsmsg_add_s64(conf, "stop_extra", stop_extra);
Expand Down Expand Up @@ -510,7 +518,7 @@ dvr_entry_create_htsp(const char *config_uuid,
const char *description, const char *lang,
epg_genre_t *content_type,
const char *creator, dvr_autorec_entry_t *dae,
dvr_prio_t pri)
dvr_prio_t pri, int retention)
{
dvr_config_t *cfg = dvr_config_find_by_uuid(config_uuid);
if (!cfg)
Expand All @@ -519,7 +527,7 @@ dvr_entry_create_htsp(const char *config_uuid,
NULL,
ch, start, stop, start_extra, stop_extra,
title, description, lang, content_type,
creator, dae, pri);
creator, dae, pri, retention);
}

/**
Expand All @@ -529,8 +537,8 @@ dvr_entry_t *
dvr_entry_create_by_event(const char *config_uuid,
epg_broadcast_t *e,
time_t start_extra, time_t stop_extra,
const char *creator,
dvr_autorec_entry_t *dae, dvr_prio_t pri)
const char *creator, dvr_autorec_entry_t *dae,
dvr_prio_t pri, int retention)
{
if(!e->channel || !e->episode || !e->episode->title)
return NULL;
Expand All @@ -540,7 +548,7 @@ dvr_entry_create_by_event(const char *config_uuid,
start_extra, stop_extra,
NULL, NULL, NULL,
LIST_FIRST(&e->episode->genre),
creator, dae, pri);
creator, dae, pri, retention);
}

/**
Expand Down Expand Up @@ -596,7 +604,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, 0, 0, buf, dae, dae->dae_pri);
dvr_entry_create_by_event(dae->dae_config_name, e, 0, 0, buf, dae, dae->dae_pri, 0);
}

/**
Expand Down Expand Up @@ -727,9 +735,9 @@ dvr_timer_expire(void *aux)
}

static dvr_entry_t *_dvr_entry_update
( dvr_entry_t *de, epg_broadcast_t *e,
const char *title, const char *desc, const char *lang,
time_t start, time_t stop, time_t start_extra, time_t stop_extra )
( dvr_entry_t *de, epg_broadcast_t *e, const char *title,
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 save = 0;

Expand Down Expand Up @@ -757,6 +765,14 @@ static dvr_entry_t *_dvr_entry_update
de->de_stop_extra = stop_extra;
save = 1;
}
if (pri != DVR_PRIO_NOTSET && (pri != de->de_pri)) {
de->de_pri = pri;
save = 1;
}
if (retention && (retention != de->de_retention)) {
de->de_retention = retention;
save = 1;
}
if (save)
dvr_entry_set_timer(de);

Expand Down Expand Up @@ -814,10 +830,12 @@ dvr_entry_update
(dvr_entry_t *de,
const char* de_title, const char *de_desc, const char *lang,
time_t de_start, time_t de_stop,
time_t de_start_extra, time_t de_stop_extra)
time_t de_start_extra, time_t de_stop_extra,
dvr_prio_t pri, int retention)
{
return _dvr_entry_update(de, NULL, de_title, de_desc, lang,
de_start, de_stop, de_start_extra, de_stop_extra);
de_start, de_stop, de_start_extra, de_stop_extra,
pri, retention);
}

/**
Expand Down Expand Up @@ -867,7 +885,7 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e)
e->start, e->stop);
e->getref(e);
de->de_bcast = e;
_dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0);
_dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0);
break;
}
}
Expand All @@ -880,7 +898,7 @@ 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, NULL, NULL, 0, 0, 0, 0);
_dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0);
else {
LIST_FOREACH(de, &dvrentries, de_global_link) {
if (de->de_sched_state != DVR_SCHEDULED) continue;
Expand All @@ -896,7 +914,7 @@ void dvr_event_updated ( epg_broadcast_t *e )
e->start, e->stop);
e->getref(e);
de->de_bcast = e;
_dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0);
_dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0);
break;
}
}
Expand All @@ -909,8 +927,6 @@ void dvr_event_updated ( epg_broadcast_t *e )
static void
dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf)
{
dvr_config_t *cfg = de->de_config;

if (de->de_rec_state == DVR_RS_PENDING ||
de->de_rec_state == DVR_RS_WAIT_PROGRAM_START ||
de->de_filename == NULL)
Expand All @@ -931,7 +947,7 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf)
htsp_dvr_entry_update(de);

gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
de->de_stop + cfg->dvr_retention_days * 86400);
de->de_stop + dvr_entry_get_retention(de) * 86400);

This comment has been minimized.

Copy link
@ksooo

ksooo Sep 16, 2014

Contributor

dvr_entry_get_retention will in most cases return zero as de_retention gets initialized with zero! As a consequence, this timer will be initialized to expire the moment a recording has ended. Means, on tvh startup every recording that has been made so far, will be removed from tvhs "database". Lost all my recordings this way!

Possibly it is a good idea to initialized de_retention with -1?

}


Expand Down Expand Up @@ -1301,7 +1317,7 @@ htsmsg_t *
dvr_entry_class_pri_list ( void *o )
{
static const struct strtab tab[] = {
{ "Not set", -1 },
{ "Not set", DVR_PRIO_NOTSET },
{ "Important", DVR_PRIO_IMPORTANT },
{ "High", DVR_PRIO_HIGH, },
{ "Normal", DVR_PRIO_NORMAL },
Expand All @@ -1311,6 +1327,13 @@ dvr_entry_class_pri_list ( void *o )
return strtab2htsmsg(tab);
}

static int
dvr_entry_class_retention_set(void *o, const void *v)
{
dvr_entry_t *de = (dvr_entry_t *)o;
return dvr_entry_class_int_set(de, &de->de_retention, *(int *)v);
}

static int
dvr_entry_class_mc_set(void *o, const void *v)
{
Expand Down Expand Up @@ -1753,6 +1776,13 @@ const idclass_t dvr_entry_class = {
.set = dvr_entry_class_pri_set,
.list = dvr_entry_class_pri_list,
},
{
.type = PT_INT,
.id = "retention",
.name = "Retention",
.off = offsetof(dvr_entry_t, de_retention),
.set = dvr_entry_class_retention_set,
},
{
.type = PT_INT,
.id = "container",
Expand Down
5 changes: 3 additions & 2 deletions src/dvr/dvr_rec.c
Expand Up @@ -46,12 +46,13 @@ static void dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc);
static void dvr_thread_epilog(dvr_entry_t *de);


const static int prio2weight[5] = {
const static int prio2weight[6] = {
[DVR_PRIO_IMPORTANT] = 500,
[DVR_PRIO_HIGH] = 400,
[DVR_PRIO_NORMAL] = 300,
[DVR_PRIO_LOW] = 200,
[DVR_PRIO_UNIMPORTANT] = 100,
[DVR_PRIO_NOTSET] = 0,
};

/**
Expand All @@ -67,7 +68,7 @@ dvr_rec_subscribe(dvr_entry_t *de)

assert(de->de_s == NULL);

if(de->de_pri < 5)
if(de->de_pri < ARRAY_SIZE(prio2weight))
weight = prio2weight[de->de_pri];
else
weight = 300;
Expand Down
20 changes: 13 additions & 7 deletions src/htsp_server.c
Expand Up @@ -660,8 +660,10 @@ htsp_build_dvrentry(dvr_entry_t *de, const char *method)
if (de->de_channel)
htsmsg_add_u32(out, "channel", channel_get_id(de->de_channel));

htsmsg_add_s64(out, "start", de->de_start);
htsmsg_add_s64(out, "stop", de->de_stop);
htsmsg_add_s64(out, "start", de->de_start);
htsmsg_add_s64(out, "stop", de->de_stop);
htsmsg_add_u32(out, "priority", de->de_pri);
htsmsg_add_u32(out, "retention", de->de_retention);

if( de->de_title && (s = lang_str_get(de->de_title, NULL)))
htsmsg_add_str(out, "title", s);
Expand Down Expand Up @@ -1176,7 +1178,7 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
dvr_entry_sched_state_t dvr_status;
const char *dvr_config_name, *title, *desc, *creator, *lang;
int64_t start, stop, start_extra, stop_extra;
uint32_t u32, priority;
uint32_t u32, priority, retention;
channel_t *ch = NULL;

/* Options */
Expand All @@ -1192,6 +1194,8 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
e = epg_broadcast_find_by_id(eventid, ch);
if(htsmsg_get_u32(in, "priority", &priority))
priority = DVR_PRIO_NORMAL;
if(htsmsg_get_u32(in, "retention", &retention))
retention = 0;
if (!(creator = htsmsg_get_str(in, "creator")) || !*creator)
creator = htsp->htsp_username ?: "anonymous";
if (!(lang = htsmsg_get_str(in, "language")))
Expand Down Expand Up @@ -1219,13 +1223,13 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
// create the dvr entry
de = dvr_entry_create_htsp(dvr_config_name, ch, start, stop,
start_extra, stop_extra,
title, desc, lang, 0, creator, NULL, priority);
title, desc, lang, 0, creator, NULL, priority, retention);

/* Event timer */
} else {
de = dvr_entry_create_by_event(dvr_config_name, e,
start_extra, stop_extra,
creator, NULL, priority);
creator, NULL, priority, retention);
}

dvr_status = de != NULL ? de->de_sched_state : DVR_NOSTATE;
Expand Down Expand Up @@ -1258,7 +1262,7 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
htsmsg_t *out;
uint32_t dvrEntryId;
dvr_entry_t *de;
time_t start, stop, start_extra, stop_extra;
time_t start, stop, start_extra, stop_extra, priority, retention;
const char *title, *desc, *lang;

if(htsmsg_get_u32(in, "id", &dvrEntryId))
Expand All @@ -1275,13 +1279,15 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
stop = htsmsg_get_s64_or_default(in, "stop", 0);
start_extra = htsmsg_get_s64_or_default(in, "start_extra", 0);
stop_extra = htsmsg_get_s64_or_default(in, "stop_extra", 0);
retention = htsmsg_get_u32_or_default(in, "retention", 0);
priority = htsmsg_get_u32_or_default(in, "priority", DVR_PRIO_NORMAL);
title = htsmsg_get_str(in, "title");
desc = htsmsg_get_str(in, "description");
lang = htsmsg_get_str(in, "language");
if (!lang) lang = htsp->htsp_language;

de = dvr_entry_update(de, title, desc, lang, start, stop,
start_extra, stop_extra);
start_extra, stop_extra, priority, retention);

//create response
out = htsmsg_create_map();
Expand Down
2 changes: 1 addition & 1 deletion src/webui/simpleui.c
Expand Up @@ -217,7 +217,7 @@ page_einfo(http_connection_t *hc, const char *remain, void *opaque)

if((http_arg_get(&hc->hc_req_args, "rec")) != NULL) {
de = dvr_entry_create_by_event(NULL, e, 0, 0, hc->hc_username ?: "anonymous", NULL,
DVR_PRIO_NORMAL);
DVR_PRIO_NORMAL, 0);
} else if(de != NULL && (http_arg_get(&hc->hc_req_args, "cancel")) != NULL) {
de = dvr_entry_cancel(de);
}
Expand Down

0 comments on commit 492a988

Please sign in to comment.