dvr: fix some webui interface issues
This commit is contained in:
parent
44bbfd4940
commit
1212a2d280
6 changed files with 205 additions and 84 deletions
|
@ -83,20 +83,21 @@ extern struct dvr_config_list dvrconfigs;
|
|||
|
||||
extern struct dvr_entry_list dvrentries;
|
||||
|
||||
#define DVR_DIR_PER_DAY 0x1
|
||||
#define DVR_DIR_PER_CHANNEL 0x2
|
||||
#define DVR_CHANNEL_IN_TITLE 0x4
|
||||
#define DVR_DATE_IN_TITLE 0x8
|
||||
#define DVR_TIME_IN_TITLE 0x10
|
||||
#define DVR_WHITESPACE_IN_TITLE 0x20
|
||||
#define DVR_DIR_PER_TITLE 0x40
|
||||
#define DVR_EPISODE_IN_TITLE 0x80
|
||||
#define DVR_CLEAN_TITLE 0x100
|
||||
#define DVR_TAG_FILES 0x200
|
||||
#define DVR_SKIP_COMMERCIALS 0x400
|
||||
#define DVR_SUBTITLE_IN_TITLE 0x800
|
||||
#define DVR_EPISODE_BEFORE_DATE 0x1000
|
||||
#define DVR_EPISODE_DUPLICATE_DETECTION 0x2000
|
||||
#define DVR_FLAGS_VALID 0x1
|
||||
#define DVR_DIR_PER_DAY 0x2
|
||||
#define DVR_DIR_PER_CHANNEL 0x4
|
||||
#define DVR_CHANNEL_IN_TITLE 0x8
|
||||
#define DVR_DATE_IN_TITLE 0x10
|
||||
#define DVR_TIME_IN_TITLE 0x20
|
||||
#define DVR_WHITESPACE_IN_TITLE 0x40
|
||||
#define DVR_DIR_PER_TITLE 0x80
|
||||
#define DVR_EPISODE_IN_TITLE 0x100
|
||||
#define DVR_CLEAN_TITLE 0x200
|
||||
#define DVR_TAG_FILES 0x400
|
||||
#define DVR_SKIP_COMMERCIALS 0x800
|
||||
#define DVR_SUBTITLE_IN_TITLE 0x1000
|
||||
#define DVR_EPISODE_BEFORE_DATE 0x2000
|
||||
#define DVR_EPISODE_DUPLICATE_DETECTION 0x4000
|
||||
|
||||
typedef enum {
|
||||
DVR_PRIO_IMPORTANT,
|
||||
|
@ -190,7 +191,6 @@ typedef struct dvr_entry {
|
|||
* Recording state (onyl valid if de_sched_state == DVR_RECORDING)
|
||||
*/
|
||||
dvr_rs_state_t de_rec_state;
|
||||
int de_locked;
|
||||
|
||||
/**
|
||||
* Number of errors (only to be modified by the recording thread)
|
||||
|
@ -297,6 +297,12 @@ extern const idclass_t dvr_autorec_entry_class;
|
|||
|
||||
void dvr_make_title(char *output, size_t outlen, dvr_entry_t *de);
|
||||
|
||||
static inline int dvr_config_is_valid(dvr_config_t *cfg)
|
||||
{ return !!(cfg->dvr_flags & DVR_FLAGS_VALID); }
|
||||
|
||||
static inline int dvr_config_is_default(dvr_config_t *cfg)
|
||||
{ return cfg->dvr_config_name == NULL || cfg->dvr_config_name[0] == '\0'; }
|
||||
|
||||
dvr_config_t *dvr_config_find_by_name(const char *name);
|
||||
|
||||
dvr_config_t *dvr_config_find_by_name_default(const char *name);
|
||||
|
@ -310,7 +316,13 @@ void dvr_config_delete(const char *name);
|
|||
|
||||
void dvr_config_save(dvr_config_t *cfg);
|
||||
|
||||
int dvr_entry_get_mc( dvr_entry_t *de);
|
||||
static inline int dvr_entry_is_editable(dvr_entry_t *de)
|
||||
{ return de->de_sched_state == DVR_SCHEDULED; }
|
||||
|
||||
static inline int dvr_entry_is_valid(dvr_entry_t *de)
|
||||
{ return de->de_refcnt > 0; }
|
||||
|
||||
int dvr_entry_get_mc(dvr_entry_t *de);
|
||||
|
||||
void dvr_entry_save(dvr_entry_t *de);
|
||||
|
||||
|
|
210
src/dvr/dvr_db.c
210
src/dvr/dvr_db.c
|
@ -409,7 +409,6 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
dvr_entry_set_timer(de);
|
||||
htsp_dvr_entry_add(de);
|
||||
|
||||
|
@ -728,7 +727,7 @@ static dvr_entry_t *_dvr_entry_update
|
|||
{
|
||||
int save = 0;
|
||||
|
||||
if (de->de_locked)
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return de;
|
||||
|
||||
/* Start/Stop */
|
||||
|
@ -906,7 +905,9 @@ 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)
|
||||
if (de->de_rec_state == DVR_RS_PENDING ||
|
||||
de->de_rec_state == DVR_RS_WAIT_PROGRAM_START ||
|
||||
de->de_filename == NULL)
|
||||
de->de_sched_state = DVR_MISSED_TIME;
|
||||
else
|
||||
_dvr_entry_completed(de);
|
||||
|
@ -919,10 +920,8 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf)
|
|||
dvr_entry_status(de));
|
||||
|
||||
if (saveconf)
|
||||
idnode_changed(&de->de_id);
|
||||
else
|
||||
idnode_notify_simple(&de->de_id);
|
||||
dvr_entry_save(de);
|
||||
idnode_notify_simple(&de->de_id);
|
||||
htsp_dvr_entry_update(de);
|
||||
|
||||
gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de,
|
||||
|
@ -1060,16 +1059,16 @@ dvr_entry_purge(dvr_entry_t *de, int delconf)
|
|||
static void
|
||||
dvr_entry_class_save(idnode_t *self)
|
||||
{
|
||||
dvr_entry_save((dvr_entry_t *)self);
|
||||
dvr_entry_t *de = (dvr_entry_t *)self;
|
||||
dvr_entry_save(de);
|
||||
if (dvr_entry_is_valid(de))
|
||||
dvr_entry_set_timer(de);
|
||||
}
|
||||
|
||||
static void
|
||||
dvr_entry_class_delete(idnode_t *self)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)self;
|
||||
if (de->de_locked)
|
||||
return;
|
||||
dvr_entry_destroy(de, 1);
|
||||
dvr_entry_cancel_delete((dvr_entry_t *)self);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -1083,13 +1082,66 @@ dvr_entry_class_get_title (idnode_t *self)
|
|||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_time_set(dvr_entry_t *de, time_t *v, time_t nv)
|
||||
{
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
if (nv != *v) {
|
||||
*v = nv;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_int_set(dvr_entry_t *de, int *v, int nv)
|
||||
{
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
if (nv != *v) {
|
||||
*v = nv;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_start_set(void *o, const void *v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
return dvr_entry_class_time_set(de, &de->de_start, *(time_t *)v);
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_start_extra_set(void *o, const void *v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
return dvr_entry_class_time_set(de, &de->de_start_extra, *(time_t *)v);
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_stop_set(void *o, const void *_v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
time_t v = *(time_t *)_v;
|
||||
|
||||
if (!dvr_entry_is_editable(de)) {
|
||||
if (v < dispatch_clock)
|
||||
v = dispatch_clock;
|
||||
}
|
||||
if (v < de->de_start)
|
||||
v = de->de_start;
|
||||
return dvr_entry_class_time_set(de, &de->de_stop, v);
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_config_name_set(void *o, const void *v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
dvr_config_t *cfg;
|
||||
|
||||
if (de->de_locked)
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
cfg = v ? dvr_config_find_by_uuid(v) : NULL;
|
||||
if (!cfg)
|
||||
|
@ -1128,11 +1180,14 @@ dvr_entry_class_channel_set(void *o, const void *v)
|
|||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
channel_t *ch;
|
||||
|
||||
if (de->de_locked)
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
ch = v ? channel_find_by_uuid(v) : NULL;
|
||||
if (!de->de_config)
|
||||
if (!de->de_config) {
|
||||
de->de_config = dvr_config_find_by_name_default("");
|
||||
if (de->de_config)
|
||||
LIST_INSERT_HEAD(&de->de_config->dvr_entries, de, de_config_link);
|
||||
}
|
||||
if (ch == NULL) {
|
||||
if (de->de_channel) {
|
||||
LIST_REMOVE(de, de_channel_link);
|
||||
|
@ -1178,10 +1233,13 @@ dvr_entry_class_channel_name_set(void *o, const void *v)
|
|||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
channel_t *ch;
|
||||
if (de->de_locked)
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
if (!de->de_config)
|
||||
if (!de->de_config) {
|
||||
de->de_config = dvr_config_find_by_name_default("");
|
||||
if (de->de_config)
|
||||
LIST_INSERT_HEAD(&de->de_config->dvr_entries, de, de_config_link);
|
||||
}
|
||||
if (!strcmp(de->de_channel_name ?: "", v ?: ""))
|
||||
return 0;
|
||||
ch = v ? channel_find_by_name(v) : NULL;
|
||||
|
@ -1206,6 +1264,13 @@ dvr_entry_class_channel_name_get(void *o)
|
|||
return &ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_pri_set(void *o, const void *v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
return dvr_entry_class_int_set(de, &de->de_pri, *(int *)v);
|
||||
}
|
||||
|
||||
htsmsg_t *
|
||||
dvr_entry_class_pri_list ( void *o )
|
||||
{
|
||||
|
@ -1220,6 +1285,13 @@ dvr_entry_class_pri_list ( void *o )
|
|||
return strtab2htsmsg(tab);
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_entry_class_mc_set(void *o, const void *v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
return dvr_entry_class_int_set(de, &de->de_mc, *(int *)v);
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
dvr_entry_class_mc_list ( void *o )
|
||||
{
|
||||
|
@ -1254,7 +1326,10 @@ static int
|
|||
dvr_entry_class_autorec_set(void *o, const void *v)
|
||||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
dvr_autorec_entry_t *dae = v ? dvr_autorec_find_by_uuid(v) : NULL;
|
||||
dvr_autorec_entry_t *dae;
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
dae = v ? dvr_autorec_find_by_uuid(v) : NULL;
|
||||
if (dae == NULL) {
|
||||
if (de->de_autorec) {
|
||||
LIST_REMOVE(de, de_autorec_link);
|
||||
|
@ -1304,7 +1379,10 @@ dvr_entry_class_broadcast_set(void *o, const void *v)
|
|||
{
|
||||
dvr_entry_t *de = (dvr_entry_t *)o;
|
||||
uint32_t id = *(uint32_t *)v;
|
||||
epg_broadcast_t *bcast = epg_broadcast_find_by_id(id, de->de_channel);
|
||||
epg_broadcast_t *bcast;
|
||||
if (!dvr_entry_is_editable(de))
|
||||
return 0;
|
||||
bcast = epg_broadcast_find_by_id(id, de->de_channel);
|
||||
if (bcast == NULL) {
|
||||
if (de->de_bcast) {
|
||||
de->de_bcast->putref((epg_object_t*)de->de_bcast);
|
||||
|
@ -1563,6 +1641,7 @@ const idclass_t dvr_entry_class = {
|
|||
.type = PT_TIME,
|
||||
.id = "start",
|
||||
.name = "Start Time",
|
||||
.set = dvr_entry_class_start_set,
|
||||
.off = offsetof(dvr_entry_t, de_start),
|
||||
},
|
||||
{
|
||||
|
@ -1570,6 +1649,7 @@ const idclass_t dvr_entry_class = {
|
|||
.id = "start_extra",
|
||||
.name = "Extra Start Time",
|
||||
.off = offsetof(dvr_entry_t, de_start_extra),
|
||||
.set = dvr_entry_class_start_extra_set,
|
||||
.list = dvr_entry_class_extra_list,
|
||||
.opts = PO_DURATION,
|
||||
},
|
||||
|
@ -1584,6 +1664,7 @@ const idclass_t dvr_entry_class = {
|
|||
.type = PT_TIME,
|
||||
.id = "stop",
|
||||
.name = "Stop Time",
|
||||
.set = dvr_entry_class_stop_set,
|
||||
.off = offsetof(dvr_entry_t, de_stop),
|
||||
},
|
||||
{
|
||||
|
@ -1617,7 +1698,7 @@ const idclass_t dvr_entry_class = {
|
|||
.list = dvr_entry_class_channel_list,
|
||||
},
|
||||
{
|
||||
.type = PT_TIME,
|
||||
.type = PT_STR,
|
||||
.id = "channel_icon",
|
||||
.name = "Channel Icon",
|
||||
.get = dvr_entry_class_channel_icon_url_get,
|
||||
|
@ -1666,6 +1747,7 @@ const idclass_t dvr_entry_class = {
|
|||
.name = "Priority",
|
||||
.off = offsetof(dvr_entry_t, de_pri),
|
||||
.def.i = DVR_PRIO_NORMAL,
|
||||
.set = dvr_entry_class_pri_set,
|
||||
.list = dvr_entry_class_pri_list,
|
||||
},
|
||||
{
|
||||
|
@ -1674,6 +1756,7 @@ const idclass_t dvr_entry_class = {
|
|||
.name = "Container",
|
||||
.off = offsetof(dvr_entry_t, de_mc),
|
||||
.def.i = MC_MATROSKA,
|
||||
.set = dvr_entry_class_mc_set,
|
||||
.list = dvr_entry_class_mc_list,
|
||||
},
|
||||
{
|
||||
|
@ -1852,6 +1935,34 @@ dvr_config_find_by_name_default(const char *name)
|
|||
return cfg;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void
|
||||
dvr_config_update_flags(dvr_config_t *cfg)
|
||||
{
|
||||
int r = 0;
|
||||
if (cfg->dvr_dir_per_day) r |= DVR_DIR_PER_DAY;
|
||||
if (cfg->dvr_channel_dir) r |= DVR_DIR_PER_CHANNEL;
|
||||
if (cfg->dvr_channel_in_title) r |= DVR_CHANNEL_IN_TITLE;
|
||||
if (cfg->dvr_date_in_title) r |= DVR_DATE_IN_TITLE;
|
||||
if (cfg->dvr_time_in_title) r |= DVR_TIME_IN_TITLE;
|
||||
if (cfg->dvr_whitespace_in_title) r |= DVR_WHITESPACE_IN_TITLE;
|
||||
if (cfg->dvr_title_dir) r |= DVR_DIR_PER_TITLE;
|
||||
if (cfg->dvr_episode_in_title) r |= DVR_EPISODE_IN_TITLE;
|
||||
if (cfg->dvr_clean_title) r |= DVR_CLEAN_TITLE;
|
||||
if (cfg->dvr_tag_files) r |= DVR_TAG_FILES;
|
||||
if (cfg->dvr_skip_commercials) r |= DVR_SKIP_COMMERCIALS;
|
||||
if (cfg->dvr_subtitle_in_title) r |= DVR_SUBTITLE_IN_TITLE;
|
||||
if (cfg->dvr_episode_before_date) r |= DVR_EPISODE_BEFORE_DATE;
|
||||
if (cfg->dvr_episode_duplicate) r |= DVR_EPISODE_DUPLICATE_DETECTION;
|
||||
cfg->dvr_flags = r | DVR_FLAGS_VALID;
|
||||
r = 0;
|
||||
if (cfg->dvr_rewrite_pat) r |= MC_REWRITE_PAT;
|
||||
if (cfg->dvr_rewrite_pmt) r |= MC_REWRITE_PMT;
|
||||
cfg->dvr_muxcnf.m_flags = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new named dvr config; the caller is responsible
|
||||
* to avoid duplicates
|
||||
|
@ -1903,8 +2014,12 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf)
|
|||
cfg->dvr_muxcnf.m_file_permissions = 0664;
|
||||
cfg->dvr_muxcnf.m_directory_permissions = 0775;
|
||||
|
||||
if (conf)
|
||||
if (conf) {
|
||||
idnode_load(&cfg->dvr_id, conf);
|
||||
if (dvr_config_is_default(cfg))
|
||||
cfg->dvr_enabled = 1;
|
||||
dvr_config_update_flags(cfg);
|
||||
}
|
||||
|
||||
tvhlog(LOG_INFO, "dvr", "Creating new configuration '%s'", cfg->dvr_config_name);
|
||||
|
||||
|
@ -1955,35 +2070,6 @@ dvr_config_delete(const char *name)
|
|||
dvr_config_destroy(cfg, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
static void
|
||||
dvr_config_update_flags(dvr_config_t *cfg)
|
||||
{
|
||||
int r = 0;
|
||||
if (cfg->dvr_dir_per_day) r |= DVR_DIR_PER_DAY;
|
||||
if (cfg->dvr_channel_dir) r |= DVR_DIR_PER_CHANNEL;
|
||||
if (cfg->dvr_channel_in_title) r |= DVR_CHANNEL_IN_TITLE;
|
||||
if (cfg->dvr_date_in_title) r |= DVR_DATE_IN_TITLE;
|
||||
if (cfg->dvr_time_in_title) r |= DVR_TIME_IN_TITLE;
|
||||
if (cfg->dvr_whitespace_in_title) r |= DVR_WHITESPACE_IN_TITLE;
|
||||
if (cfg->dvr_title_dir) r |= DVR_DIR_PER_TITLE;
|
||||
if (cfg->dvr_episode_in_title) r |= DVR_EPISODE_IN_TITLE;
|
||||
if (cfg->dvr_clean_title) r |= DVR_CLEAN_TITLE;
|
||||
if (cfg->dvr_tag_files) r |= DVR_TAG_FILES;
|
||||
if (cfg->dvr_skip_commercials) r |= DVR_SKIP_COMMERCIALS;
|
||||
if (cfg->dvr_subtitle_in_title) r |= DVR_SUBTITLE_IN_TITLE;
|
||||
if (cfg->dvr_episode_before_date) r |= DVR_EPISODE_BEFORE_DATE;
|
||||
if (cfg->dvr_episode_duplicate) r |= DVR_EPISODE_DUPLICATE_DETECTION;
|
||||
cfg->dvr_flags = r;
|
||||
r = 0;
|
||||
if (cfg->dvr_rewrite_pat) r |= MC_REWRITE_PAT;
|
||||
if (cfg->dvr_rewrite_pmt) r |= MC_REWRITE_PMT;
|
||||
cfg->dvr_muxcnf.m_flags = r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -2006,14 +2092,19 @@ dvr_config_save(dvr_config_t *cfg)
|
|||
static void
|
||||
dvr_config_class_save(idnode_t *self)
|
||||
{
|
||||
dvr_config_update_flags((dvr_config_t *)self);
|
||||
dvr_config_save((dvr_config_t *)self);
|
||||
dvr_config_t *cfg = (dvr_config_t *)self;
|
||||
if (dvr_config_is_default(cfg))
|
||||
cfg->dvr_enabled = 1;
|
||||
dvr_config_update_flags(cfg);
|
||||
dvr_config_save(cfg);
|
||||
}
|
||||
|
||||
static void
|
||||
dvr_config_class_delete(idnode_t *self)
|
||||
{
|
||||
dvr_config_destroy((dvr_config_t *)self, 1);
|
||||
dvr_config_t *cfg = (dvr_config_t *)self;
|
||||
if (!dvr_config_is_default(cfg))
|
||||
dvr_config_destroy(cfg, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2042,6 +2133,20 @@ fine:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dvr_config_class_enabled_set(void *o, const void *v)
|
||||
{
|
||||
dvr_config_t *cfg = (dvr_config_t *)o;
|
||||
if (dvr_config_is_default(cfg) && dvr_config_is_valid(cfg))
|
||||
return 0;
|
||||
if (cfg->dvr_enabled != *(int *)v) {
|
||||
cfg->dvr_enabled = *(int *)v;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
dvr_config_class_get_title (idnode_t *self)
|
||||
{
|
||||
|
@ -2119,6 +2224,7 @@ const idclass_t dvr_config_class = {
|
|||
.type = PT_BOOL,
|
||||
.id = "enabled",
|
||||
.name = "Enabled",
|
||||
.set = dvr_config_class_enabled_set,
|
||||
.off = offsetof(dvr_config_t, dvr_enabled),
|
||||
.def.i = 1,
|
||||
.group = 1,
|
||||
|
|
|
@ -115,17 +115,16 @@ void dvr_inotify_add ( dvr_entry_t *de )
|
|||
SKEL_USED(dvr_inotify_entry_skel);
|
||||
e->path = strdup(e->path);
|
||||
e->fd = inotify_add_watch(_inot_fd, e->path, EVENT_MASK);
|
||||
if (e->fd == -1) {
|
||||
tvhlog(LOG_ERR, "dvr", "failed to add inotify watch to %s (err=%s)",
|
||||
e->path, strerror(errno));
|
||||
free(path);
|
||||
dvr_inotify_del(de);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LIST_INSERT_HEAD(&e->entries, de, de_inotify_link);
|
||||
|
||||
if (e->fd < 0) {
|
||||
tvhlog(LOG_ERR, "dvr", "failed to add inotify watch to %s (err=%s)",
|
||||
e->path, strerror(errno));
|
||||
dvr_inotify_del(de);
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
|
@ -146,7 +145,8 @@ void dvr_inotify_del ( dvr_entry_t *de )
|
|||
LIST_REMOVE(det, de_inotify_link);
|
||||
if (LIST_FIRST(&e->entries) == NULL) {
|
||||
RB_REMOVE(&_inot_tree, e, link);
|
||||
inotify_rm_watch(_inot_fd, e->fd);
|
||||
if (e->fd >= 0)
|
||||
inotify_rm_watch(_inot_fd, e->fd);
|
||||
free(e->path);
|
||||
free(e);
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ _dvr_inotify_find2
|
|||
snprintf(path, sizeof(path), "%s/%s", die->path, name);
|
||||
|
||||
LIST_FOREACH(de, &die->entries, de_inotify_link)
|
||||
if (!strcmp(path, de->de_filename))
|
||||
if (de->de_filename && !strcmp(path, de->de_filename))
|
||||
break;
|
||||
|
||||
return de;
|
||||
|
|
|
@ -66,9 +66,6 @@ dvr_rec_subscribe(dvr_entry_t *de)
|
|||
int flags;
|
||||
|
||||
assert(de->de_s == NULL);
|
||||
assert(!de->de_locked);
|
||||
|
||||
de->de_locked = 1;
|
||||
|
||||
if(de->de_pri < 5)
|
||||
weight = prio2weight[de->de_pri];
|
||||
|
@ -120,8 +117,6 @@ dvr_rec_unsubscribe(dvr_entry_t *de, int stopcode)
|
|||
globalheaders_destroy(de->de_gh);
|
||||
|
||||
de->de_last_error = stopcode;
|
||||
|
||||
de->de_locked = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -473,6 +473,8 @@ idnode_find(const char *uuid, const idclass_t *idc)
|
|||
idnode_t skel, *r;
|
||||
|
||||
tvhtrace("idnode", "find node %s class %s", uuid, idc ? idc->ic_class : NULL);
|
||||
if(uuid == NULL || strlen(uuid) != UUID_HEX_SIZE - 1)
|
||||
return NULL;
|
||||
if(hex2bin(skel.in_uuid, sizeof(skel.in_uuid), uuid))
|
||||
return NULL;
|
||||
r = RB_FIND(&idnodes, &skel, in_link, in_cmp);
|
||||
|
|
|
@ -83,6 +83,8 @@ tvheadend.dvrRowActions = function() {
|
|||
tvheadend.dvr_upcoming = function(panel, index) {
|
||||
|
||||
var actions = tvheadend.dvrRowActions();
|
||||
var list = 'disp_title,start,start_extra,stop,stop_extra,' +
|
||||
'channel,config_name';
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
url: 'api/dvr/entry',
|
||||
|
@ -94,11 +96,15 @@ tvheadend.dvr_upcoming = function(panel, index) {
|
|||
add: {
|
||||
url: 'api/dvr/entry',
|
||||
params: {
|
||||
list: 'disp_title,start,start_extra,stop,stop_extra,' +
|
||||
'channel,config_name',
|
||||
list: list,
|
||||
},
|
||||
create: { }
|
||||
},
|
||||
edit: {
|
||||
params: {
|
||||
list: list,
|
||||
}
|
||||
},
|
||||
del: true,
|
||||
list: 'disp_title,episode,pri,start_real,stop_real,' +
|
||||
'duration,channelname,creator,config_name,' +
|
||||
|
|
Loading…
Add table
Reference in a new issue