From abea3ddee04cb8839f179da18aed5b1b8c2208e3 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 16 Dec 2014 16:10:27 +0100 Subject: [PATCH] DVR: Implement autorec start window instead Starting Around (approx) --- src/config.c | 60 ++++++++++++++++++++++++++++++++++++- src/dvr/dvr.h | 7 +++-- src/dvr/dvr_autorec.c | 37 ++++++++++++++++------- src/htsp_server.c | 28 ++++++++++++----- src/webui/static/app/dvr.js | 5 ++-- 5 files changed, 114 insertions(+), 23 deletions(-) diff --git a/src/config.c b/src/config.c index 60fbd8e0..a6adf39e 100644 --- a/src/config.c +++ b/src/config.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include #include @@ -1102,6 +1103,62 @@ config_migrate_v15 ( void ) } } +static int +config_dvr_autorec_start_set(const char *s, int *tm) +{ + int t; + + if(s == NULL || s[0] == '\0' || !isdigit(s[0])) + t = -1; + else if(strchr(s, ':') != NULL) + // formatted time string - convert + t = (atoi(s) * 60) + atoi(s + 3); + else { + t = atoi(s); + } + if (t >= 24 * 60) + t = -1; + if (t != *tm) { + *tm = t; + return 1; + } + return 0; +} + +static void +config_modify_dvrauto( htsmsg_t *c ) +{ + int tm = -1; + char buf[16]; + + if (config_dvr_autorec_start_set(htsmsg_get_str(c, "start"), &tm) > 0 && tm >= 0) { + tm -= 15; + if (tm < 0) + tm += 24 * 60; + snprintf(buf, sizeof(buf), "%02d:%02d", tm / 60, tm % 60); + htsmsg_set_str(c, "start", tm <= 0 ? "Any" : buf); + htsmsg_set_u32(c, "start_window", 30); + } else { + htsmsg_delete_field(c, "start"); + } +} + +static void +config_migrate_v16 ( void ) +{ + htsmsg_t *c, *e; + htsmsg_field_t *f; + + if ((c = hts_settings_load("dvr/autorec")) != NULL) { + HTSMSG_FOREACH(f, c) { + if (!(e = htsmsg_field_get_map(f))) continue; + config_modify_dvrauto(e); + hts_settings_save(e, "dvr/autorec/%s", f->hmf_name); + } + htsmsg_destroy(c); + } +} + /* * Perform backup */ @@ -1205,7 +1262,8 @@ static const config_migrate_t config_migrate_table[] = { config_migrate_v12, config_migrate_v13, config_migrate_v14, - config_migrate_v15 + config_migrate_v15, + config_migrate_v16 }; /* diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index e6bf12bb..d3d1e2ad 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -251,7 +251,8 @@ typedef struct dvr_autorec_entry { uint32_t dae_content_type; - int dae_start; /* Minutes from midnight */ + int dae_start; /* Minutes from midnight */ + int dae_start_window; /* Minutes (duration) */ uint32_t dae_weekdays; @@ -480,8 +481,8 @@ dvr_entry_create_(const char *config_uuid, epg_broadcast_t *e, dvr_autorec_entry_t * dvr_autorec_create_htsp(const char *dvr_config_name, const char *title, - channel_t *ch, uint32_t aroundTime, uint32_t days, - time_t start_extra, time_t stop_extra, + channel_t *ch, uint32_t start, uint32_t start_window, + uint32_t days, time_t start_extra, time_t stop_extra, dvr_prio_t pri, int retention, int min_duration, int max_duration, const char *creator, const char *comment); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 9e181c48..a18b8a99 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -126,14 +126,16 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) return 0; } - if(dae->dae_start >= 0) { - struct tm a_time; - struct tm ev_time; + if(dae->dae_start >= 0 && dae->dae_start_window >= 0) { + struct tm a_time, ev_time; + time_t ta, te; localtime_r(&e->start, &a_time); - localtime_r(&e->start, &ev_time); + ev_time = a_time; a_time.tm_min = dae->dae_start % 60; a_time.tm_hour = dae->dae_start / 60; - if(abs(mktime(&a_time) - mktime(&ev_time)) > 900) + ta = mktime(&a_time); + te = mktime(&ev_time); + if(ta > te || te > ta + dae->dae_start_window * 60) return 0; } @@ -191,8 +193,8 @@ dvr_autorec_create(const char *uuid, htsmsg_t *conf) dvr_autorec_entry_t* dvr_autorec_create_htsp(const char *dvr_config_name, const char *title, - channel_t *ch, uint32_t aroundTime, uint32_t weekdays, - time_t start_extra, time_t stop_extra, + channel_t *ch, uint32_t start, uint32_t start_window, + uint32_t weekdays, time_t start_extra, time_t stop_extra, dvr_prio_t pri, int retention, int min_duration, int max_duration, const char *creator, const char *comment) @@ -215,8 +217,10 @@ dvr_autorec_create_htsp(const char *dvr_config_name, const char *title, htsmsg_add_str(conf, "creator", creator ?: ""); htsmsg_add_str(conf, "comment", comment ?: ""); - if (aroundTime) - htsmsg_add_u32(conf, "start", (aroundTime-1)); + if (start >= 0) + htsmsg_add_u32(conf, "start", start); + if (start_window >= 0) + htsmsg_add_u32(conf, "start_window", start_window); if (ch) htsmsg_add_str(conf, "channel", idnode_uuid_as_str(&ch->ch_id)); @@ -530,6 +534,12 @@ dvr_autorec_entry_class_time_list_(void *o) return dvr_autorec_entry_class_time_list(o, "Any"); } +static htsmsg_t * +dvr_autorec_entry_class_time_window_list(void *o) +{ + return dvr_entry_class_duration_list(o, "Exact", 24*60, 60); +} + static htsmsg_t * dvr_autorec_entry_class_extra_list(void *o) { @@ -841,12 +851,19 @@ const idclass_t dvr_autorec_entry_class = { { .type = PT_STR, .id = "start", - .name = "Starting Around", + .name = "Start Time", .set = dvr_autorec_entry_class_start_set, .get = dvr_autorec_entry_class_start_get, .list = dvr_autorec_entry_class_time_list_, .opts = PO_SORTKEY }, + { + .type = PT_INT, + .id = "start_window", + .name = "Start Window", + .list = dvr_autorec_entry_class_time_window_list, + .off = offsetof(dvr_autorec_entry_t, dae_start_window), + }, { .type = PT_TIME, .id = "start_extra", diff --git a/src/htsp_server.c b/src/htsp_server.c index 066c44f3..4fad985e 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -738,7 +738,11 @@ htsp_build_autorecentry(dvr_autorec_entry_t *dae, const char *method) htsmsg_add_u32(out, "minDuration", dae->dae_minduration); htsmsg_add_u32(out, "retention", dae->dae_retention); htsmsg_add_u32(out, "daysOfWeek", dae->dae_weekdays); - htsmsg_add_u32(out, "approxTime", dae->dae_start); + htsmsg_add_u32(out, "approxTime", + dae->dae_start_window == 30 && dae->dae_start >= 0 ? + dae->dae_start + 15 : -1); + htsmsg_add_u32(out, "start", dae->dae_start); + htsmsg_add_u32(out, "startWindow", dae->dae_start_window); htsmsg_add_u32(out, "priority", dae->dae_pri); htsmsg_add_s64(out, "startExtra", dae->dae_start_extra); htsmsg_add_s64(out, "stopExtra", dae->dae_stop_extra); @@ -1523,8 +1527,8 @@ htsp_method_addAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) dvr_autorec_entry_t *dae; const char *dvr_config_name, *title, *creator, *comment; int64_t start_extra, stop_extra; - uint32_t u32, days_of_week, priority, approx_time, - min_duration, max_duration, retention; + uint32_t u32, days_of_week, priority, approx_time, start, start_window, + min_duration, max_duration, retention; channel_t *ch = NULL; /* Options */ @@ -1544,9 +1548,19 @@ htsp_method_addAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) if(htsmsg_get_u32(in, "priority", &priority)) priority = DVR_PRIO_NORMAL; if(htsmsg_get_u32(in, "approxTime", &approx_time)) - approx_time = 0; - else - approx_time++; + approx_time = -1; + if(htsmsg_get_u32(in, "start", &start)) + start = -1; + if(htsmsg_get_u32(in, "startWindow", &start_window)) + start_window = -1; + if (start < 0 || start_window < 0) + start = start_window = -1; + if (start < 0 && approx_time >= 0) { + start = approx_time - 15; + if (start < 0) + start += 24 * 60; + start_window = 60; + } if(htsmsg_get_s64(in, "startExtra", &start_extra)) start_extra = 0; // 0 = dvr config if(htsmsg_get_s64(in, "stopExtra", &stop_extra)) @@ -1559,7 +1573,7 @@ htsp_method_addAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) if (ch && !htsp_user_access_channel(htsp, ch)) return htsp_error("User does not have access"); - dae = dvr_autorec_create_htsp(dvr_config_name, title, ch, approx_time, days_of_week, + dae = dvr_autorec_create_htsp(dvr_config_name, title, ch, start, start_window, days_of_week, start_extra, stop_extra, priority, retention, min_duration, max_duration, creator, comment); /* create response */ diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index 5876b155..cf3fa794 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -434,6 +434,7 @@ tvheadend.autorec_editor = function(panel, index) { maxduration: { width: 80 }, weekdays: { width: 160 }, start: { width: 100 }, + start_window: { width: 100 }, pri: { width: 80 }, config_name: { width: 120 }, creator: { width: 200 }, @@ -443,13 +444,13 @@ tvheadend.autorec_editor = function(panel, index) { url: 'api/dvr/autorec', params: { list: 'enabled,name,title,channel,tag,content_type,minduration,' + - 'maxduration,weekdays,start,pri,config_name,comment' + 'maxduration,weekdays,start,start_window,pri,config_name,comment' }, create: { } }, del: true, list: 'enabled,name,title,channel,tag,content_type,minduration,' + - 'maxduration,weekdays,start,pri,config_name,creator,comment', + 'maxduration,weekdays,start,start_window,pri,config_name,creator,comment', columns: { weekdays: { renderer: function(st) { return tvheadend.weekdaysRenderer(st); }