diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 4e66f278..b2c83d5c 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -445,6 +445,7 @@ struct mpegts_service uint16_t s_dvb_prefcapid; int s_dvb_prefcapid_lock; uint16_t s_dvb_forcecaid; + time_t s_dvb_last_seen; /* * EIT/EPG control diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 1d561e09..1b4c39b8 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -183,6 +183,13 @@ const idclass_t mpegts_service_class = .off = offsetof(mpegts_service_t, s_dvb_forcecaid), .opts = PO_ADVANCED | PO_HEXA, }, + { + .type = PT_TIME, + .id = "last_seen", + .name = "Last Seen", + .off = offsetof(mpegts_service_t, s_dvb_last_seen), + .opts = PO_ADVANCED | PO_RDONLY, + }, {}, } }; @@ -575,6 +582,10 @@ mpegts_service_find s->s_pmt_pid = pmt_pid; if (save) *save = 1; } + if (create && (*save || s->s_dvb_last_seen + 3600 < dispatch_clock)) { + s->s_dvb_last_seen = dispatch_clock; + if (save) *save = 1; + } return s; } } @@ -582,9 +593,10 @@ mpegts_service_find /* Create */ if (create) { s = mm->mm_network->mn_create_service(mm, sid, pmt_pid); + s->s_dvb_last_seen = dispatch_clock; if (save) *save = 1; } - + return s; } diff --git a/src/prop.c b/src/prop.c index c568fb3a..35d6f029 100644 --- a/src/prop.c +++ b/src/prop.c @@ -470,6 +470,8 @@ prop_serialize_value htsmsg_add_bool(m, "duration", 1); if (opts & PO_HEXA) htsmsg_add_bool(m, "hexa", 1); + if (opts & PO_DATE) + htsmsg_add_bool(m, "date", 1); /* Enum list */ if (pl->list) diff --git a/src/prop.h b/src/prop.h index aa4fed05..5e5d9566 100644 --- a/src/prop.h +++ b/src/prop.h @@ -55,6 +55,7 @@ typedef enum { #define PO_PASSWORD 0x0080 // String is a password #define PO_DURATION 0x0100 // For PT_TIME - differentiate between duration and datetime #define PO_HEXA 0x0200 // Hexadecimal value +#define PO_DATE 0x0400 // Show date only /* * Property definition diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index d78604f7..2b21f610 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -193,6 +193,7 @@ tvheadend.IdNodeField = function(conf) this.hidden = conf.hidden || conf.advanced; this.password = conf.showpwd ? false : conf.password; this.duration = conf.duration; + this.date = conf.date; this.intsplit = conf.intsplit; this.hexa = conf.hexa; this.group = conf.group; @@ -234,7 +235,7 @@ tvheadend.IdNodeField = function(conf) } else if (this.type === 'time') { w = 120; ftype = 'date'; - if (this.durations) { + if (this.duration) { ftype = 'numeric'; w = 80; } @@ -294,9 +295,15 @@ tvheadend.IdNodeField = function(conf) } return min + ' min'; } + if (this.date) { + return function(v) { + var dt = new Date(v * 1000); + return dt.toLocaleDateString(); + } + } return function(v) { var dt = new Date(v * 1000); - return dt.format('D j M H:i'); + return dt.toLocaleString(); } } @@ -551,12 +558,24 @@ tvheadend.idnode_editor_field = function(f, conf) }); case 'time': - if (!f.duration) + if (!f.duration) { + if (d) { + var dt = new Date(value * 1000); + value = f.date ? dt.toLocaleDateString() : + dt.toLocaleString(); + return new Ext.form.TextField({ + fieldLabel: f.caption, + name: f.id, + value: value, + disabled: true, + width: 300 + }); + } return new Ext.ux.form.TwinDateTimeField({ fieldLabel: f.caption, name: f.id, value: value, - disabled: d, + disabled: false, width: 300, timeFormat: 'H:i:s', timeConfig: { @@ -570,6 +589,7 @@ tvheadend.idnode_editor_field = function(f, conf) allowBlank: true } }); + } /* fall thru!!! */ case 'int':