diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 8c6567b8..c9ba7d09 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -142,10 +142,11 @@ extjs_root(http_connection_t *hc, const char *remain, void *opaque) extjs_load(hq, "static/app/cwceditor.js"); extjs_load(hq, "static/app/capmteditor.js"); extjs_load(hq, "static/app/tvadapters.js"); + extjs_load(hq, "static/app/idnode.js"); #if ENABLE_LINUXDVB extjs_load(hq, "static/app/dvb.js"); extjs_load(hq, "static/app/dvb_networks.js"); - extjs_load(hq, "static/app/networks.js"); + extjs_load(hq, "static/app/mpegts.js"); #endif extjs_load(hq, "static/app/iptv.js"); #if ENABLE_V4L diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 02864dbf..0ceaa584 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -65,683 +65,6 @@ extjs_grid_conf conf->filter = NULL; } -#if 0 -/** - * - */ -static int -extjs_dvblocations(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - const char *s = http_arg_get(&hc->hc_req_args, "node"); - const char *a = http_arg_get(&hc->hc_req_args, "adapter"); - th_dvb_adapter_t *tda; - htsmsg_t *out = NULL; - - if(s == NULL || a == NULL) - return HTTP_STATUS_BAD_REQUEST; - - pthread_mutex_lock(&global_lock); - - if(http_access_verify(hc, ACCESS_ADMIN)) { - pthread_mutex_unlock(&global_lock); - return HTTP_STATUS_UNAUTHORIZED; - } - - if((tda = dvb_adapter_find_by_identifier(a)) == NULL) { - pthread_mutex_unlock(&global_lock); - return HTTP_STATUS_BAD_REQUEST; - } - - pthread_mutex_unlock(&global_lock); - - if((out = dvb_mux_preconf_get_node(tda->tda_fe_type, s)) == NULL) - return 404; - - htsmsg_json_serialize(out, hq, 0); - htsmsg_destroy(out); - http_output_content(hc, "text/x-json; charset=UTF-8"); - return 0; -} -#endif - - -#if 0 -/** - * - */ -static htsmsg_t * -json_single_record(htsmsg_t *rec, const char *root) -{ - htsmsg_t *out, *array; - - out = htsmsg_create_map(); - array = htsmsg_create_list(); - - htsmsg_add_msg(array, NULL, rec); - htsmsg_add_msg(out, root, array); - return out; -} - - -/** - * - */ -static int -extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - th_dvb_adapter_t *tda, *ref; - htsmsg_t *out, *array, *r; - const char *op = http_arg_get(&hc->hc_req_args, "op"); - const char *sibling = http_arg_get(&hc->hc_req_args, "sibling"); - const char *s; - - pthread_mutex_lock(&global_lock); - - if(remain == NULL) { - /* Just list all adapters */ - - ref = sibling != NULL ? dvb_adapter_find_by_identifier(sibling) : NULL; - - array = htsmsg_create_list(); - - TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) { - if(ref == NULL || (ref != tda && ref->tda_fe_type == tda->tda_fe_type)) - htsmsg_add_msg(array, NULL, dvb_adapter_build_msg(tda)); - } - pthread_mutex_unlock(&global_lock); - out = htsmsg_create_map(); - htsmsg_add_msg(out, "entries", array); - - htsmsg_json_serialize(out, hq, 0); - htsmsg_destroy(out); - http_output_content(hc, "text/x-json; charset=UTF-8"); - return 0; - } - - if((tda = dvb_adapter_find_by_identifier(remain)) == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - if(!strcmp(op, "load")) { - r = htsmsg_create_map(); - htsmsg_add_str(r, "id", tda->tda_identifier); - htsmsg_add_u32(r, "enabled", tda->tda_enabled); - htsmsg_add_str(r, "device", tda->tda_rootpath ?: "No hardware attached"); - htsmsg_add_str(r, "name", tda->tda_displayname); - htsmsg_add_u32(r, "skip_initialscan", tda->tda_skip_initialscan); - htsmsg_add_u32(r, "idleclose", tda->tda_idleclose); - htsmsg_add_u32(r, "qmon", tda->tda_qmon); - htsmsg_add_u32(r, "poweroff", tda->tda_poweroff); - htsmsg_add_u32(r, "sidtochan", tda->tda_sidtochan); - htsmsg_add_u32(r, "full_mux_rx", tda->tda_full_mux_rx+1); - htsmsg_add_u32(r, "grace_period", tda->tda_grace_period); - htsmsg_add_str(r, "diseqcversion", - ((const char *[]){"DiSEqC 1.0 / 2.0", - "DiSEqC 1.1 / 2.1"}) - [tda->tda_diseqc_version % 2]); - htsmsg_add_str(r, "diseqcrepeats", - ((const char *[]){"0", "1", "3"}) - [tda->tda_diseqc_repeats % 3]); - htsmsg_add_u32(r, "extrapriority", tda->tda_extrapriority); - - out = json_single_record(r, "dvbadapters"); - } else if(!strcmp(op, "save")) { - - if((s = http_arg_get(&hc->hc_req_args, "name")) != NULL) - dvb_adapter_set_displayname(tda, s); - - s = http_arg_get(&hc->hc_req_args, "enabled"); - dvb_adapter_set_enabled(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "automux"); - dvb_adapter_set_auto_discovery(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "skip_initialscan"); - dvb_adapter_set_skip_initialscan(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "idleclose"); - dvb_adapter_set_idleclose(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "qmon"); - dvb_adapter_set_qmon(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "poweroff"); - dvb_adapter_set_poweroff(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "sidtochan"); - dvb_adapter_set_sidtochan(tda, !!s); - - s = http_arg_get(&hc->hc_req_args, "full_mux_rx"); - dvb_adapter_set_full_mux_rx(tda, atoi(s)-1); - - s = http_arg_get(&hc->hc_req_args, "grace_period"); - dvb_adapter_set_grace_period(tda, atoi(s)); - - if((s = http_arg_get(&hc->hc_req_args, "nitoid")) != NULL) - dvb_adapter_set_nitoid(tda, atoi(s)); - - if((s = http_arg_get(&hc->hc_req_args, "diseqcversion")) != NULL) { - if(!strcmp(s, "DiSEqC 1.0 / 2.0")) - dvb_adapter_set_diseqc_version(tda, 0); - else if(!strcmp(s, "DiSEqC 1.1 / 2.1")) - dvb_adapter_set_diseqc_version(tda, 1); - } - - if((s = http_arg_get(&hc->hc_req_args, "diseqcrepeats")) != NULL) { - if(!strcmp(s, "0")) - dvb_adapter_set_diseqc_repeats(tda, 0); - else if(!strcmp(s, "1")) - dvb_adapter_set_diseqc_repeats(tda, 1); - else if(!strcmp(s, "2")) - dvb_adapter_set_diseqc_repeats(tda, 2); - } - if((s = http_arg_get(&hc->hc_req_args, "extrapriority")) != NULL) - dvb_adapter_set_extrapriority(tda, atoi(s)); - - out = htsmsg_create_map(); - htsmsg_add_u32(out, "success", 1); - } else if(!strcmp(op, "addnetwork")) { - -// sc = http_arg_get(&hc->hc_req_args, "satconf"); - - if((s = http_arg_get(&hc->hc_req_args, "network")) != NULL) - dvb_mux_preconf_add_network(tda->tda_dn, s); - - out = htsmsg_create_map(); - htsmsg_add_u32(out, "success", 1); - - } else if(!strcmp(op, "serviceprobe")) { - - tvhlog(LOG_NOTICE, "web interface", - "Service probe started on \"%s\"", tda->tda_displayname); - - dvb_mux_t *dm; - service_t *s; - - LIST_FOREACH(dm, &tda->tda_dn->dn_muxes, dm_network_link) { - LIST_FOREACH(s, &dm->dm_services, s_group_link) { - if(s->s_enabled) - serviceprobe_enqueue(s); - } - } - - - out = htsmsg_create_map(); - htsmsg_add_u32(out, "success", 1); - - } 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; -} -#endif - -#if 0 - -/** - * - */ -static void -mux_update(htsmsg_t *in) -{ - htsmsg_field_t *f; - htsmsg_t *c; - th_dvb_mux_instance_t *tdmi; - uint32_t u32; - const char *id; - - TAILQ_FOREACH(f, &in->hm_fields, hmf_link) { - if((c = htsmsg_get_map_by_field(f)) == NULL || - (id = htsmsg_get_str(c, "id")) == NULL) - continue; - - if((tdmi = dvb_mux_find_by_identifier(id)) == NULL) - continue; - - if(!htsmsg_get_u32(c, "enabled", &u32)) - dvb_mux_set_enable(tdmi, u32); - } -} - - -/** - * - */ -static void -mux_delete(htsmsg_t *in) -{ - htsmsg_field_t *f; - th_dvb_mux_instance_t *tdmi; - const char *id; - - TAILQ_FOREACH(f, &in->hm_fields, hmf_link) { - if((id = htsmsg_field_get_string(f)) != NULL && - (tdmi = dvb_mux_find_by_identifier(id)) != NULL) - dvb_mux_destroy(tdmi); - } -} - - -/** - * - */ -static int -extjs_dvbmuxes(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - th_dvb_adapter_t *tda; - htsmsg_t *out, *array, *in; - const char *op = http_arg_get(&hc->hc_req_args, "op"); - const char *entries = http_arg_get(&hc->hc_req_args, "entries"); - th_dvb_mux_instance_t *tdmi; - - pthread_mutex_lock(&global_lock); - - if(remain == NULL || - (tda = dvb_adapter_find_by_identifier(remain)) == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - in = entries != NULL ? htsmsg_json_deserialize(entries) : NULL; - - out = htsmsg_create_map(); - - if(!strcmp(op, "get")) { - array = htsmsg_create_list(); - - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) - htsmsg_add_msg(array, NULL, dvb_mux_build_msg(tdmi)); - - htsmsg_add_msg(out, "entries", array); - } else if(!strcmp(op, "update")) { - if(in != NULL) - mux_update(in); - - out = htsmsg_create_map(); - - } else if(!strcmp(op, "delete")) { - if(in != NULL) - mux_delete(in); - - out = htsmsg_create_map(); - - } else { - pthread_mutex_unlock(&global_lock); - if(in != NULL) - htsmsg_destroy(in); - htsmsg_destroy(out); - 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"); - - if(in != NULL) - htsmsg_destroy(in); - - return 0; -} - - - - -/** - * - */ -static int -transportcmp(const void *A, const void *B) -{ - service_t *a = *(service_t **)A; - service_t *b = *(service_t **)B; - - return strcasecmp(a->s_svcname ?: "\0377", b->s_svcname ?: "\0377"); -} - -/** - * - */ -static int -extjs_dvbservices(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - th_dvb_adapter_t *tda; - htsmsg_t *out, *array, *in; - const char *op = http_arg_get(&hc->hc_req_args, "op"); - const char *entries = http_arg_get(&hc->hc_req_args, "entries"); - th_dvb_mux_instance_t *tdmi; - service_t *t, **tvec; - int count = 0, i = 0; - - pthread_mutex_lock(&global_lock); - - if(remain == NULL || - (tda = dvb_adapter_find_by_identifier(remain)) == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - in = entries != NULL ? htsmsg_json_deserialize(entries) : NULL; - - if(!strcmp(op, "get")) { - - out = htsmsg_create_map(); - array = htsmsg_create_list(); - - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) { - count++; - } - } - - tvec = alloca(sizeof(service_t *) * count); - - LIST_FOREACH(tdmi, &tda->tda_dn->dn_mux_instances, tdmi_adapter_link) { - LIST_FOREACH(t, &tdmi->tdmi_mux->dm_services, s_group_link) { - tvec[i++] = t; - } - } - - qsort(tvec, count, sizeof(service_t *), transportcmp); - - for(i = 0; i < count; i++) - htsmsg_add_msg(array, NULL, dvb_service_build_msg(tvec[i])); - - htsmsg_add_msg(out, "entries", array); - - } else if(!strcmp(op, "update")) { - if(in != NULL) - extjs_service_update(in); - - out = htsmsg_create_map(); - - } else { - pthread_mutex_unlock(&global_lock); - htsmsg_destroy(in); - return HTTP_STATUS_BAD_REQUEST; - } - - htsmsg_destroy(in); - - 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; -} - -/** - * - */ -static int -extjs_lnbtypes(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - htsmsg_t *out; - - out = htsmsg_create_map(); - - htsmsg_add_msg(out, "entries", dvb_lnblist_get()); - - htsmsg_json_serialize(out, hq, 0); - htsmsg_destroy(out); - http_output_content(hc, "text/x-json; charset=UTF-8"); - return 0; -} - - - - -/** - * - */ -static int -extjs_dvbsatconf(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - th_dvb_adapter_t *tda; - htsmsg_t *out; - const char *adapter = http_arg_get(&hc->hc_req_args, "adapter"); - - pthread_mutex_lock(&global_lock); - - if((remain == NULL || - (tda = dvb_adapter_find_by_identifier(remain)) == NULL) && - (adapter == NULL || - (tda = dvb_adapter_find_by_identifier(adapter)) == NULL)) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - out = htsmsg_create_map(); - htsmsg_add_msg(out, "entries", dvb_satconf_list(tda)); - - 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; -} - - -/** - * - */ -static int -extjs_dvb_feopts(http_connection_t *hc, const char *remain, void *opaque) -{ - htsbuf_queue_t *hq = &hc->hc_reply; - char *a, *r; - th_dvb_adapter_t *tda; - htsmsg_t *e, *out; - - if(remain == NULL) - return 400; - - r = tvh_strdupa(remain); - if((a = strchr(r, '/')) == NULL) - return 400; - *a++ = 0; - - pthread_mutex_lock(&global_lock); - - if((tda = dvb_adapter_find_by_identifier(a)) == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - e = dvb_fe_opts(tda, r); - - if(e == NULL) { - pthread_mutex_unlock(&global_lock); - return 400; - } - - out = htsmsg_create_map(); - htsmsg_add_msg(out, "entries", e); - - pthread_mutex_unlock(&global_lock); - - htsmsg_json_serialize(out, hq, 0); - http_output_content(hc, "text/x-json; charset=UTF-8"); - htsmsg_destroy(out); - return 0; -} - -/** - * - */ -static int -extjs_dvb_addmux(http_connection_t *hc, const char *remain, void *opaque) -{ - htsmsg_t *out; - htsbuf_queue_t *hq = &hc->hc_reply; - struct http_arg_list *args = &hc->hc_req_args; - th_dvb_adapter_t *tda; - const char *err; - pthread_mutex_lock(&global_lock); - - if(remain == NULL || - (tda = dvb_adapter_find_by_identifier(remain)) == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - err = - dvb_mux_add_by_params(tda, - atoi(http_arg_get(args, "frequency")?:"-1"), - atoi(http_arg_get(args, "symbolrate")?: "-1"), - atoi(http_arg_get(args, "bandwidthID")?: "-1"), - atoi(http_arg_get(args, "constellationID")?: "-1"), - atoi(http_arg_get(args, "delsysID")?: "-1"), - atoi(http_arg_get(args, "tmodeID")?: "-1"), - atoi(http_arg_get(args, "guardintervalID")?: "-1"), - atoi(http_arg_get(args, "hierarchyID")?: "-1"), - atoi(http_arg_get(args, "fechiID")?: "-1"), - atoi(http_arg_get(args, "fecloID")?: "-1"), - atoi(http_arg_get(args, "fecID")?: "-1"), - atoi(http_arg_get(args, "polarisationID")?: "-1"), - http_arg_get(args, "satconfID") ?: NULL); - - if(err != NULL) - tvhlog(LOG_ERR, "web interface", - "Unable to create mux on %s: %s", - tda->tda_displayname, err); - - pthread_mutex_unlock(&global_lock); - - out = htsmsg_create_map(); - htsmsg_json_serialize(out, hq, 0); - http_output_content(hc, "text/x-json; charset=UTF-8"); - htsmsg_destroy(out); - - return 0; -} - -#if 0 -/** - * - */ -static int -extjs_dvb_copymux(http_connection_t *hc, const char *remain, void *opaque) -{ - htsmsg_t *out; - htsbuf_queue_t *hq = &hc->hc_reply; - th_dvb_adapter_t *tda; - htsmsg_t *in; - const char *entries = http_arg_get(&hc->hc_req_args, "entries"); - const char *satconf = http_arg_get(&hc->hc_req_args, "satconf"); - const char *id; - htsmsg_field_t *f; - th_dvb_mux_instance_t *tdmi; - dvb_satconf_t *sc = NULL; - - in = entries != NULL ? htsmsg_json_deserialize(entries) : NULL; - - if(in == NULL) - return 400; - - pthread_mutex_lock(&global_lock); - - if(remain == NULL || - (tda = dvb_adapter_find_by_identifier(remain)) == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - - if (satconf) { - sc = dvb_satconf_entry_find(tda, satconf, 0); - if (sc == NULL) { - pthread_mutex_unlock(&global_lock); - return 404; - } - } - - TAILQ_FOREACH(f, &in->hm_fields, hmf_link) { - if((id = htsmsg_field_get_string(f)) != NULL && - (tdmi = dvb_mux_find_by_identifier(id)) != NULL && - tda != tdmi->tdmi_adapter) { - - if(dvb_mux_copy(tda, tdmi, sc)) { - char buf[100]; - dvb_mux_nicename(buf, sizeof(buf), tdmi); - - tvhlog(LOG_NOTICE, "DVB", - "Skipped copy of mux %s to adapter %s, mux already exist", - buf, tda->tda_displayname); - } - } - } - - pthread_mutex_unlock(&global_lock); - - out = htsmsg_create_map(); - htsmsg_json_serialize(out, hq, 0); - http_output_content(hc, "text/x-json; charset=UTF-8"); - htsmsg_destroy(out); - - return 0; -} -#endif - -#endif - -/** - * - */ -#if 0 -static int -extjs_dvbnetworks(http_connection_t *hc, const char *remain, void *opaque) -{ - return extjs_get_idnode(hc, remain, opaque, &dvb_network_root); -} -#endif - -#if 0 -static int -extjs_mpegts_services_filter - (mpegts_service_t *s, htsmsg_t *filter) -{ - htsmsg_t *e; - htsmsg_field_t *f; - const char *n; - HTSMSG_FOREACH(f, filter) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(n = htsmsg_get_str(e, "field"))) continue; - if (!strcmp(n, "name")) - if (!strstr(s->s_dvb_svcname ?: "", htsmsg_get_str(e, "value") ?: "")) return 1; - if (!strcmp(n, "sid")) { - const char *t = htsmsg_get_str(e, "comparison"); - const char *v = htsmsg_get_str(e, "value"); - if (!strcmp(t ?: "", "gt")) { - if (s->s_dvb_service_id < atoi(v)) return 1; - } else if (!strcmp(t ?: "", "lt")) { - if (s->s_dvb_service_id > atoi(v)) return 1; - } else if (!strcmp(t ?: "", "eq")) { - if (s->s_dvb_service_id != atoi(v)) return 1; - } - } - } - return 0; -} -#endif - static int extjs_idnode_filter ( idnode_t *in, htsmsg_t *filter ) @@ -777,11 +100,22 @@ extjs_idnode_filter return 1; } +static htsmsg_t * +extjs_idnode_class ( const idclass_t *idc ) +{ + htsmsg_t *ret = htsmsg_create_list(); + while (idc) { + prop_add_params_to_msg(NULL, idc->ic_properties, ret); + idc = idc->ic_super; + } + return ret; +} + static int extjs_mpegts_services (http_connection_t *hc, const char *remain, void *opaque) { - char buf[256]; + //char buf[256]; mpegts_network_t *mn; mpegts_mux_t *mm; mpegts_service_t *ms; @@ -807,21 +141,7 @@ extjs_mpegts_services conf.limit--; htsmsg_t *e = htsmsg_create_map(); htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&ms->s_id)); - mm->mm_display_name(mm, buf, sizeof(buf)); - htsmsg_add_str(e, "mux", buf); - htsmsg_add_bool(e, "enabled", ms->s_enabled); - htsmsg_add_u32(e, "sid", ms->s_dvb_service_id); - htsmsg_add_u32(e, "pmt", ms->s_pmt_pid); - htsmsg_add_u32(e, "lcn", ms->s_dvb_channel_num); - if (ms->s_dvb_svcname) - htsmsg_add_str(e, "name", ms->s_dvb_svcname); - if (ms->s_dvb_provider) - htsmsg_add_str(e, "provider", ms->s_dvb_provider); - if (ms->s_dvb_cridauth) - htsmsg_add_str(e, "crid_auth", ms->s_dvb_cridauth); - if (ms->s_dvb_charset) - htsmsg_add_str(e, "charset", ms->s_dvb_charset); - htsmsg_add_u32(e, "type", ms->s_dvb_servicetype); + idnode_save(&ms->s_id, e); htsmsg_add_msg(list, NULL, e); conf.limit--; } @@ -831,6 +151,10 @@ extjs_mpegts_services pthread_mutex_unlock(&global_lock); htsmsg_add_msg(out, "entries", list); htsmsg_add_u32(out, "total", total); + } else if (!strcmp(op, "class")) { + extern const idclass_t mpegts_service_class; + htsmsg_t *list= extjs_idnode_class(&mpegts_service_class); + htsmsg_add_msg(out, "entries", list); } htsmsg_json_serialize(out, hq, 0); @@ -847,35 +171,50 @@ extjs_mpegts_muxes { char buf[256]; mpegts_network_t *mn; - mpegts_mux_t *mm; + mpegts_mux_t *mm; mpegts_service_t *ms; - int s; - htsmsg_t *out, *list = htsmsg_create_list(); - htsbuf_queue_t *hq = &hc->hc_reply; - pthread_mutex_lock(&global_lock); - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - s = 0; - htsmsg_t *e = htsmsg_create_map(); - htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mm->mm_id)); - mn->mn_display_name(mn, buf, sizeof(buf)); - htsmsg_add_str(e, "network", buf); - mm->mm_display_name(mm, buf, sizeof(buf)); - htsmsg_add_str(e, "name", buf); - htsmsg_add_bool(e, "enabled", mm->mm_enabled); - htsmsg_add_u32(e, "onid", mm->mm_onid); - htsmsg_add_u32(e, "tsid", mm->mm_tsid); - htsmsg_add_bool(e, "initscan", mm->mm_initial_scan_done); - htsmsg_add_str(e, "crid_auth", mm->mm_crid_authority ?: ""); - LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) - s++; - htsmsg_add_u32(e, "num_svc", s); - htsmsg_add_msg(list, NULL, e); + htsbuf_queue_t *hq = &hc->hc_reply; + const char *op = http_arg_get(&hc->hc_req_args, "op"); + htsmsg_t *out = htsmsg_create_map(); + extjs_grid_conf_t conf; + int s, total = 0; + + if (!strcmp(op, "list")) { + htsmsg_t *list = htsmsg_create_list(); + extjs_grid_conf(&hc->hc_req_args, &conf); + + pthread_mutex_lock(&global_lock); + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + if (conf.filter && !extjs_idnode_filter(&mm->mm_id, conf.filter)) + continue; + total++; + if (conf.start-- > 0) + continue; + if (conf.limit) { + s = 0; + conf.limit--; + htsmsg_t *e = htsmsg_create_map(); + htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mm->mm_id)); + idnode_save(&mm->mm_id, e); + mn->mn_display_name(mn, buf, sizeof(buf)); + htsmsg_add_str(e, "network", buf); + LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) + s++; + htsmsg_add_u32(e, "num_svc", s); + htsmsg_add_msg(list, NULL, e); + } + } } + pthread_mutex_unlock(&global_lock); + htsmsg_add_msg(out, "entries", list); + htsmsg_add_u32(out, "total", total); + } else if (!strcmp(op, "class")) { + extern const idclass_t mpegts_mux_class; + htsmsg_t *list= extjs_idnode_class(&mpegts_mux_class); + htsmsg_add_msg(out, "entries", list); } - pthread_mutex_unlock(&global_lock); - out = htsmsg_create_map(); - htsmsg_add_msg(out, "entries", list); + htsmsg_json_serialize(out, hq, 0); http_output_content(hc, "text/x-json; charset=UTF-8"); htsmsg_destroy(out); @@ -887,35 +226,51 @@ static int extjs_mpegts_networks (http_connection_t *hc, const char *remain, void *opaque) { - char buf[256]; mpegts_network_t *mn; - mpegts_mux_t *mm; + mpegts_mux_t *mm; mpegts_service_t *ms; - int m, s; - htsmsg_t *out, *list = htsmsg_create_list(); - htsbuf_queue_t *hq = &hc->hc_reply; - pthread_mutex_lock(&global_lock); - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - m = s = 0; - htsmsg_t *e = htsmsg_create_map(); - htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mn->mn_id)); - mn->mn_display_name(mn, buf, sizeof(buf)); - htsmsg_add_str(e, "name", buf); - htsmsg_add_u32(e, "nid", mn->mn_nid); - htsmsg_add_u32(e, "autodiscovery", mn->mn_autodiscovery); - htsmsg_add_u32(e, "skipinitscan", mn->mn_skipinitscan); - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - m++; - LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) - s++; + htsbuf_queue_t *hq = &hc->hc_reply; + const char *op = http_arg_get(&hc->hc_req_args, "op"); + htsmsg_t *out = htsmsg_create_map(); + extjs_grid_conf_t conf; + int s, m, total = 0; + + if (!strcmp(op, "list")) { + htsmsg_t *list = htsmsg_create_list(); + extjs_grid_conf(&hc->hc_req_args, &conf); + + pthread_mutex_lock(&global_lock); + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + if (conf.filter && !extjs_idnode_filter(&mn->mn_id, conf.filter)) + continue; + total++; + if (conf.start-- > 0) + continue; + if (conf.limit) { + s = m = 0; + conf.limit--; + htsmsg_t *e = htsmsg_create_map(); + htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mn->mn_id)); + idnode_save(&mn->mn_id, e); + LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + m++; + LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) + s++; + } + htsmsg_add_u32(e, "num_mux", m); + htsmsg_add_u32(e, "num_svc", s); + htsmsg_add_msg(list, NULL, e); + } } - htsmsg_add_u32(e, "num_mux", m); - htsmsg_add_u32(e, "num_svc", s); - htsmsg_add_msg(list, NULL, e); + pthread_mutex_unlock(&global_lock); + htsmsg_add_msg(out, "entries", list); + htsmsg_add_u32(out, "total", total); + } else if (!strcmp(op, "class")) { + extern const idclass_t mpegts_network_class; + htsmsg_t *list= extjs_idnode_class(&mpegts_network_class); + htsmsg_add_msg(out, "entries", list); } - pthread_mutex_unlock(&global_lock); - out = htsmsg_create_map(); - htsmsg_add_msg(out, "entries", list); + htsmsg_json_serialize(out, hq, 0); http_output_content(hc, "text/x-json; charset=UTF-8"); htsmsg_destroy(out); @@ -931,11 +286,11 @@ void extjs_start_dvb(void) { printf("extjs_start_dvb()\n"); - http_path_add("/api/mpegts/networks", + http_path_add("/api/mpegts/network", NULL, extjs_mpegts_networks, ACCESS_WEB_INTERFACE); - http_path_add("/api/mpegts/muxes", + http_path_add("/api/mpegts/mux", NULL, extjs_mpegts_muxes, ACCESS_WEB_INTERFACE); - http_path_add("/api/mpegts/services", + http_path_add("/api/mpegts/service", NULL, extjs_mpegts_services, ACCESS_WEB_INTERFACE); #if 0 http_path_add("/dvb/locations", diff --git a/src/webui/static/app/idnode.js b/src/webui/static/app/idnode.js new file mode 100644 index 00000000..cbec99cf --- /dev/null +++ b/src/webui/static/app/idnode.js @@ -0,0 +1,93 @@ +/* + * IDnode grid + */ +tvheadend.idnode_grid = function(panel, conf) +{ + function build (d) + { + if (d && d.responseText) { + d = Ext.util.JSON.decode(d.responseText) + d = d.entries; + } else + d = [] + + /* Process object */ + var columns = []; + var filters = []; + var fields = []; + for (i = 0; i < d.length; i++) { + var type = 'string'; + if (d[i].type == 'int' || d[i].type == 'u16' || d[i].type == 'u32') + type = 'numeric'; + else if (d[i].type == 'bool') + type = 'boolean'; + fields.push(d[i].id) + columns.push({ + dataIndex: d[i].id, + header : d[i].caption, + sortable : true + }); + filters.push({ + type : type, + dataIndex : d[i].id + }); + } + + /* Filters */ + var filter = new Ext.ux.grid.GridFilters({ + encode : true, + local : false, + filters : filters + }); + + /* Store */ + var store = new Ext.data.JsonStore({ + root : 'entries', + url : conf.url, + autoLoad : true, + id : 'uuid', + totalProperty : 'total', + fields : fields, + baseParams : { + op : 'list', + } + }); + + /* Model */ + var model = new Ext.grid.ColumnModel({ + defaultSortable : true, + columns : columns + }); + + /* Grid Panel */ + var grid = new Ext.grid.EditorGridPanel({ + stripeRows : true, + title : conf.title, + store : store, + cm : model, + plugins : [ + filter + ], + viewConfig : { + forceFit : true + }, + bbar : new Ext.PagingToolbar({ + store : store, + pageSize : 50, + displayInfo : true, + displayMsg : conf.title + ' {0} - {1} of {2}', + emptyMsg : 'No ' + conf.title.toLowerCase() + ' to display' + }) + }); + + panel.add(grid); + } + + Ext.Ajax.request({ + url : conf.url, + success : build, + params : { + op: 'class' + } + }); +} diff --git a/src/webui/static/app/mpegts.js b/src/webui/static/app/mpegts.js new file mode 100644 index 00000000..1c4d0605 --- /dev/null +++ b/src/webui/static/app/mpegts.js @@ -0,0 +1,31 @@ +/* + * IDnode stuff + */ + +/* + * DVB network + */ + +tvheadend.networks = function(panel) +{ + tvheadend.idnode_grid(panel, { + url : 'api/mpegts/network', + title: 'Networks' + }); +} + +tvheadend.muxes = function(panel) +{ + tvheadend.idnode_grid(panel, { + url : 'api/mpegts/mux', + title: 'Muxes' + }); +} + +tvheadend.services = function(panel) +{ + tvheadend.idnode_grid(panel, { + url : 'api/mpegts/service', + title: 'Services' + }); +} diff --git a/src/webui/static/app/networks.js b/src/webui/static/app/networks.js deleted file mode 100644 index dd6d4128..00000000 --- a/src/webui/static/app/networks.js +++ /dev/null @@ -1,263 +0,0 @@ -/* - * DVB Networks - */ - -tvheadend.networks = function() -{ - // TODO: build this from mpegts_network_class? - - var model = new Ext.grid.ColumnModel({ - defaultSortable: true, - columns : [ - { - header : 'Name', - dataIndex : 'name', - width : 200, - editor : new Ext.form.TextField({ - allowBlank : true - }) - }, - { - header : 'Network ID', - dataIndex : 'nid', - width : 100, - editor : new Ext.form.NumberField({ - minValue : 0, - maxValue : 65536 - }) - }, - { - header : 'Auto Discovery', - dataIndex : 'autodiscovery', - width : 50, - editor : new Ext.form.Checkbox({}) - }, - { - header : 'Auto Discovery', - dataIndex : 'skipinitscan', - width : 50, - editor : new Ext.form.Checkbox({}) - }, - { - header : '# Muxes', - dataIndex : 'num_mux', - width : 100, - }, - { - header : '# Services', - dataIndex : 'num_svc', - width : 100, - }, - ] - }); - - var store = new Ext.data.JsonStore({ - root : 'entries', - url : 'api/mpegts/networks', - autoLoad : true, - id : 'uuid', - fields : [ - 'uuid', 'name', 'nid', 'autodiscovery', 'skipinitscan', 'num_mux', 'num_svc' - ], - baseParams : { - op : 'list', - } - }); - - var grid = new Ext.grid.EditorGridPanel({ - stripeRows : true, - title : 'Networks', - store : store, - cm : model, - viewConfig : { - forceFit : true - }, - }); - - return grid; -} - -/* - * DVB Muxes - */ - -tvheadend.muxes = function() -{ - // TODO: build this from mpegts_network_class? - - var model = new Ext.grid.ColumnModel({ - defaultSortable: true, - columns : [ - { - header : 'Enabled', - dataIndex : 'enabled', - width : 50, - editor : new Ext.form.Checkbox({}) - }, - { - header : 'Name', - dataIndex : 'name', - width : 100, - }, - { - header : 'ONID', - dataIndex : 'onid', - width : 50, - }, - { - header : 'TSID', - dataIndex : 'tsid', - width : 50, - editor : new Ext.form.Checkbox({}) - }, - { - header : 'CRID Authority', - dataIndex : 'crid_auth', - width : 100, - editor : new Ext.form.Checkbox({}) - }, - { - header : 'Initial Scan', - dataIndex : 'initscan', - width : 50, - }, - { - header : '# Services', - dataIndex : 'num_svc', - width : 50, - }, - ] - }); - - var store = new Ext.data.JsonStore({ - root : 'entries', - url : 'api/mpegts/muxes', - autoLoad : true, - id : 'uuid', - fields : [ - 'uuid', 'network', 'name', 'onid', 'tsid', 'initscan', 'crid_auth', 'num_svc' - ], - baseParams : { - op : 'list', - } - }); - - var grid = new Ext.grid.EditorGridPanel({ - stripeRows : true, - title : 'Muxes', - store : store, - cm : model, - viewConfig : { - forceFit : true - }, - }); - - return grid; -} - -/* - * DVB Services - */ - -tvheadend.services = function() -{ - // TODO: build this from mpegts_network_class? - - var filter = new Ext.ux.grid.GridFilters({ - encode : true, - local : false, - filters : [ - { type: 'string', dataIndex: 'name' }, - { type: 'numeric', dataIndex: 'sid' } - ] - }); - - var model = new Ext.grid.ColumnModel({ - defaultSortable: true, - columns : [ - { - header : 'Enabled', - dataIndex : 'enabled', - width : 50, - editor : new Ext.form.Checkbox({}) - }, - { - header : 'Name', - dataIndex : 'name', - width : 100, - filterable : true, - }, - { - header : 'Mux', - dataIndex : 'mux', - width : 100, - }, - { - header : 'SID', - dataIndex : 'sid', - width : 50, - }, - { - header : 'PMT PID', - dataIndex : 'pmt', - width : 50, - }, - { - header : 'Type', - dataIndex : 'type', - width : 50, - }, - { - header : 'Provider', - dataIndex : 'provider', - width : 100, - }, - { - header : 'CRID Authority', - dataIndex : 'crid_auth', - width : 100, - }, - { - header : 'Charset', - dataIndex : 'charset', - width : 100, - }, - ] - }); - - var store = new Ext.data.JsonStore({ - root : 'entries', - url : 'api/mpegts/services', - autoLoad : true, - id : 'uuid', - totalProperty: 'total', - fields : [ - 'uuid', 'mux', 'name', 'sid', 'pmt', 'type', 'provider', 'crid_auth', 'charset' - ], - baseParams : { - op : 'list', - } - }); - - var grid = new Ext.grid.EditorGridPanel({ - stripeRows : true, - title : 'Services', - store : store, - cm : model, - plugins : [ - filter - ], - viewConfig : { - forceFit : true - }, - bbar : new Ext.PagingToolbar({ - store: store, - pageSize: 50, - displayInfo: true, - displayMsg: 'Services {0} - {1} of {2}', - emptyMsg: 'No services to display' - }) - }); - - return grid; -} diff --git a/src/webui/static/app/tvheadend.js b/src/webui/static/app/tvheadend.js index 2c7d7c54..f7c92417 100644 --- a/src/webui/static/app/tvheadend.js +++ b/src/webui/static/app/tvheadend.js @@ -268,9 +268,6 @@ function accessUpdate(o) { tabs2.push(new tvheadend.tvadapters); } tabs2.push(new tvheadend.iptv); - tabs2.push(new tvheadend.networks); - tabs2.push(new tvheadend.muxes); - tabs2.push(new tvheadend.services); tvheadend.conf_dvbin = new Ext.TabPanel({ activeTab: 0, autoScroll: true, @@ -278,6 +275,9 @@ function accessUpdate(o) { iconCls: 'hardware', items : tabs2 }); + tvheadend.networks(tvheadend.conf_dvbin); + tvheadend.muxes(tvheadend.conf_dvbin); + tvheadend.services(tvheadend.conf_dvbin); tabs1.push(tvheadend.conf_dvbin); /* Channel / EPG */