From cf528dbe65dbfc9cb9d95160419366acef6f7b51 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 2 Sep 2014 18:16:18 +0200 Subject: [PATCH] comet events - an attempt to clean them --- src/access.c | 1 + src/channels.c | 2 + src/dvr/dvr.h | 2 - src/dvr/dvr_autorec.c | 15 +-- src/dvr/dvr_db.c | 33 ++----- src/dvr/dvr_inotify.c | 4 +- src/dvr/dvr_rec.c | 5 +- src/esfilter.c | 1 + src/htsmsg.c | 19 ++++ src/htsmsg.h | 5 + src/idnode.c | 99 +++++++++++++------- src/idnode.h | 7 +- src/input.c | 4 - src/input/mpegts/dvb_psi.c | 3 +- src/input/mpegts/linuxdvb/linuxdvb_adapter.c | 1 + src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 3 + src/input/mpegts/mpegts_input.c | 1 + src/input/mpegts/mpegts_network_scan.c | 4 +- src/input/mpegts/mpegts_service.c | 8 +- src/input/mpegts/satip/satip_satconf.c | 1 + src/service.c | 1 + src/webui/static/app/acleditor.js | 1 - src/webui/static/app/chconf.js | 11 +-- src/webui/static/app/comet.js | 1 + src/webui/static/app/dvr.js | 5 +- src/webui/static/app/esfilter.js | 6 -- src/webui/static/app/idnode.js | 21 +++-- src/webui/static/app/mpegts.js | 4 - src/webui/static/app/tvadapters.js | 1 - 29 files changed, 147 insertions(+), 122 deletions(-) diff --git a/src/access.c b/src/access.c index fa8ec0a8..442eb4ab 100644 --- a/src/access.c +++ b/src/access.c @@ -912,6 +912,7 @@ access_entry_dvr_config_get(void *o) const idclass_t access_entry_class = { .ic_class = "access", .ic_caption = "Access", + .ic_event = "access", .ic_save = access_entry_class_save, .ic_get_title = access_entry_class_get_title, .ic_delete = access_entry_class_delete, diff --git a/src/channels.c b/src/channels.c index 3dc23f4b..a8921116 100644 --- a/src/channels.c +++ b/src/channels.c @@ -275,6 +275,7 @@ channel_class_epggrab_list ( void *o ) const idclass_t channel_class = { .ic_class = "channel", .ic_caption = "Channel", + .ic_event = "channel", .ic_save = channel_class_save, .ic_get_title = channel_class_get_title, .ic_delete = channel_class_delete, @@ -846,6 +847,7 @@ channel_tag_class_get_list(void *o) const idclass_t channel_tag_class = { .ic_class = "channeltag", .ic_caption = "Channel Tag", + .ic_event = "channeltag", .ic_save = channel_tag_class_save, .ic_get_title = channel_tag_class_get_title, .ic_delete = channel_tag_class_delete, diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index b01b4b73..dbbe8f19 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -312,8 +312,6 @@ void dvr_config_save(dvr_config_t *cfg); int dvr_entry_get_mc( dvr_entry_t *de); -void dvr_entry_notify(dvr_entry_t *de); - void dvr_entry_save(dvr_entry_t *de); const char *dvr_entry_status(dvr_entry_t *de); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index bc736652..077547fd 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -31,7 +31,6 @@ #include "tvheadend.h" #include "settings.h" #include "dvr.h" -#include "notify.h" #include "dtable.h" #include "epg.h" @@ -683,6 +682,7 @@ dvr_autorec_entry_class_content_type_list(void *o) const idclass_t dvr_autorec_entry_class = { .ic_class = "dvrautorec", .ic_caption = "DVR Auto-Record Entry", + .ic_event = "dvrautorec", .ic_save = dvr_autorec_entry_class_save, .ic_get_title = dvr_autorec_entry_class_get_title, .ic_delete = dvr_autorec_entry_class_delete, @@ -921,15 +921,9 @@ void autorec_destroy_by_channel(channel_t *ch, int delconf) { dvr_autorec_entry_t *dae; - htsmsg_t *m; while((dae = LIST_FIRST(&ch->ch_autorecs)) != NULL) autorec_entry_destroy(dae, delconf); - - /* Notify web clients that we have messed with the tables */ - m = htsmsg_create_map(); - htsmsg_add_u32(m, "reload", 1); - notify_by_msg("autorec", m); } /* @@ -939,17 +933,12 @@ void autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf) { dvr_autorec_entry_t *dae; - htsmsg_t *m; while((dae = LIST_FIRST(&ct->ct_autorecs)) != NULL) { LIST_REMOVE(dae, dae_channel_tag_link); dae->dae_channel_tag = NULL; + idnode_notify_simple(&dae->dae_id); if (delconf) dvr_autorec_save(dae); } - - /* Notify web clients that we have messed with the tables */ - m = htsmsg_create_map(); - htsmsg_add_u32(m, "reload", 1); - notify_by_msg("autorec", m); } diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index dae4f84d..b0744586 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -26,7 +26,6 @@ #include "tvheadend.h" #include "dvr.h" -#include "notify.h" #include "htsp_server.h" #include "streaming.h" #include "intlconv.h" @@ -209,22 +208,6 @@ dvr_entry_schedstatus(dvr_entry_t *de) } } -/** - * - */ -void -dvr_entry_notify(dvr_entry_t *de) -{ - htsmsg_t *m = htsmsg_create_map(); - - htsmsg_add_u32(m, "updateEntry", 1); - htsmsg_add_str(m, "uuid", idnode_uuid_as_str(&de->de_id)); - htsmsg_add_str(m, "status", dvr_entry_status(de)); - htsmsg_add_str(m, "schedstate", dvr_entry_schedstatus(de)); - notify_by_msg("dvrdb", m); -} - - /** * */ @@ -809,9 +792,8 @@ static dvr_entry_t *_dvr_entry_update /* Save changes */ if (save) { - dvr_entry_save(de); + idnode_changed(&de->de_id); htsp_dvr_entry_update(de); - dvr_entry_notify(de); tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\": Updated Timer", lang_str_get(de->de_title, NULL), DVR_CH_NAME(de)); } @@ -920,7 +902,7 @@ void dvr_event_updated ( epg_broadcast_t *e ) * */ static void -dvr_stop_recording(dvr_entry_t *de, int stopcode, int delconf) +dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf) { dvr_config_t *cfg = de->de_config; @@ -936,10 +918,12 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int delconf) lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), dvr_entry_status(de)); - if (delconf) + if (saveconf) + idnode_changed(&de->de_id); + else + idnode_notify_simple(&de->de_id); dvr_entry_save(de); htsp_dvr_entry_update(de); - dvr_entry_notify(de); gtimer_arm_abs(&de->de_timer, dvr_timer_expire, de, de->de_stop + cfg->dvr_retention_days * 86400); @@ -971,7 +955,7 @@ dvr_timer_start_recording(void *aux) tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\" recorder starting", lang_str_get(de->de_title, NULL), DVR_CH_NAME(de)); - dvr_entry_notify(de); + idnode_changed(&de->de_id); htsp_dvr_entry_update(de); dvr_rec_subscribe(de); @@ -1570,6 +1554,7 @@ dvr_entry_class_content_type_list(void *o) const idclass_t dvr_entry_class = { .ic_class = "dvrentry", .ic_caption = "DVR Entry", + .ic_event = "dvrentry", .ic_save = dvr_entry_class_save, .ic_get_title = dvr_entry_class_get_title, .ic_delete = dvr_entry_class_delete, @@ -2079,7 +2064,6 @@ dvr_config_class_charset_list(void *o) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "type", "api"); htsmsg_add_str(m, "uri", "intlconv/charsets"); - htsmsg_add_str(m, "event", "charsets"); return m; } @@ -2099,6 +2083,7 @@ dvr_config_class_cache_list(void *o) const idclass_t dvr_config_class = { .ic_class = "dvrconfig", .ic_caption = "DVR Configuration Profile", + .ic_event = "dvrconfig", .ic_save = dvr_config_class_save, .ic_get_title = dvr_config_class_get_title, .ic_delete = dvr_config_class_delete, diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index ba439f96..b2226b52 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -211,7 +211,7 @@ _dvr_inotify_moved dvr_inotify_del(de); htsp_dvr_entry_update(de); - dvr_entry_notify(de); + idnode_notify_simple(&de->de_id); } /* @@ -239,7 +239,7 @@ _dvr_inotify_moved_all while ((de = LIST_FIRST(&die->entries))) { htsp_dvr_entry_update(de); - dvr_entry_notify(de); + idnode_notify_simple(&de->de_id); dvr_inotify_del(de); } } diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 45146f10..814ea59e 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -300,7 +300,7 @@ dvr_rec_set_state(dvr_entry_t *de, dvr_rs_state_t newstate, int error) de->de_errors++; } if (notify) - dvr_entry_notify(de); + idnode_notify_simple(&de->de_id); } /** @@ -521,9 +521,8 @@ dvr_thread(void *aux) dvr_rec_set_state(de, DVR_RS_WAIT_PROGRAM_START, 0); if(dvr_rec_start(de, sm->sm_data) == 0) { started = 1; - dvr_entry_notify(de); + idnode_changed(&de->de_id); htsp_dvr_entry_update(de); - dvr_entry_save(de); } pthread_mutex_unlock(&global_lock); } diff --git a/src/esfilter.c b/src/esfilter.c index ed4f6d02..2a5f1f55 100644 --- a/src/esfilter.c +++ b/src/esfilter.c @@ -587,6 +587,7 @@ esfilter_class_action_enum(void *o) const idclass_t esfilter_class = { .ic_class = "esfilter", .ic_caption = "Elementary Stream Filter", + .ic_event = "esfilter", .ic_save = esfilter_class_save, .ic_get_title = esfilter_class_get_title, .ic_delete = esfilter_class_delete, diff --git a/src/htsmsg.c b/src/htsmsg.c index 6ef0259a..1f9744f9 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -261,6 +261,25 @@ htsmsg_add_str(htsmsg_t *msg, const char *name, const char *str) f->hmf_str = strdup(str); } +/* + * + */ +int +htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str) +{ + htsmsg_field_t *f = htsmsg_field_find(msg, name); + if (!f) + f = htsmsg_field_add(msg, name, HMF_STR, HMF_ALLOCED | HMF_NAME_ALLOCED); + else { + if (f->hmf_type != HMF_STR) + return 1; + if(f->hmf_flags & HMF_ALLOCED) + free((void *)f->hmf_str); + } + f->hmf_str = strdup(str); + return 0; +} + /* * */ diff --git a/src/htsmsg.h b/src/htsmsg.h index fb0e0d60..479a39a3 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -135,6 +135,11 @@ void htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64); */ void htsmsg_add_str(htsmsg_t *msg, const char *name, const char *str); +/** + * Add/update a string field + */ +int htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str); + /** * Add an field where source is a list or map message. */ diff --git a/src/idnode.c b/src/idnode.c index 0ab8e0b0..1fa741b2 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -155,7 +155,7 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) idclass_register(class); // Note: we never actually unregister /* Fire event */ - idnode_notify(in, NULL, 0, 1); + idnode_notify_simple(in); return 0; } @@ -169,7 +169,7 @@ idnode_unlink(idnode_t *in) lock_assert(&global_lock); RB_REMOVE(&idnodes, in, in_link); tvhtrace("idnode", "unlink node %s", idnode_uuid_as_str(in)); - idnode_notify(in, NULL, 0, 1); + idnode_notify_simple(in); } /** @@ -826,7 +826,7 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) if (save && dosave) idnode_savefn(self); if (dosave) - idnode_notify(self, NULL, 0, 0); + idnode_notify_simple(self); // Note: always output event if "dosave", reason is that UI updates on // these, but there are some subtle cases where it will expect // an update and not get one. This include fields being set for @@ -835,6 +835,13 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) return save; } +void +idnode_changed( idnode_t *self ) +{ + idnode_notify_simple(self); + idnode_savefn(self); +} + /* ************************************************************************** * Read * *************************************************************************/ @@ -902,6 +909,17 @@ idclass_get_class (const idclass_t *idc) return NULL; } +static const char * +idclass_get_event (const idclass_t *idc) +{ + while (idc) { + if (idc->ic_event) + return idc->ic_event; + idc = idc->ic_super; + } + return NULL; +} + static const char * idclass_get_order (const idclass_t *idc) { @@ -992,6 +1010,8 @@ idclass_serialize0(const idclass_t *idc, htsmsg_t *list, int optmask) htsmsg_add_str(m, "caption", s); if ((s = idclass_get_class(idc))) htsmsg_add_str(m, "class", s); + if ((s = idclass_get_event(idc))) + htsmsg_add_str(m, "event", s); if ((s = idclass_get_order(idc))) htsmsg_add_str(m, "order", s); if ((p = idclass_get_property_groups(idc))) @@ -1022,6 +1042,8 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask) htsmsg_add_str(m, "caption", s); if ((s = idclass_get_class(idc))) htsmsg_add_str(m, "class", s); + if ((s = idclass_get_event(idc))) + htsmsg_add_str(m, "event", s); htsmsg_add_msg(m, "params", idnode_params(idc, self, list, optmask)); @@ -1029,9 +1051,23 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask) } /* ************************************************************************** - * Notifcation + * Notification * *************************************************************************/ +/** + * Delayed notification + */ +static void +idnode_notify_delayed ( idnode_t *in, const char *uuid, const char *event ) +{ + pthread_mutex_lock(&idnode_mutex); + if (!idnode_queue) + idnode_queue = htsmsg_create_map(); + htsmsg_set_str(idnode_queue, uuid, event); + pthread_cond_signal(&idnode_cond); + pthread_mutex_unlock(&idnode_mutex); +} + /** * Update internal event pipes */ @@ -1041,11 +1077,8 @@ idnode_notify_event ( idnode_t *in ) const idclass_t *ic = in->in_class; const char *uuid = idnode_uuid_as_str(in); while (ic) { - if (ic->ic_event) { - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "uuid", uuid); - notify_by_msg(ic->ic_event, m); - } + if (ic->ic_event) + idnode_notify_delayed(in, uuid, ic->ic_event); ic = ic->ic_super; } } @@ -1055,38 +1088,37 @@ idnode_notify_event ( idnode_t *in ) */ void idnode_notify - (idnode_t *in, const char *chn, int force, int event) + (idnode_t *in, int event) { const char *uuid = idnode_uuid_as_str(in); if (!tvheadend_running) return; - /* Forced */ - if (chn || force) { - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "uuid", uuid); - notify_by_msg(chn ?: "idnodeUpdated", m); + /* Immediate */ + if (!event) { + + const idclass_t *ic = in->in_class; + + while (ic) { + if (ic->ic_event) { + htsmsg_t *m = htsmsg_create_map(); + htsmsg_add_str(m, "uuid", uuid); + notify_by_msg(ic->ic_event, m); + } + ic = ic->ic_super; + } /* Rate-limited */ } else { - pthread_mutex_lock(&idnode_mutex); - if (!idnode_queue) - idnode_queue = htsmsg_create_map(); - htsmsg_set_u32(idnode_queue, uuid, 1); - pthread_cond_signal(&idnode_cond); - pthread_mutex_unlock(&idnode_mutex); - } - - /* Send event */ - if (event) idnode_notify_event(in); + } } void idnode_notify_simple (void *in) { - idnode_notify(in, NULL, 0, 0); + idnode_notify(in, 1); } void @@ -1095,7 +1127,7 @@ idnode_notify_title_changed (void *in) htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "uuid", idnode_uuid_as_str(in)); htsmsg_add_str(m, "text", idnode_get_title(in)); - notify_by_msg("idnodeUpdated", m); + notify_by_msg("title", m); idnode_notify_event(in); } @@ -1108,6 +1140,7 @@ idnode_thread ( void *p ) idnode_t *node; htsmsg_t *m, *q = NULL; htsmsg_field_t *f; + const char *event; pthread_mutex_lock(&idnode_mutex); @@ -1126,13 +1159,13 @@ idnode_thread ( void *p ) pthread_mutex_lock(&global_lock); HTSMSG_FOREACH(f, q) { - node = idnode_find(f->hmf_name, NULL); - m = htsmsg_create_map(); + node = idnode_find(f->hmf_name, NULL); + event = htsmsg_field_get_str(f); + m = htsmsg_create_map(); htsmsg_add_str(m, "uuid", f->hmf_name); - if (node) - notify_by_msg("idnodeUpdated", m); - else - notify_by_msg("idnodeDeleted", m); + if (!node) + htsmsg_add_u32(m, "removed", 1); + notify_by_msg(event, m); } /* Finished */ diff --git a/src/idnode.h b/src/idnode.h index 4a016d39..82c70245 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -141,12 +141,13 @@ void idnode_delete (idnode_t *in); void idnode_moveup (idnode_t *in); void idnode_movedown (idnode_t *in); +void idnode_changed (idnode_t *in); + void *idnode_find (const char *uuid, const idclass_t *idc); idnode_set_t *idnode_find_all(const idclass_t *idc); -#define idnode_updated(in) idnode_notify(in, NULL, 0, 0) -void idnode_notify - (idnode_t *in, const char *chn, int force, int event); + +void idnode_notify (idnode_t *in, int event); void idnode_notify_simple (void *in); void idnode_notify_title_changed (void *in); diff --git a/src/input.c b/src/input.c index b6f1eceb..7952cf2f 100644 --- a/src/input.c +++ b/src/input.c @@ -43,9 +43,6 @@ tvh_hardware_create0 /* Load config */ if (conf) idnode_load(&th->th_id, conf); - - /* Update */ - notify_reload("hardware"); return o; } @@ -60,7 +57,6 @@ tvh_hardware_delete ( tvh_hardware_t *th ) // TODO LIST_REMOVE(th, th_link); idnode_unlink(&th->th_id); - notify_reload("hardware"); } /* diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 79204e17..90e4a7f0 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -989,8 +989,7 @@ dvb_sdt_callback /* Save details */ if (save) { - idnode_updated(&s->s_id); - s->s_config_save((service_t*)s); + idnode_changed(&s->s_id); service_refresh_channel((service_t*)s); } } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index 1f5d8e70..5c610fbf 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -72,6 +72,7 @@ const idclass_t linuxdvb_adapter_class = { .ic_class = "linuxdvb_adapter", .ic_caption = "LinuxDVB Adapter", + .ic_event = "linuxdvb_adapter", .ic_save = linuxdvb_adapter_class_save, .ic_get_childs = linuxdvb_adapter_class_get_childs, .ic_get_title = linuxdvb_adapter_class_get_title, diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 39fa40c9..b89ae72d 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -211,6 +211,7 @@ const idclass_t linuxdvb_satconf_class = { .ic_class = "linuxdvb_satconf", .ic_caption = "DVB-S Satconf", + .ic_event = "linuxdvb_satconf", .ic_get_title = linuxdvb_satconf_class_get_title, .ic_save = linuxdvb_satconf_class_save, .ic_properties = (const property_t[]) { @@ -1020,6 +1021,7 @@ const idclass_t linuxdvb_satconf_ele_class = { .ic_class = "linuxdvb_satconf_ele", .ic_caption = "Satconf", + .ic_event = "linuxdvb_satconf_ele", .ic_get_title = linuxdvb_satconf_ele_class_get_title, .ic_get_childs = linuxdvb_satconf_ele_class_get_childs, .ic_save = linuxdvb_satconf_ele_class_save, @@ -1205,6 +1207,7 @@ const idclass_t linuxdvb_diseqc_class = { .ic_class = "linuxdvb_diseqc", .ic_caption = "DiseqC", + .ic_event = "linuxdvb_diseqc", .ic_get_title = linuxdvb_diseqc_class_get_title, .ic_save = linuxdvb_diseqc_class_save, }; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 96b2c176..292c81a4 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -142,6 +142,7 @@ const idclass_t mpegts_input_class = { .ic_class = "mpegts_input", .ic_caption = "MPEGTS Input", + .ic_event = "mpegts_input", .ic_get_title = mpegts_input_class_get_title, .ic_properties = (const property_t[]){ { diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index 664db417..94646ecd 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -27,8 +27,8 @@ static void mpegts_network_scan_notify ( mpegts_mux_t *mm ) { - idnode_updated(&mm->mm_id); - idnode_updated(&mm->mm_network->mn_id); + idnode_notify_simple(&mm->mm_id); + idnode_notify_simple(&mm->mm_network->mn_id); } static int diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 57c882e9..9b2310f2 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -423,7 +423,9 @@ mpegts_service_create0 { int r; char buf[256]; - service_create0((service_t*)s, class, uuid, S_MPEG_TS, conf); + + if (service_create0((service_t*)s, class, uuid, S_MPEG_TS, conf) == NULL) + return NULL; /* Create */ sbuf_init(&s->s_tsbuf); @@ -457,8 +459,8 @@ mpegts_service_create0 tvhlog(LOG_DEBUG, "mpegts", "%s - add service %04X %s", buf, s->s_dvb_service_id, s->s_dvb_svcname); /* Notification */ - idnode_updated(&mm->mm_id); - idnode_updated(&mm->mm_network->mn_id); + idnode_notify_simple(&mm->mm_id); + idnode_notify_simple(&mm->mm_network->mn_id); return s; } diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index 0271a297..ea1ece1c 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -169,6 +169,7 @@ const idclass_t satip_satconf_class = { .ic_class = "satip_satconf", .ic_caption = "Satconf", + .ic_event = "satip_satconf", .ic_get_title = satip_satconf_class_get_title, .ic_save = satip_satconf_class_save, .ic_properties = (const property_t[]) { diff --git a/src/service.c b/src/service.c index e7c91b42..4d461fee 100644 --- a/src/service.c +++ b/src/service.c @@ -168,6 +168,7 @@ service_class_caid_get ( void *obj ) const idclass_t service_class = { .ic_class = "service", .ic_caption = "Service", + .ic_event = "service", .ic_save = service_class_save, .ic_get_title = service_class_get_title, .ic_properties = (const property_t[]){ diff --git a/src/webui/static/app/acleditor.js b/src/webui/static/app/acleditor.js index 2a546fba..dffc28c1 100644 --- a/src/webui/static/app/acleditor.js +++ b/src/webui/static/app/acleditor.js @@ -18,7 +18,6 @@ tvheadend.acleditor = function(panel) tvheadend.idnode_grid(panel, { url: 'api/access/entry', - comet: 'acl_entries', titleS: 'Access Entry', titleP: 'Access Entries', columns: { diff --git a/src/webui/static/app/chconf.js b/src/webui/static/app/chconf.js index f25baa91..74320952 100644 --- a/src/webui/static/app/chconf.js +++ b/src/webui/static/app/chconf.js @@ -6,16 +6,9 @@ insertChannelTagsClearOption = function( scope, records, options ){ scope.insert(0,new placeholder({key: '-1', val: '(Clear filter)'})); }; -tvheadend.channelTags = new Ext.data.JsonStore({ +tvheadend.channelTags = tvheadend.idnode_get_enum({ url: 'api/channeltag/list', - root: 'entries', - fields: ['key', 'val'], - id: 'key', - autoLoad: true, - sortInfo: { - field: 'val', - direction: 'ASC', - }, + event: 'channeltag', listeners: { 'load': insertChannelTagsClearOption } diff --git a/src/webui/static/app/comet.js b/src/webui/static/app/comet.js index 3b9493e6..c7fc24c1 100644 --- a/src/webui/static/app/comet.js +++ b/src/webui/static/app/comet.js @@ -61,6 +61,7 @@ tvheadend.cometPoller = function() { for (x = 0; x < response.messages.length; x++) { m = response.messages[x]; try { + console.log('comet:' + m.notificationClass); tvheadend.comet.fireEvent(m.notificationClass, m); } catch (e) { tvheadend.log('comet failure [e=' + e.message + ']'); diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index ec6132fa..17f15b44 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -85,7 +85,6 @@ tvheadend.dvr_upcoming = function(panel, index) { tvheadend.idnode_grid(panel, { url: 'api/dvr/entry', gridURL: 'api/dvr/entry/grid_upcoming', - comet: 'dvrentry', titleS: 'Upcoming Recording', titleP: 'Upcoming Recordings', iconCls: 'clock', @@ -127,7 +126,6 @@ tvheadend.dvr_finished = function(panel, index) { url: 'api/dvr/entry', gridURL: 'api/dvr/entry/grid_finished', readonly: true, - comet: 'dvrentry', titleS: 'Finished Recording', titleP: 'Finished Recordings', iconCls: 'television', @@ -172,8 +170,8 @@ tvheadend.dvr_failed = function(panel, index) { tvheadend.idnode_grid(panel, { url: 'api/dvr/entry', gridURL: 'api/dvr/entry/grid_failed', - readonly: true, comet: 'dvrentry', + readonly: true, titleS: 'Failed Recording', titleP: 'Failed Recordings', iconCls: 'exclamation', @@ -234,7 +232,6 @@ tvheadend.autorec_editor = function(panel, index) { tvheadend.idnode_grid(panel, { url: 'api/dvr/autorec', - comet: 'dvrautorec', titleS: 'DVR AutoRec Entry', titleP: 'DVR AutoRec Entries', iconCls: 'wand', diff --git a/src/webui/static/app/esfilter.js b/src/webui/static/app/esfilter.js index a7ed3873..84e97626 100644 --- a/src/webui/static/app/esfilter.js +++ b/src/webui/static/app/esfilter.js @@ -6,7 +6,6 @@ tvheadend.esfilter_tab = function(panel) { tvheadend.idnode_grid(panel, { url: 'api/esfilter/video', - comet: 'esfilter_video', titleS: 'Video Stream Filter', titleP: 'Video Stream Filters', tabIndex: 0, @@ -23,7 +22,6 @@ tvheadend.esfilter_tab = function(panel) tvheadend.idnode_grid(panel, { url: 'api/esfilter/audio', - comet: 'esfilter_audio', titleS: 'Audio Stream Filter', titleP: 'Audio Stream Filters', tabIndex: 1, @@ -40,7 +38,6 @@ tvheadend.esfilter_tab = function(panel) tvheadend.idnode_grid(panel, { url: 'api/esfilter/teletext', - comet: 'esfilter_teletext', titleS: 'Teletext Stream Filter', titleP: 'Teletext Stream Filters', tabIndex: 2, @@ -57,7 +54,6 @@ tvheadend.esfilter_tab = function(panel) tvheadend.idnode_grid(panel, { url: 'api/esfilter/subtit', - comet: 'esfilter_subtit', titleS: 'Subtitle Stream Filter', titleP: 'Subtitle Stream Filters', tabIndex: 3, @@ -74,7 +70,6 @@ tvheadend.esfilter_tab = function(panel) tvheadend.idnode_grid(panel, { url: 'api/esfilter/ca', - comet: 'esfilter_ca', titleS: 'CA Stream Filter', titleP: 'CA Stream Filters', tabIndex: 4, @@ -91,7 +86,6 @@ tvheadend.esfilter_tab = function(panel) tvheadend.idnode_grid(panel, { url: 'api/esfilter/other', - comet: 'esfilter_other', titleS: 'Other Stream Filter', titleP: 'Other Stream Filters', tabIndex: 5, diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js index d889abb8..e4e6cb01 100644 --- a/src/webui/static/app/idnode.js +++ b/src/webui/static/app/idnode.js @@ -317,6 +317,7 @@ tvheadend.IdNode = function(conf) */ this.clazz = conf.class; this.text = conf.caption || this.clazz; + this.event = conf.event; this.props = conf.props; this.order = []; this.groups = conf.groups; @@ -1251,8 +1252,8 @@ tvheadend.idnode_grid = function(panel, conf) }; if (conf.comet) tvheadend.comet.on(conf.comet, update); - tvheadend.comet.on('idnodeUpdated', update); - tvheadend.comet.on('idnodeDeleted', update); + if (idnode.event && idnode.event != conf.comet) + tvheadend.comet.on(idnode.event, update); } /* Request data */ @@ -1506,8 +1507,6 @@ tvheadend.idnode_form_grid = function(panel, conf) }; if (conf.comet) tvheadend.comet.on(conf.comet, update); - tvheadend.comet.on('idnodeUpdated', update); - tvheadend.comet.on('idnodeDeleted', update); }; /* @@ -1516,6 +1515,7 @@ tvheadend.idnode_form_grid = function(panel, conf) tvheadend.idnode_tree = function(conf) { var current = null; + var events = {}; var params = conf.params || {}; var loader = new Ext.tree.TreeLoader({ dataUrl: conf.url, @@ -1524,6 +1524,16 @@ tvheadend.idnode_tree = function(conf) nodeParameter: 'uuid' }); + loader.on('load', function(l, n, r) { + if (n.uuid && n.event && !(n.event in events)) { + events[n.event] = 1; + tvheadend.comet.on(n.event, function(o) { + if (o.uuid) + tree.getRootNode().reload(); + }); + } + }); + var tree = new Ext.tree.TreePanel({ loader: loader, flex: 1, @@ -1556,8 +1566,7 @@ tvheadend.idnode_tree = function(conf) }); } - // TODO: top-level reload - tvheadend.comet.on('idnodeUpdated', function(o) { + tvheadend.comet.on('title', function(o) { var n = tree.getNodeById(o.uuid); if (n) { if (o.text) diff --git a/src/webui/static/app/mpegts.js b/src/webui/static/app/mpegts.js index a091b4eb..c2d7ec1e 100644 --- a/src/webui/static/app/mpegts.js +++ b/src/webui/static/app/mpegts.js @@ -29,7 +29,6 @@ tvheadend.networks = function(panel) { tvheadend.idnode_grid(panel, { url: 'api/mpegts/network', - comet: 'mpegts_network', titleS: 'Network', titleP: 'Networks', tabIndex: 1, @@ -61,7 +60,6 @@ tvheadend.muxes = function(panel) { tvheadend.idnode_grid(panel, { url: 'api/mpegts/mux', - comet: 'mpegts_mux', titleS: 'Mux', titleP: 'Muxes', tabIndex: 2, @@ -233,7 +231,6 @@ tvheadend.services = function(panel) }); tvheadend.idnode_grid(panel, { url: 'api/mpegts/service', - comet: 'service', titleS: 'Service', titleP: 'Services', tabIndex: 3, @@ -269,7 +266,6 @@ tvheadend.mux_sched = function(panel) { tvheadend.idnode_grid(panel, { url: 'api/mpegts/mux_sched', - comet: 'mpegts_mux_sched', titleS: 'Mux Scheduler', titleP: 'Mux Schedulers', tabIndex: 4, diff --git a/src/webui/static/app/tvadapters.js b/src/webui/static/app/tvadapters.js index 50e32480..7a5330be 100644 --- a/src/webui/static/app/tvadapters.js +++ b/src/webui/static/app/tvadapters.js @@ -2,7 +2,6 @@ tvheadend.tvadapters = function() { return tvheadend.idnode_tree({ url: 'api/hardware/tree', title: 'TV adapters', - comet: 'hardware', help: function() { new tvheadend.help('TV adapters', 'config_tvadapters.html'); }