webui: starting to get a slightly more usable idnode grid framework

The layout of the grid and filtering etc. is now auto-setup from the
idnode class definition.

I think I need to extend idnode to allow it to be used more for this
context.
This commit is contained in:
Adam Sutton 2013-06-04 11:11:05 +01:00
parent e9631fa6ed
commit 331a63c6de
6 changed files with 231 additions and 1014 deletions

View file

@ -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

View file

@ -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",

View file

@ -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'
}
});
}

View file

@ -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'
});
}

View file

@ -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;
}

View file

@ -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 */