#include "diseqc.h"
#include "notify.h"
#include "transports.h"
-
+#include "dvr/dvr.h"
/**
* Front end monitor
struct dmx_pes_filter_params dmx_param;
char fullname[1000];
char path[500];
- extern char *dvr_storage;
const char *fname = tda->tda_mux_current->tdmi_identifier;
int fd = tvh_open(tda->tda_demux_path, O_RDWR, 0);
return;
}
- snprintf(path, sizeof(path), "%s/muxdumps", dvr_storage);
+ snprintf(path, sizeof(path), "%s/muxdumps",
+ dvr_config_find_by_name_default("")->dvr_storage);
if(mkdir(path, 0777) && errno != EEXIST) {
tvhlog(LOG_ERR, "dvb", "\"%s\" unable to create mux dump dir %s -- %s",
#include "channels.h"
#include "subscriptions.h"
-extern char *dvr_storage;
-extern char *dvr_format;
-extern char *dvr_file_postfix;
-extern uint32_t dvr_retention_days;
-extern int dvr_flags;
-extern char *dvr_postproc;
-extern int dvr_extra_time_pre;
-extern int dvr_extra_time_post;
+typedef struct dvr_config {
+ char *dvr_config_name;
+ char *dvr_storage;
+ char *dvr_format;
+ char *dvr_file_postfix;
+ uint32_t dvr_retention_days;
+ int dvr_flags;
+ char *dvr_postproc;
+ int dvr_extra_time_pre;
+ int dvr_extra_time_post;
+
+ LIST_ENTRY(dvr_config) config_link;
+} dvr_config_t;
+
+extern struct dvr_config_list dvrconfigs;
+
extern struct dvr_entry_list dvrentries;
#define DVR_DIR_PER_DAY 0x1
* These meta fields will stay valid as long as reference count > 0
*/
+ char *de_config_name;
+
time_t de_start;
time_t de_stop;
TAILQ_ENTRY(dvr_autorec_entry) dae_link;
char *dae_id;
+ char *dae_config_name;
+
int dae_enabled;
char *dae_creator;
char *dae_comment;
* Prototypes
*/
+dvr_config_t *dvr_config_find_by_name(const char *name);
+
+dvr_config_t *dvr_config_find_by_name_default(const char *name);
+
+dvr_config_t *dvr_config_create(const char *name);
+
+void dvr_config_delete(const char *name);
+
void dvr_entry_notify(dvr_entry_t *de);
const char *dvr_entry_status(dvr_entry_t *de);
void dvr_entry_create_by_autorec(event_t *e, dvr_autorec_entry_t *dae);
-dvr_entry_t *dvr_entry_create_by_event(event_t *e, const char *creator,
+dvr_entry_t *dvr_entry_create_by_event(const char *dvr_config_name,
+ event_t *e, const char *creator,
dvr_autorec_entry_t *dae,
dvr_prio_t pri);
-dvr_entry_t *dvr_entry_create(channel_t *ch, time_t start, time_t stop,
+dvr_entry_t *dvr_entry_create(const char *dvr_config_name,
+ channel_t *ch, time_t start, time_t stop,
const char *title, const char *description,
const char *creator, dvr_autorec_entry_t *dae,
epg_episode_t *ee, uint8_t content_type,
void dvr_entry_dec_ref(dvr_entry_t *de);
-void dvr_storage_set(const char *storage);
+void dvr_storage_set(dvr_config_t *cfg, const char *storage);
-void dvr_postproc_set(const char *postproc);
+void dvr_postproc_set(dvr_config_t *cfg, const char *postproc);
-void dvr_retention_set(int days);
+void dvr_retention_set(dvr_config_t *cfg, int days);
-void dvr_flags_set(int flags);
+void dvr_flags_set(dvr_config_t *cfg, int flags);
-void dvr_extra_time_pre_set(int d);
+void dvr_extra_time_pre_set(dvr_config_t *cfg, int d);
-void dvr_extra_time_post_set(int d);
+void dvr_extra_time_post_set(dvr_config_t *cfg, int d);
/**
* Query interface
/**
*
*/
-void dvr_autorec_add(const char *title, const char *channel,
+void dvr_autorec_add(const char *dvr_config_name,
+ const char *title, const char *channel,
const char *tag, uint8_t content_type,
const char *creator, const char *comment);
free(dae->dae_id);
+ free(dae->dae_config_name);
free(dae->dae_creator);
free(dae->dae_comment);
htsmsg_add_str(e, "id", dae->dae_id);
htsmsg_add_u32(e, "enabled", !!dae->dae_enabled);
+ if (dae->dae_config_name != NULL)
+ htsmsg_add_str(e, "config_name", dae->dae_config_name);
if(dae->dae_creator != NULL)
htsmsg_add_str(e, "creator", dae->dae_creator);
if(dae->dae_comment != NULL)
if((dae = autorec_entry_find(id, maycreate)) == NULL)
return NULL;
+ tvh_str_update(&dae->dae_config_name, htsmsg_get_str(values, "config_name"));
tvh_str_update(&dae->dae_creator, htsmsg_get_str(values, "creator"));
tvh_str_update(&dae->dae_comment, htsmsg_get_str(values, "comment"));
*
*/
void
-dvr_autorec_add(const char *title, const char *channel,
+dvr_autorec_add(const char *config_name,
+ const char *title, const char *channel,
const char *tag, uint8_t content_type,
const char *creator, const char *comment)
{
if((dae = autorec_entry_find(NULL, 1)) == NULL)
return;
+ tvh_str_set(&dae->dae_config_name, config_name);
tvh_str_set(&dae->dae_creator, creator);
tvh_str_set(&dae->dae_comment, comment);
#include "htsp.h"
#include "streaming.h"
-char *dvr_storage;
-char *dvr_format;
-char *dvr_file_postfix;
-uint32_t dvr_retention_days;
-int dvr_flags;
-int dvr_extra_time_pre;
-int dvr_extra_time_post;
-char *dvr_postproc;
-int dvr_iov_max;
-
static int de_tally;
+int dvr_iov_max;
+
+struct dvr_config_list dvrconfigs;
struct dvr_entry_list dvrentries;
static void dvr_entry_save(dvr_entry_t *de);
notify_by_msg("dvrdb", m);
}
+/**
+ *
+ */
+static void
+dvrconfig_changed(void)
+{
+ htsmsg_t *m = htsmsg_create_map();
+ htsmsg_add_u32(m, "reload", 1);
+ notify_by_msg("dvrconfig", m);
+}
+
/**
*
struct tm tm;
char buf[40];
int i;
+ dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name);
- if(dvr_flags & DVR_CHANNEL_IN_TITLE)
+ if(cfg->dvr_flags & DVR_CHANNEL_IN_TITLE)
snprintf(output, outlen, "%s-", de->de_channel->ch_name);
else
output[0] = 0;
localtime_r(&de->de_start, &tm);
- if(dvr_flags & DVR_DATE_IN_TITLE) {
+ if(cfg->dvr_flags & DVR_DATE_IN_TITLE) {
strftime(buf, sizeof(buf), "%F", &tm);
snprintf(output + strlen(output), outlen - strlen(output), ".%s", buf);
}
- if(dvr_flags & DVR_TIME_IN_TITLE) {
+ if(cfg->dvr_flags & DVR_TIME_IN_TITLE) {
strftime(buf, sizeof(buf), "%H-%M", &tm);
snprintf(output + strlen(output), outlen - strlen(output), ".%s", buf);
}
- if(dvr_flags & DVR_EPISODE_IN_TITLE) {
+ if(cfg->dvr_flags & DVR_EPISODE_IN_TITLE) {
if(de->de_episode.ee_season && de->de_episode.ee_episode)
snprintf(output + strlen(output), outlen - strlen(output),
de->de_episode.ee_episode);
}
- if(dvr_flags & DVR_CLEAN_TITLE) {
+ if(cfg->dvr_flags & DVR_CLEAN_TITLE) {
for (i=0;i<strlen(output);i++) {
if (
output[i]<32 ||
{
time_t now, preamble;
char buf[100];
+ dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name);
dvr_make_title(buf, sizeof(buf), de);
else
de->de_sched_state = DVR_COMPLETED;
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
- de->de_stop + dvr_retention_days * 86400);
+ de->de_stop + cfg->dvr_retention_days * 86400);
} else {
de->de_sched_state = DVR_SCHEDULED;
*
*/
dvr_entry_t *
-dvr_entry_create(channel_t *ch, time_t start, time_t stop,
+dvr_entry_create(const char *config_name,
+ channel_t *ch, time_t start, time_t stop,
const char *title, const char *description,
const char *creator, dvr_autorec_entry_t *dae,
epg_episode_t *ee, uint8_t content_type, dvr_prio_t pri)
char tbuf[30];
struct tm tm;
time_t t;
+ dvr_config_t *cfg = dvr_config_find_by_name_default(config_name);
LIST_FOREACH(de, &ch->ch_dvrs, de_channel_link)
if(de->de_start == start && de->de_sched_state != DVR_COMPLETED)
if (ch->ch_dvr_extra_time_pre)
de->de_start_extra = ch->ch_dvr_extra_time_pre;
else
- de->de_start_extra = dvr_extra_time_pre;
+ de->de_start_extra = cfg->dvr_extra_time_pre;
if (ch->ch_dvr_extra_time_post)
de->de_stop_extra = ch->ch_dvr_extra_time_post;
else
- de->de_stop_extra = dvr_extra_time_post;
+ de->de_stop_extra = cfg->dvr_extra_time_post;
+ de->de_config_name = strdup(cfg->dvr_config_name);
de->de_creator = strdup(creator);
de->de_title = strdup(title);
de->de_desc = description ? strdup(description) : NULL;
*
*/
dvr_entry_t *
-dvr_entry_create_by_event(event_t *e, const char *creator,
+dvr_entry_create_by_event(const char *config_name,
+ event_t *e, const char *creator,
dvr_autorec_entry_t *dae, dvr_prio_t pri)
{
if(e->e_channel == NULL || e->e_title == NULL)
return NULL;
- return dvr_entry_create(e->e_channel, e->e_start, e->e_stop,
+ return dvr_entry_create(config_name,
+ e->e_channel, e->e_start, e->e_stop,
e->e_title, e->e_desc, creator, dae, &e->e_episode,
e->e_content_type, pri);
}
} else {
snprintf(buf, sizeof(buf), "Auto recording");
}
- dvr_entry_create_by_event(e, buf, dae, dae->dae_pri);
+ dvr_entry_create_by_event(dae->dae_config_name, e, buf, dae, dae->dae_pri);
}
if(de->de_autorec != NULL)
LIST_REMOVE(de, de_autorec_link);
+ free(de->de_config_name);
free(de->de_creator);
free(de->de_title);
free(de->de_ititle);
channel_t *ch;
uint32_t start, stop;
int d;
+ dvr_config_t *cfg;
if(htsmsg_get_u32(c, "start", &start))
return;
if((ch = channel_find_by_name(s, 0, 0)) == NULL)
return;
+ s = htsmsg_get_str(c, "config_name");
+ cfg = dvr_config_find_by_name_default(s);
+
if((title = htsmsg_get_str(c, "title")) == NULL)
return;
de->de_start = start;
de->de_stop = stop;
+ de->de_config_name = strdup(cfg->dvr_config_name);
de->de_creator = strdup(creator);
de->de_title = strdup(title);
de->de_pri = dvr_pri2val(htsmsg_get_str(c, "pri"));
if(htsmsg_get_s32(c, "start_extra", &d))
- de->de_start_extra = dvr_extra_time_pre;
+ de->de_start_extra = cfg->dvr_extra_time_pre;
else
de->de_start_extra = d;
if(htsmsg_get_s32(c, "stop_extra", &d))
- de->de_stop_extra = dvr_extra_time_post;
+ de->de_stop_extra = cfg->dvr_extra_time_post;
else
de->de_stop_extra = d;
htsmsg_add_s32(m, "start_extra", de->de_start_extra);
htsmsg_add_s32(m, "stop_extra", de->de_stop_extra);
+ htsmsg_add_str(m, "config_name", de->de_config_name);
+
htsmsg_add_str(m, "creator", de->de_creator);
if(de->de_filename != NULL)
static void
dvr_stop_recording(dvr_entry_t *de, int stopcode)
{
+ dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name);
+
dvr_rec_unsubscribe(de, stopcode);
de->de_sched_state = DVR_COMPLETED;
dvr_entry_notify(de);
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
- de->de_stop + dvr_retention_days * 86400);
+ de->de_stop + cfg->dvr_retention_days * 86400);
}
void
dvr_init(void)
{
- htsmsg_t *m;
+ htsmsg_t *m, *l;
+ htsmsg_field_t *f;
+ const char *s;
char buf[500];
const char *homedir;
struct stat st;
uint32_t u32;
+ dvr_config_t *cfg;
dvr_iov_max = sysconf(_SC_IOV_MAX);
/* Default settings */
- dvr_retention_days = 31;
- dvr_format = strdup("matroska");
- dvr_file_postfix = strdup("mkv");
+ LIST_INIT(&dvrconfigs);
+ cfg = dvr_config_create("");
/* Override settings with config */
- dvr_flags = DVR_TAG_FILES;
+ l = hts_settings_load("dvr");
+ if(l != NULL) {
+ HTSMSG_FOREACH(f, l) {
+ m = htsmsg_get_map_by_field(f);
+ if(m == NULL)
+ continue;
- if((m = hts_settings_load("dvr/config")) != NULL) {
+ s = htsmsg_get_str(m, "config_name");
+ cfg = dvr_config_find_by_name(s);
+ if(cfg == NULL)
+ cfg = dvr_config_create(s);
- htsmsg_get_s32(m, "pre-extra-time", &dvr_extra_time_pre);
- htsmsg_get_s32(m, "post-extra-time", &dvr_extra_time_post);
- htsmsg_get_u32(m, "retention-days", &dvr_retention_days);
- tvh_str_set(&dvr_storage, htsmsg_get_str(m, "storage"));
+ htsmsg_get_s32(m, "pre-extra-time", &cfg->dvr_extra_time_pre);
+ htsmsg_get_s32(m, "post-extra-time", &cfg->dvr_extra_time_post);
+ htsmsg_get_u32(m, "retention-days", &cfg->dvr_retention_days);
+ tvh_str_set(&cfg->dvr_storage, htsmsg_get_str(m, "storage"));
- if(!htsmsg_get_u32(m, "day-dir", &u32) && u32)
- dvr_flags |= DVR_DIR_PER_DAY;
+ if(!htsmsg_get_u32(m, "day-dir", &u32) && u32)
+ cfg->dvr_flags |= DVR_DIR_PER_DAY;
- if(!htsmsg_get_u32(m, "channel-dir", &u32) && u32)
- dvr_flags |= DVR_DIR_PER_CHANNEL;
+ if(!htsmsg_get_u32(m, "channel-dir", &u32) && u32)
+ cfg->dvr_flags |= DVR_DIR_PER_CHANNEL;
- if(!htsmsg_get_u32(m, "channel-in-title", &u32) && u32)
- dvr_flags |= DVR_CHANNEL_IN_TITLE;
+ if(!htsmsg_get_u32(m, "channel-in-title", &u32) && u32)
+ cfg->dvr_flags |= DVR_CHANNEL_IN_TITLE;
- if(!htsmsg_get_u32(m, "date-in-title", &u32) && u32)
- dvr_flags |= DVR_DATE_IN_TITLE;
+ if(!htsmsg_get_u32(m, "date-in-title", &u32) && u32)
+ cfg->dvr_flags |= DVR_DATE_IN_TITLE;
- if(!htsmsg_get_u32(m, "time-in-title", &u32) && u32)
- dvr_flags |= DVR_TIME_IN_TITLE;
-
- if(!htsmsg_get_u32(m, "whitespace-in-title", &u32) && u32)
- dvr_flags |= DVR_WHITESPACE_IN_TITLE;
+ if(!htsmsg_get_u32(m, "time-in-title", &u32) && u32)
+ cfg->dvr_flags |= DVR_TIME_IN_TITLE;
+
+ if(!htsmsg_get_u32(m, "whitespace-in-title", &u32) && u32)
+ cfg->dvr_flags |= DVR_WHITESPACE_IN_TITLE;
- if(!htsmsg_get_u32(m, "title-dir", &u32) && u32)
- dvr_flags |= DVR_DIR_PER_TITLE;
+ if(!htsmsg_get_u32(m, "title-dir", &u32) && u32)
+ cfg->dvr_flags |= DVR_DIR_PER_TITLE;
- if(!htsmsg_get_u32(m, "episode-in-title", &u32) && u32)
- dvr_flags |= DVR_EPISODE_IN_TITLE;
+ if(!htsmsg_get_u32(m, "episode-in-title", &u32) && u32)
+ cfg->dvr_flags |= DVR_EPISODE_IN_TITLE;
- if(!htsmsg_get_u32(m, "tag-files", &u32) && !u32)
- dvr_flags &= ~DVR_TAG_FILES;
-
- tvh_str_set(&dvr_postproc, htsmsg_get_str(m, "postproc"));
+ if(!htsmsg_get_u32(m, "tag-files", &u32) && !u32)
+ cfg->dvr_flags &= ~DVR_TAG_FILES;
+
+ tvh_str_set(&cfg->dvr_postproc, htsmsg_get_str(m, "postproc"));
+ }
- htsmsg_destroy(m);
+ htsmsg_destroy(l);
}
- if(dvr_storage == NULL) {
- /* Try to figure out a good place to put them videos */
-
- homedir = getenv("HOME");
-
- if(homedir != NULL) {
- snprintf(buf, sizeof(buf), "%s/Videos", homedir);
- if(stat(buf, &st) == 0 && S_ISDIR(st.st_mode))
- dvr_storage = strdup(buf);
-
- else if(stat(homedir, &st) == 0 && S_ISDIR(st.st_mode))
- dvr_storage = strdup(homedir);
- else
- dvr_storage = strdup(getcwd(buf, sizeof(buf)));
+ LIST_FOREACH(cfg, &dvrconfigs, config_link) {
+ if(cfg->dvr_storage == NULL || !strlen(cfg->dvr_storage)) {
+ /* Try to figure out a good place to put them videos */
+
+ homedir = getenv("HOME");
+
+ if(homedir != NULL) {
+ snprintf(buf, sizeof(buf), "%s/Videos", homedir);
+ if(stat(buf, &st) == 0 && S_ISDIR(st.st_mode))
+ cfg->dvr_storage = strdup(buf);
+
+ else if(stat(homedir, &st) == 0 && S_ISDIR(st.st_mode))
+ cfg->dvr_storage = strdup(homedir);
+ else
+ cfg->dvr_storage = strdup(getcwd(buf, sizeof(buf)));
+ }
+
+ tvhlog(LOG_WARNING, "dvr",
+ "Output directory for video recording is not yet configured "
+ "for DVR configuration \"%s\". "
+ "Defaulting to to \"%s\". "
+ "This can be changed from the web user interface.",
+ cfg->dvr_config_name, cfg->dvr_storage);
}
-
- tvhlog(LOG_WARNING, "dvr",
- "Output directory for video recording is not yet configured. "
- "Defaulting to to \"%s\". "
- "This can be changed from the web user interface.",
- dvr_storage);
}
dvr_autorec_init();
dvr_db_load();
}
+/**
+ * find a dvr config by name, return NULL if not found
+ */
+dvr_config_t *
+dvr_config_find_by_name(const char *name)
+{
+ dvr_config_t *cfg;
+
+ if (name == NULL)
+ name = "";
+
+ LIST_FOREACH(cfg, &dvrconfigs, config_link)
+ if (!strcmp(name, cfg->dvr_config_name))
+ return cfg;
+
+ return NULL;
+}
+
+/**
+ * find a dvr config by name, return the default config if not found
+ */
+dvr_config_t *
+dvr_config_find_by_name_default(const char *name)
+{
+ dvr_config_t *cfg;
+
+ cfg = dvr_config_find_by_name(name);
+
+ if (cfg == NULL) {
+ tvhlog(LOG_WARNING, "dvr", "Configuration '%s' not found", name);
+ cfg = dvr_config_find_by_name("");
+ }
+
+ if (cfg == NULL) {
+ cfg = dvr_config_create("");
+ }
+
+ return cfg;
+}
+
+/**
+ * create a new named dvr config; the caller is responsible
+ * to avoid duplicates
+ */
+dvr_config_t *
+dvr_config_create(const char *name)
+{
+ dvr_config_t *cfg;
+
+ if (name == NULL)
+ name = "";
+
+ tvhlog(LOG_INFO, "dvr", "Creating new configuration '%s'", name);
+
+ cfg = calloc(1, sizeof(dvr_config_t));
+ cfg->dvr_config_name = strdup(name);
+ cfg->dvr_retention_days = 31;
+ cfg->dvr_format = strdup("matroska");
+ cfg->dvr_file_postfix = strdup("mkv");
+ cfg->dvr_flags = DVR_TAG_FILES;
+
+ LIST_INSERT_HEAD(&dvrconfigs, cfg, config_link);
+
+ return LIST_FIRST(&dvrconfigs);
+}
+
+/**
+ *
+ */
+void
+dvr_config_delete(const char *name)
+{
+ dvr_config_t *cfg;
+
+ if (name == NULL || strlen(name) == 0) {
+ tvhlog(LOG_WARNING,"dvr","Attempt to delete default config ignored");
+ return;
+ }
+
+ cfg = dvr_config_find_by_name(name);
+ if (cfg != NULL) {
+ tvhlog(LOG_INFO, "dvr", "Deleting configuration '%s'",
+ cfg->dvr_config_name);
+ hts_settings_remove("dvr/config%s", cfg->dvr_config_name);
+ LIST_REMOVE(cfg, config_link);
+ dvrconfig_changed();
+ }
+}
+
/**
*
*/
static void
-dvr_save(void)
+dvr_save(dvr_config_t *cfg)
{
htsmsg_t *m = htsmsg_create_map();
- htsmsg_add_str(m, "storage", dvr_storage);
- htsmsg_add_u32(m, "retention-days", dvr_retention_days);
- htsmsg_add_u32(m, "pre-extra-time", dvr_extra_time_pre);
- htsmsg_add_u32(m, "post-extra-time", dvr_extra_time_post);
- htsmsg_add_u32(m, "day-dir", !!(dvr_flags & DVR_DIR_PER_DAY));
- htsmsg_add_u32(m, "channel-dir", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
- htsmsg_add_u32(m, "channel-in-title", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
- htsmsg_add_u32(m, "date-in-title", !!(dvr_flags & DVR_DATE_IN_TITLE));
- htsmsg_add_u32(m, "time-in-title", !!(dvr_flags & DVR_TIME_IN_TITLE));
- htsmsg_add_u32(m, "whitespace-in-title", !!(dvr_flags & DVR_WHITESPACE_IN_TITLE));
- htsmsg_add_u32(m, "title-dir", !!(dvr_flags & DVR_DIR_PER_TITLE));
- htsmsg_add_u32(m, "episode-in-title", !!(dvr_flags & DVR_EPISODE_IN_TITLE));
- htsmsg_add_u32(m, "tag-files", !!(dvr_flags & DVR_TAG_FILES));
- if(dvr_postproc != NULL)
- htsmsg_add_str(m, "postproc", dvr_postproc);
-
- hts_settings_save(m, "dvr/config");
+ if (cfg->dvr_config_name != NULL && strlen(cfg->dvr_config_name) != 0)
+ htsmsg_add_str(m, "config_name", cfg->dvr_config_name);
+ htsmsg_add_str(m, "storage", cfg->dvr_storage);
+ htsmsg_add_u32(m, "retention-days", cfg->dvr_retention_days);
+ htsmsg_add_u32(m, "pre-extra-time", cfg->dvr_extra_time_pre);
+ htsmsg_add_u32(m, "post-extra-time", cfg->dvr_extra_time_post);
+ htsmsg_add_u32(m, "day-dir", !!(cfg->dvr_flags & DVR_DIR_PER_DAY));
+ htsmsg_add_u32(m, "channel-dir", !!(cfg->dvr_flags & DVR_DIR_PER_CHANNEL));
+ htsmsg_add_u32(m, "channel-in-title", !!(cfg->dvr_flags & DVR_CHANNEL_IN_TITLE));
+ htsmsg_add_u32(m, "date-in-title", !!(cfg->dvr_flags & DVR_DATE_IN_TITLE));
+ htsmsg_add_u32(m, "time-in-title", !!(cfg->dvr_flags & DVR_TIME_IN_TITLE));
+ htsmsg_add_u32(m, "whitespace-in-title", !!(cfg->dvr_flags & DVR_WHITESPACE_IN_TITLE));
+ htsmsg_add_u32(m, "title-dir", !!(cfg->dvr_flags & DVR_DIR_PER_TITLE));
+ htsmsg_add_u32(m, "episode-in-title", !!(cfg->dvr_flags & DVR_EPISODE_IN_TITLE));
+ htsmsg_add_u32(m, "tag-files", !!(cfg->dvr_flags & DVR_TAG_FILES));
+ if(cfg->dvr_postproc != NULL)
+ htsmsg_add_str(m, "postproc", cfg->dvr_postproc);
+
+ hts_settings_save(m, "dvr/config%s", cfg->dvr_config_name);
htsmsg_destroy(m);
+
+ dvrconfig_changed();
}
/**
*
*/
void
-dvr_storage_set(const char *storage)
+dvr_storage_set(dvr_config_t *cfg, const char *storage)
{
- if(!strcmp(dvr_storage, storage))
+ if(cfg->dvr_storage != NULL && !strcmp(cfg->dvr_storage, storage))
return;
- tvh_str_set(&dvr_storage, storage);
- dvr_save();
+ tvh_str_set(&cfg->dvr_storage, storage);
+ dvr_save(cfg);
}
/**
*
*/
void
-dvr_postproc_set(const char *postproc)
+dvr_postproc_set(dvr_config_t *cfg, const char *postproc)
{
- if(dvr_postproc != NULL && !strcmp(dvr_postproc, postproc))
+ if(cfg->dvr_postproc != NULL && !strcmp(cfg->dvr_postproc, postproc))
return;
- tvh_str_set(&dvr_postproc, !strcmp(postproc, "") ? NULL : postproc);
- dvr_save();
+ tvh_str_set(&cfg->dvr_postproc, !strcmp(postproc, "") ? NULL : postproc);
+ dvr_save(cfg);
}
*
*/
void
-dvr_retention_set(int days)
+dvr_retention_set(dvr_config_t *cfg, int days)
{
dvr_entry_t *de;
- if(days < 1 || dvr_retention_days == days)
+ if(days < 1 || cfg->dvr_retention_days == days)
return;
- dvr_retention_days = days;
+ cfg->dvr_retention_days = days;
/* Also, rearm all timres */
LIST_FOREACH(de, &dvrentries, de_global_link)
if(de->de_sched_state == DVR_COMPLETED)
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
- de->de_stop + dvr_retention_days * 86400);
- dvr_save();
+ de->de_stop + cfg->dvr_retention_days * 86400);
+ dvr_save(cfg);
}
*
*/
void
-dvr_flags_set(int flags)
+dvr_flags_set(dvr_config_t *cfg, int flags)
{
- if(dvr_flags == flags)
+ if(cfg->dvr_flags == flags)
return;
- dvr_flags = flags;
- dvr_save();
+ cfg->dvr_flags = flags;
+ dvr_save(cfg);
}
*
*/
void
-dvr_extra_time_pre_set(int d)
+dvr_extra_time_pre_set(dvr_config_t *cfg, int d)
{
- if(dvr_extra_time_pre == d)
+ if(cfg->dvr_extra_time_pre == d)
return;
- dvr_extra_time_pre = d;
- dvr_save();
+
+ cfg->dvr_extra_time_pre = d;
+ dvr_save(cfg);
}
*
*/
void
-dvr_extra_time_post_set(int d)
+dvr_extra_time_post_set(dvr_config_t *cfg, int d)
{
- if(dvr_extra_time_post == d)
+ if(cfg->dvr_extra_time_post == d)
return;
- dvr_extra_time_post = d;
- dvr_save();
+
+ cfg->dvr_extra_time_post = d;
+ dvr_save(cfg);
}
*
*/
static void *dvr_thread(void *aux);
-static void dvr_spawn_postproc(dvr_entry_t *de);
+static void dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc);
static void dvr_thread_epilog(dvr_entry_t *de);
* Replace various chars with a dash
*/
static void
-cleanupfilename(char *s)
+cleanupfilename(char *s, int dvr_flags)
{
int i, len = strlen(s);
for(i = 0; i < len; i++) {
struct stat st;
char *filename;
struct tm tm;
+ dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name);
filename = strdup(de->de_ititle);
- cleanupfilename(filename);
+ cleanupfilename(filename,cfg->dvr_flags);
- snprintf(path, sizeof(path), "%s", dvr_storage);
+ snprintf(path, sizeof(path), "%s", cfg->dvr_storage);
/* Append per-day directory */
- if(dvr_flags & DVR_DIR_PER_DAY) {
+ if(cfg->dvr_flags & DVR_DIR_PER_DAY) {
localtime_r(&de->de_start, &tm);
strftime(fullname, sizeof(fullname), "%F", &tm);
- cleanupfilename(fullname);
+ cleanupfilename(fullname,cfg->dvr_flags);
snprintf(path + strlen(path), sizeof(path) - strlen(path),
"/%s", fullname);
}
/* Append per-channel directory */
- if(dvr_flags & DVR_DIR_PER_CHANNEL) {
+ if(cfg->dvr_flags & DVR_DIR_PER_CHANNEL) {
char *chname = strdup(de->de_channel->ch_name);
- cleanupfilename(chname);
+ cleanupfilename(chname,cfg->dvr_flags);
snprintf(path + strlen(path), sizeof(path) - strlen(path),
"/%s", chname);
free(chname);
/* Append per-title directory */
- if(dvr_flags & DVR_DIR_PER_TITLE) {
+ if(cfg->dvr_flags & DVR_DIR_PER_TITLE) {
char *title = strdup(de->de_title);
- cleanupfilename(title);
+ cleanupfilename(title,cfg->dvr_flags);
snprintf(path + strlen(path), sizeof(path) - strlen(path),
"/%s", title);
free(title);
/* Construct final name */
snprintf(fullname, sizeof(fullname), "%s/%s.%s",
- path, filename, dvr_file_postfix);
+ path, filename, cfg->dvr_file_postfix);
while(1) {
if(stat(fullname, &st) == -1) {
tally++;
snprintf(fullname, sizeof(fullname), "%s/%s-%d.%s",
- path, filename, tally, dvr_file_postfix);
+ path, filename, tally, cfg->dvr_file_postfix);
}
tvh_str_set(&de->de_filename, fullname);
const source_info_t *si = &ss->ss_si;
const streaming_start_component_t *ssc;
int i;
+ dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name);
if(pvr_generate_filename(de) != 0) {
dvr_rec_fatal_error(de, "Unable to create directories");
}
de->de_mkmux = mk_mux_create(de->de_filename, ss, de,
- !!(dvr_flags & DVR_TAG_FILES));
+ !!(cfg->dvr_flags & DVR_TAG_FILES));
if(de->de_mkmux == NULL) {
dvr_rec_fatal_error(de, "Unable to open file");
*
*/
static void
-dvr_spawn_postproc(dvr_entry_t *de)
+dvr_spawn_postproc(dvr_entry_t *de, const char *dvr_postproc)
{
char *fmap[256];
char **args;
mk_mux_close(de->de_mkmux);
de->de_mkmux = NULL;
- if(dvr_postproc)
- dvr_spawn_postproc(de);
+ dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name);
+ if(cfg->dvr_postproc)
+ dvr_spawn_postproc(de,cfg->dvr_postproc);
}
event_t *e;
dvr_entry_t *de;
dvr_entry_sched_state_t dvr_status;
+ const char *dvr_config_name;
if(htsmsg_get_u32(in, "eventId", &eventid))
return htsp_error("Missing argument 'eventId'");
if((e = epg_event_find_by_id(eventid)) == NULL)
return htsp_error("Event does not exist");
+
+ if((dvr_config_name = htsmsg_get_str(in, "configName")) == NULL)
+ dvr_config_name = "";
//create the dvr entry
- de = dvr_entry_create_by_event(e,
+ de = dvr_entry_create_by_event(dvr_config_name,e,
htsp->htsp_username ?
htsp->htsp_username : "anonymous",
NULL, DVR_PRIO_NORMAL);
{
htsmsg_t *out;
struct statvfs diskdata;
+ dvr_config_t *cfg = dvr_config_find_by_name_default("");
- if(statvfs(dvr_storage,&diskdata) == -1)
+ if(statvfs(cfg->dvr_storage,&diskdata) == -1)
return htsp_error("Unable to stat path");
out = htsmsg_create_map();
LIST_HEAD(channel_list, channel);
LIST_HEAD(event_list, event);
RB_HEAD(event_tree, event);
+LIST_HEAD(dvr_config_list, dvr_config);
LIST_HEAD(dvr_entry_list, dvr_entry);
TAILQ_HEAD(ref_update_queue, ref_update);
LIST_HEAD(th_transport_list, th_transport);
pthread_mutex_lock(&global_lock);
- if(!strcmp(op, "listTags")) {
+ if(op != NULL && !strcmp(op, "listTags")) {
out = htsmsg_create_map();
array = htsmsg_create_list();
}
+/**
+ *
+ */
+static int
+extjs_confignames(http_connection_t *hc, const char *remain, void *opaque)
+{
+ htsbuf_queue_t *hq = &hc->hc_reply;
+ const char *op = http_arg_get(&hc->hc_req_args, "op");
+ htsmsg_t *out, *array, *e;
+ dvr_config_t *cfg;
+
+ pthread_mutex_lock(&global_lock);
+
+ if(op != NULL && !strcmp(op, "list")) {
+
+ out = htsmsg_create_map();
+ array = htsmsg_create_list();
+
+ LIST_FOREACH(cfg, &dvrconfigs, config_link) {
+ e = htsmsg_create_map();
+ htsmsg_add_str(e, "identifier", cfg->dvr_config_name);
+ if (strlen(cfg->dvr_config_name) == 0)
+ htsmsg_add_str(e, "name", "(default)");
+ else
+ htsmsg_add_str(e, "name", cfg->dvr_config_name);
+ htsmsg_add_msg(array, NULL, e);
+ }
+
+ htsmsg_add_msg(out, "entries", array);
+
+ } else {
+ pthread_mutex_unlock(&global_lock);
+ return HTTP_STATUS_BAD_REQUEST;
+ }
+
+ pthread_mutex_unlock(&global_lock);
+
+ htsmsg_json_serialize(out, hq, 0);
+ htsmsg_destroy(out);
+ http_output_content(hc, "text/x-json; charset=UTF-8");
+ return 0;
+
+}
+
/**
*
*/
dvr_entry_t *de;
const char *s;
int flags = 0;
+ dvr_config_t *cfg;
if(op == NULL)
op = "loadSettings";
}
if(!strcmp(op, "recordEvent")) {
- s = http_arg_get(&hc->hc_req_args, "eventId");
+ const char *config_name = http_arg_get(&hc->hc_req_args, "config_name");
+
+ s = http_arg_get(&hc->hc_req_args, "eventId");
if((e = epg_event_find_by_id(atoi(s))) == NULL) {
pthread_mutex_unlock(&global_lock);
return HTTP_STATUS_BAD_REQUEST;
}
- dvr_entry_create_by_event(e, hc->hc_representative, NULL, DVR_PRIO_NORMAL);
+ dvr_entry_create_by_event(config_name,
+ e, hc->hc_representative, NULL, DVR_PRIO_NORMAL);
out = htsmsg_create_map();
htsmsg_add_u32(out, "success", 1);
} else if(!strcmp(op, "createEntry")) {
+ const char *config_name = http_arg_get(&hc->hc_req_args, "config_name");
const char *title = http_arg_get(&hc->hc_req_args, "title");
const char *datestr = http_arg_get(&hc->hc_req_args, "date");
const char *startstr = http_arg_get(&hc->hc_req_args, "starttime");
if(stop < start)
stop += 86400;
- dvr_entry_create(ch, start, stop, title, NULL, hc->hc_representative,
+ dvr_entry_create(config_name,
+ ch, start, stop, title, NULL, hc->hc_representative,
NULL, NULL, 0, dvr_pri2val(pri));
out = htsmsg_create_map();
- dvr_autorec_add(http_arg_get(&hc->hc_req_args, "title"),
+ dvr_autorec_add(http_arg_get(&hc->hc_req_args, "config_name"),
+ http_arg_get(&hc->hc_req_args, "title"),
http_arg_get(&hc->hc_req_args, "channel"),
http_arg_get(&hc->hc_req_args, "tag"),
cgrp ? epg_content_group_find_by_name(cgrp) : 0,
} else if(!strcmp(op, "loadSettings")) {
+ s = http_arg_get(&hc->hc_req_args, "config_name");
+ if (s == NULL)
+ s = "";
+ cfg = dvr_config_find_by_name_default(s);
+
r = htsmsg_create_map();
- htsmsg_add_str(r, "storage", dvr_storage);
- if(dvr_postproc != NULL)
- htsmsg_add_str(r, "postproc", dvr_postproc);
- htsmsg_add_u32(r, "retention", dvr_retention_days);
- htsmsg_add_u32(r, "preExtraTime", dvr_extra_time_pre);
- htsmsg_add_u32(r, "postExtraTime", dvr_extra_time_post);
- htsmsg_add_u32(r, "dayDirs", !!(dvr_flags & DVR_DIR_PER_DAY));
- htsmsg_add_u32(r, "channelDirs", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
- htsmsg_add_u32(r, "channelInTitle", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
- htsmsg_add_u32(r, "dateInTitle", !!(dvr_flags & DVR_DATE_IN_TITLE));
- htsmsg_add_u32(r, "timeInTitle", !!(dvr_flags & DVR_TIME_IN_TITLE));
- htsmsg_add_u32(r, "whitespaceInTitle", !!(dvr_flags & DVR_WHITESPACE_IN_TITLE));
- htsmsg_add_u32(r, "titleDirs", !!(dvr_flags & DVR_DIR_PER_TITLE));
- htsmsg_add_u32(r, "episodeInTitle", !!(dvr_flags & DVR_EPISODE_IN_TITLE));
- htsmsg_add_u32(r, "cleanTitle", !!(dvr_flags & DVR_CLEAN_TITLE));
- htsmsg_add_u32(r, "tagFiles", !!(dvr_flags & DVR_TAG_FILES));
+ htsmsg_add_str(r, "storage", cfg->dvr_storage);
+ if(cfg->dvr_postproc != NULL)
+ htsmsg_add_str(r, "postproc", cfg->dvr_postproc);
+ htsmsg_add_u32(r, "retention", cfg->dvr_retention_days);
+ htsmsg_add_u32(r, "preExtraTime", cfg->dvr_extra_time_pre);
+ htsmsg_add_u32(r, "postExtraTime", cfg->dvr_extra_time_post);
+ htsmsg_add_u32(r, "dayDirs", !!(cfg->dvr_flags & DVR_DIR_PER_DAY));
+ htsmsg_add_u32(r, "channelDirs", !!(cfg->dvr_flags & DVR_DIR_PER_CHANNEL));
+ htsmsg_add_u32(r, "channelInTitle", !!(cfg->dvr_flags & DVR_CHANNEL_IN_TITLE));
+ htsmsg_add_u32(r, "dateInTitle", !!(cfg->dvr_flags & DVR_DATE_IN_TITLE));
+ htsmsg_add_u32(r, "timeInTitle", !!(cfg->dvr_flags & DVR_TIME_IN_TITLE));
+ htsmsg_add_u32(r, "whitespaceInTitle", !!(cfg->dvr_flags & DVR_WHITESPACE_IN_TITLE));
+ htsmsg_add_u32(r, "titleDirs", !!(cfg->dvr_flags & DVR_DIR_PER_TITLE));
+ htsmsg_add_u32(r, "episodeInTitle", !!(cfg->dvr_flags & DVR_EPISODE_IN_TITLE));
+ htsmsg_add_u32(r, "cleanTitle", !!(cfg->dvr_flags & DVR_CLEAN_TITLE));
+ htsmsg_add_u32(r, "tagFiles", !!(cfg->dvr_flags & DVR_TAG_FILES));
out = json_single_record(r, "dvrSettings");
} else if(!strcmp(op, "saveSettings")) {
+ s = http_arg_get(&hc->hc_req_args, "config_name");
+ cfg = dvr_config_find_by_name(s);
+ if (cfg == NULL)
+ cfg = dvr_config_create(s);
+
+ tvhlog(LOG_INFO,"dvr","Saving configuration '%s'", cfg->dvr_config_name);
+
if((s = http_arg_get(&hc->hc_req_args, "storage")) != NULL)
- dvr_storage_set(s);
+ dvr_storage_set(cfg,s);
if((s = http_arg_get(&hc->hc_req_args, "postproc")) != NULL)
- dvr_postproc_set(s);
+ dvr_postproc_set(cfg,s);
if((s = http_arg_get(&hc->hc_req_args, "retention")) != NULL)
- dvr_retention_set(atoi(s));
+ dvr_retention_set(cfg,atoi(s));
if((s = http_arg_get(&hc->hc_req_args, "preExtraTime")) != NULL)
- dvr_extra_time_pre_set(atoi(s));
+ dvr_extra_time_pre_set(cfg,atoi(s));
if((s = http_arg_get(&hc->hc_req_args, "postExtraTime")) != NULL)
- dvr_extra_time_post_set(atoi(s));
+ dvr_extra_time_post_set(cfg,atoi(s));
if(http_arg_get(&hc->hc_req_args, "dayDirs") != NULL)
flags |= DVR_DIR_PER_DAY;
if(http_arg_get(&hc->hc_req_args, "tagFiles") != NULL)
flags |= DVR_TAG_FILES;
- dvr_flags_set(flags);
+ dvr_flags_set(cfg,flags);
+
+ out = htsmsg_create_map();
+ htsmsg_add_u32(out, "success", 1);
+
+ } else if(!strcmp(op, "deleteSettings")) {
+
+ s = http_arg_get(&hc->hc_req_args, "config_name");
+ dvr_config_delete(s);
out = htsmsg_create_map();
htsmsg_add_u32(out, "success", 1);
htsmsg_add_str(m, "chicon", de->de_channel->ch_icon);
}
+ htsmsg_add_str(m, "config_name", de->de_config_name);
+
if(de->de_title != NULL)
htsmsg_add_str(m, "title", de->de_title);
http_path_add("/channels", NULL, extjs_channels, ACCESS_WEB_INTERFACE);
http_path_add("/xmltv", NULL, extjs_xmltv, ACCESS_WEB_INTERFACE);
http_path_add("/channeltags", NULL, extjs_channeltags, ACCESS_WEB_INTERFACE);
+ http_path_add("/confignames", NULL, extjs_confignames, ACCESS_WEB_INTERFACE);
http_path_add("/epg", NULL, extjs_epg, ACCESS_WEB_INTERFACE);
http_path_add("/dvr", NULL, extjs_dvr, ACCESS_WEB_INTERFACE);
http_path_add("/dvrlist", NULL, extjs_dvrlist, ACCESS_WEB_INTERFACE);
de = dvr_entry_find_by_event(e);
if((http_arg_get(&hc->hc_req_args, "rec")) != NULL) {
- de = dvr_entry_create_by_event(e, hc->hc_username ?: "anonymous", NULL,
+ de = dvr_entry_create_by_event("", e, hc->hc_username ?: "anonymous", NULL,
DVR_PRIO_NORMAL);
} else if(de != NULL && (http_arg_get(&hc->hc_req_args, "cancel")) != NULL) {
de = dvr_entry_cancel(de);
channeltags: true,
autorec: true,
dvrdb: true,
+ dvrconfig: true,
channels: true
});
}, Ext.util.Observable);
]
});
+/**
+ * Configuration names
+ */
+tvheadend.configNames = new Ext.data.JsonStore({
+ autoLoad:true,
+ root:'entries',
+ fields: ['identifier','name'],
+ id: 'identifier',
+ url:'confignames',
+ baseParams: {
+ op: 'list'
+ }
+});
+
+tvheadend.configNames.setDefaultSort('name', 'ASC');
+
+tvheadend.comet.on('dvrconfig', function(m) {
+ if(m.reload != null)
+ tvheadend.configNames.reload();
+});
+
+
/**
*
*/
hidden:true,
dataIndex: 'creator'
},{
+ width: 200,
+ id:'config_name',
+ header: "DVR Configuration",
+ renderer: function(value, metadata, record, row, col, store) {
+ if (!value) {
+ return '<span class="tvh-grid-unset">(default)</span>';
+ } else {
+ return value;
+ }
+ },
+ dataIndex: 'config_name'
+ },{
width: 200,
id:'status',
header: "Status",
allowBlank: false,
fieldLabel: 'Title',
name: 'title'
- }
+ },
+ new Ext.form.ComboBox({
+ store: tvheadend.configNames,
+ triggerAction: 'all',
+ mode: 'local',
+ fieldLabel: 'DVR Configuration',
+ valueField: 'identifier',
+ displayField: 'name',
+ name: 'config_name',
+ emptyText: '(default)',
+ value: '',
+ editable: false
+ })
],
buttons: [{
text: 'Create',
items: panel
});
win.show();
+ new Ext.form.ComboBox({
+ store: tvheadend.configNames,
+ triggerAction: 'all',
+ mode: 'local',
+ fieldLabel: 'DVR Configuration',
+ valueField: 'identifier',
+ displayField: 'name',
+ name: 'config_name',
+ emptyText: '(default)',
+ value: '',
+ editable: false
+ })
};
valueField: 'identifier',
displayField: 'name'
})
+ },{
+ header: "DVR Configuration",
+ dataIndex: 'config_name',
+ renderer: function(value, metadata, record, row, col, store) {
+ if (!value) {
+ return '<span class="tvh-grid-unset">(default)</span>';
+ } else {
+ return value;
+ }
+ },
+ editor: new Ext.form.ComboBox({
+ store: tvheadend.configNames,
+ triggerAction: 'all',
+ mode: 'local',
+ valueField: 'identifier',
+ displayField: 'name',
+ name: 'config_name',
+ emptyText: '(default)',
+ editable: false
+ })
},{
header: "Created by",
dataIndex: 'creator',
{name: 'chicon'},
{name: 'start', type: 'date', dateFormat: 'U' /* unix time */},
{name: 'end', type: 'date', dateFormat: 'U' /* unix time */},
+ {name: 'config_name'},
{name: 'status'},
{name: 'schedstate'},
{name: 'creator'},
tvheadend.autorecRecord = Ext.data.Record.create([
'enabled','title','channel','tag','creator','contentgrp','comment',
- 'weekdays', 'pri', 'approx_time'
+ 'weekdays', 'pri', 'approx_time', 'config_name'
]);
'preExtraTime', 'postExtraTime', 'whitespaceInTitle',
'titleDirs', 'episodeInTitle', 'cleanTitle', 'tagFiles']);
+ var confcombo = new Ext.form.ComboBox({
+ store: tvheadend.configNames,
+ triggerAction: 'all',
+ mode: 'local',
+ displayField: 'name',
+ name: 'config_name',
+ emptyText: '(default)',
+ value: '',
+ editable: true
+ });
+
+ var delButton = new Ext.Toolbar.Button({
+ tooltip: 'Delete named configuration',
+ iconCls:'remove',
+ text: "Delete configuration",
+ handler: deleteConfiguration,
+ disabled: true
+ });
+
var confpanel = new Ext.FormPanel({
title:'Digital Video Recorder',
iconCls: 'drive',
fieldLabel: 'Post-processor command',
name: 'postproc'
}],
- tbar: [{
- tooltip: 'Save changes made to channel configuration below',
+ tbar: [confcombo, {
+ tooltip: 'Save changes made to dvr configuration below',
iconCls:'save',
text: "Save configuration",
handler: saveChanges
- }, '->', {
+ }, delButton, '->', {
text: 'Help',
handler: function() {
new tvheadend.help('DVR configuration',
'config_dvr.html');
}
}]
-
});
-
- confpanel.on('render', function() {
+
+ function loadConfig() {
confpanel.getForm().load({
url:'dvr',
- params:{'op':'loadSettings'},
+ params:{'op':'loadSettings','config_name':confcombo.getValue()},
success:function(form, action) {
confpanel.enable();
}
});
+ }
+
+ confcombo.on('select', function() {
+ if (confcombo.getValue() == '')
+ delButton.disable();
+ else
+ delButton.enable();
+ loadConfig();
+ });
+
+ confpanel.on('render', function() {
+ loadConfig();
});
function saveChanges() {
+ var config_name = confcombo.getValue();
confpanel.getForm().submit({
url:'dvr',
- params:{'op':'saveSettings'},
+ params:{'op':'saveSettings','config_name':config_name},
waitMsg:'Saving Data...',
+ success: function(form, action) {
+ confcombo.setValue(config_name);
+ confcombo.fireEvent('select');
+ },
failure: function(form, action) {
Ext.Msg.alert('Save failed', action.result.errormsg);
}
});
}
+ function deleteConfiguration() {
+ if (confcombo.getValue() != "") {
+ Ext.MessageBox.confirm('Message',
+ 'Do you really want to delete DVR configuration \'' +
+ confcombo.getValue() + '\'?',
+ deleteAction);
+ }
+ }
+
+ function deleteAction(btn) {
+ if (btn == 'yes') {
+ confpanel.getForm().submit({
+ url:'dvr',
+ params:{'op':'deleteSettings','config_name':confcombo.getValue()},
+ waitMsg:'Deleting Data...',
+ success: function(form, action) {
+ confcombo.setValue('');
+ confcombo.fireEvent('select');
+ },
+ failure: function(form, action) {
+ Ext.Msg.alert('Delete failed', action.result.errormsg);
+ }
+ });
+ }
+ }
+
return confpanel;
}
'http://akas.imdb.org/find?q=' + event.title + '">Search IMDB</a></div>'
+ var confcombo = new Ext.form.ComboBox({
+ store: tvheadend.configNames,
+ triggerAction: 'all',
+ mode: 'local',
+ valueField: 'identifier',
+ displayField: 'name',
+ name: 'config_name',
+ emptyText: '(default)',
+ value: '',
+ editable: false
+ });
+
var win = new Ext.Window({
title: event.title,
bodyStyle: 'margin: 5px',
height: 300,
constrainHeader: true,
buttons: [
+ confcombo,
new Ext.Button({
handler: recordEvent,
text: "Record program"
function recordEvent() {
Ext.Ajax.request({
url: 'dvr',
- params: {eventId: event.id, op: 'recordEvent'},
+ params: {
+ eventId: event.id,
+ op: 'recordEvent',
+ config_name: confcombo.getValue()
+ },
success:function(response, options) {
win.close();