webui: updated the webui to use new idnode API
This includes generic routines for all pagination, filtering and sorting.
This commit is contained in:
parent
7037697cca
commit
4d1b777d53
3 changed files with 141 additions and 150 deletions
|
@ -16,6 +16,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
@ -39,13 +40,25 @@
|
|||
|
||||
#include "input.h"
|
||||
|
||||
extern const idclass_t mpegts_input_class;
|
||||
extern const idclass_t mpegts_network_class;
|
||||
extern const idclass_t mpegts_mux_class;
|
||||
extern const idclass_t mpegts_service_class;
|
||||
|
||||
typedef struct extjs_grid_conf
|
||||
{
|
||||
int start;
|
||||
int limit;
|
||||
htsmsg_t *filter;
|
||||
int start;
|
||||
int limit;
|
||||
idnode_filter_t filter;
|
||||
idnode_sort_t sort;
|
||||
} extjs_grid_conf_t;
|
||||
|
||||
static struct strtab extjs_filtcmp_tab[] = {
|
||||
{ "gt", IC_GT },
|
||||
{ "lt", IC_LT },
|
||||
{ "eq", IC_EQ }
|
||||
};
|
||||
|
||||
static void
|
||||
extjs_grid_conf
|
||||
( struct http_arg_list *args, extjs_grid_conf_t *conf )
|
||||
|
@ -59,45 +72,40 @@ extjs_grid_conf
|
|||
conf->limit = atoi(str);
|
||||
else
|
||||
conf->limit = 50;
|
||||
if ((str = http_arg_get(args, "filter")))
|
||||
conf->filter = htsmsg_json_deserialize(str);
|
||||
else
|
||||
conf->filter = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
extjs_idnode_filter
|
||||
( idnode_t *in, htsmsg_t *filter )
|
||||
{
|
||||
htsmsg_t *e;
|
||||
htsmsg_field_t *f;
|
||||
const char *k, *t;
|
||||
|
||||
HTSMSG_FOREACH(f, filter) {
|
||||
if (!(e = htsmsg_get_map_by_field(f))) continue;
|
||||
if (!(k = htsmsg_get_str(e, "field"))) continue;
|
||||
if (!(t = htsmsg_get_str(e, "type"))) continue;
|
||||
if (!strcmp(t, "string")) {
|
||||
const char *str = idnode_get_str(in, k);
|
||||
if (!strstr(str ?: "", htsmsg_get_str(e, "value") ?: ""))
|
||||
return 0;
|
||||
} else if (!strcmp(t, "numeric")) {
|
||||
uint32_t u32, val;
|
||||
if (!idnode_get_u32(in, k, &u32)) {
|
||||
const char *op = htsmsg_get_str(e, "comparison");
|
||||
if (!op) continue;
|
||||
if (htsmsg_get_u32(e, "value", &val)) continue;
|
||||
if (!strcmp(op, "lt")) {
|
||||
if (u32 > val) return 0;
|
||||
} else if (!strcmp(op, "gt")) {
|
||||
if (u32 < val) return 0;
|
||||
} else {
|
||||
if (u32 != val) return 0;
|
||||
if ((str = http_arg_get(args, "filter"))) {
|
||||
htsmsg_field_t *f;
|
||||
htsmsg_t *e, *t = htsmsg_json_deserialize(str);
|
||||
HTSMSG_FOREACH(f, t) {
|
||||
const char *k, *t, *v;
|
||||
if (!(e = htsmsg_get_map_by_field(f))) continue;
|
||||
if (!(k = htsmsg_get_str(e, "field"))) continue;
|
||||
if (!(t = htsmsg_get_str(e, "type"))) continue;
|
||||
if (!strcmp(t, "string")) {
|
||||
if ((v = htsmsg_get_str(e, "value")))
|
||||
idnode_filter_add_str(&conf->filter, k, v, IC_RE);
|
||||
} else if (!strcmp(t, "numeric")) {
|
||||
uint32_t v;
|
||||
if (!htsmsg_get_u32(e, "value", &v)) {
|
||||
int t = str2val(htsmsg_get_str(e, "comparison") ?: "",
|
||||
extjs_filtcmp_tab);
|
||||
idnode_filter_add_num(&conf->filter, k, v, t == -1 ? IC_EQ : t);
|
||||
}
|
||||
} else if (!strcmp(t, "boolean")) {
|
||||
uint32_t v;
|
||||
if (!htsmsg_get_u32(e, "value", &v))
|
||||
idnode_filter_add_bool(&conf->filter, k, v, IC_EQ);
|
||||
}
|
||||
}
|
||||
htsmsg_destroy(t);
|
||||
}
|
||||
return 1;
|
||||
if ((str = http_arg_get(args, "sort"))) {
|
||||
conf->sort.key = str;
|
||||
if ((str = http_arg_get(args, "dir")) && !strcmp(str, "DESC"))
|
||||
conf->sort.dir = IS_DSC;
|
||||
else
|
||||
conf->sort.dir = IS_ASC;
|
||||
} else
|
||||
conf->sort.key = NULL;
|
||||
}
|
||||
|
||||
// TODO: move this
|
||||
|
@ -112,6 +120,27 @@ extjs_idnode_class ( const idclass_t *idc )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
extjs_idnode_grid
|
||||
(idnode_set_t *ins, extjs_grid_conf_t *conf, htsmsg_t *out)
|
||||
{
|
||||
int i;
|
||||
htsmsg_t *list = htsmsg_create_list();
|
||||
if (conf->sort.key)
|
||||
idnode_set_sort(ins, &conf->sort);
|
||||
for (i = conf->start; i < ins->is_count && conf->limit > 0; i++, conf->limit--) {
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
htsmsg_add_str(e, "uuid", idnode_uuid_as_str(ins->is_array[i]));
|
||||
idnode_save(ins->is_array[i], e);
|
||||
htsmsg_add_msg(list, NULL, e);
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
free(ins->is_array);
|
||||
idnode_filter_clear(&conf->filter);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
htsmsg_add_u32(out, "total", ins->is_count);
|
||||
}
|
||||
|
||||
static int
|
||||
extjs_mpegts_service
|
||||
(http_connection_t *hc, const char *remain, void *opaque)
|
||||
|
@ -123,38 +152,22 @@ extjs_mpegts_service
|
|||
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 total = 0;
|
||||
extjs_grid_conf_t conf = { 0 };
|
||||
|
||||
if (!strcmp(op, "list")) {
|
||||
htsmsg_t *list = htsmsg_create_list();
|
||||
idnode_set_t ins = { 0 };
|
||||
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) {
|
||||
LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) {
|
||||
if (conf.filter && !extjs_idnode_filter(&ms->s_id, conf.filter))
|
||||
continue;
|
||||
total++;
|
||||
if (conf.start-- > 0)
|
||||
continue;
|
||||
if (conf.limit) {
|
||||
conf.limit--;
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&ms->s_id));
|
||||
idnode_save(&ms->s_id, e);
|
||||
htsmsg_add_msg(list, NULL, e);
|
||||
conf.limit--;
|
||||
}
|
||||
idnode_set_add(&ins, (idnode_t*)ms, &conf.filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
htsmsg_add_u32(out, "total", total);
|
||||
extjs_idnode_grid(&ins, &conf, out);
|
||||
} else if (!strcmp(op, "class")) {
|
||||
extern const idclass_t mpegts_service_class;
|
||||
htsmsg_t *list= extjs_idnode_class(&mpegts_service_class);
|
||||
htsmsg_t *list = extjs_idnode_class(&mpegts_service_class);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
}
|
||||
|
||||
|
@ -170,49 +183,25 @@ static int
|
|||
extjs_mpegts_mux
|
||||
(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
char buf[256];
|
||||
mpegts_network_t *mn;
|
||||
mpegts_mux_t *mm;
|
||||
mpegts_service_t *ms;
|
||||
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;
|
||||
extjs_grid_conf_t conf = { 0 };
|
||||
|
||||
if (!strcmp(op, "list")) {
|
||||
htsmsg_t *list = htsmsg_create_list();
|
||||
idnode_set_t ins = { 0 };
|
||||
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);
|
||||
}
|
||||
idnode_set_add(&ins, (idnode_t*)mm, &conf.filter);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
htsmsg_add_u32(out, "total", total);
|
||||
extjs_idnode_grid(&ins, &conf, out);
|
||||
} else if (!strcmp(op, "class")) {
|
||||
extern const idclass_t mpegts_mux_class;
|
||||
htsmsg_t *list= extjs_idnode_class(&mpegts_mux_class);
|
||||
htsmsg_t *list = extjs_idnode_class(&mpegts_mux_class);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
}
|
||||
|
||||
|
@ -228,48 +217,22 @@ extjs_mpegts_network
|
|||
(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
mpegts_network_t *mn;
|
||||
mpegts_mux_t *mm;
|
||||
mpegts_service_t *ms;
|
||||
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;
|
||||
extjs_grid_conf_t conf = { 0 };
|
||||
|
||||
if (!strcmp(op, "list")) {
|
||||
htsmsg_t *list = htsmsg_create_list();
|
||||
idnode_set_t ins = { 0 };
|
||||
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);
|
||||
}
|
||||
idnode_set_add(&ins, (idnode_t*)mn, &conf.filter);
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
htsmsg_add_u32(out, "total", total);
|
||||
extjs_idnode_grid(&ins, &conf, out);
|
||||
} 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);
|
||||
htsmsg_t *c = extjs_idnode_class(&mpegts_network_class);
|
||||
htsmsg_add_msg(out, "entries", c);
|
||||
}
|
||||
|
||||
htsmsg_json_serialize(out, hq, 0);
|
||||
|
@ -283,39 +246,37 @@ static int
|
|||
extjs_mpegts_input
|
||||
(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
extern const idclass_t mpegts_input_class;
|
||||
mpegts_input_t *mi;
|
||||
mpegts_network_t *mn;
|
||||
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 total = 0;
|
||||
extjs_grid_conf_t conf = { 0 };
|
||||
|
||||
if (!op) return 404;
|
||||
|
||||
if (!strcmp(op, "list")) {
|
||||
int i;
|
||||
idnode_set_t ins = { 0 };
|
||||
htsmsg_t *list = htsmsg_create_list();
|
||||
extjs_grid_conf(&hc->hc_req_args, &conf);
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
LIST_FOREACH(mi, &mpegts_input_all, mi_global_link) {
|
||||
if (conf.filter && !extjs_idnode_filter(&mi->mi_id, conf.filter))
|
||||
continue;
|
||||
total++;
|
||||
if (conf.start-- > 0)
|
||||
continue;
|
||||
if (conf.limit != 0) {
|
||||
if (conf.limit > 0) conf.limit--;
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&mi->mi_id));
|
||||
idnode_save(&mi->mi_id, e);
|
||||
htsmsg_add_msg(list, NULL, e);
|
||||
}
|
||||
idnode_set_add(&ins, (idnode_t*)mi, &conf.filter);
|
||||
}
|
||||
if (conf.sort.key)
|
||||
idnode_set_sort(&ins, &conf.sort);
|
||||
for (i = conf.start; i < ins.is_count && conf.limit > 0; i++, conf.limit--) {
|
||||
htsmsg_t *e = htsmsg_create_map();
|
||||
htsmsg_add_str(e, "uuid", idnode_uuid_as_str(ins.is_array[i]));
|
||||
idnode_save(ins.is_array[i], e);
|
||||
htsmsg_add_msg(list, NULL, e);
|
||||
}
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
free(ins.is_array);
|
||||
idnode_filter_clear(&conf.filter);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
htsmsg_add_u32(out, "total", total);
|
||||
htsmsg_add_u32(out, "total", ins.is_count);
|
||||
} else if (!strcmp(op, "class")) {
|
||||
htsmsg_t *list= extjs_idnode_class(&mpegts_input_class);
|
||||
htsmsg_add_msg(out, "entries", list);
|
||||
|
|
|
@ -157,9 +157,6 @@ tvheadend.idnode_grid = function(panel, conf)
|
|||
var addBtn = null;
|
||||
var delBtn = null;
|
||||
|
||||
/* Load Class */
|
||||
d = json_decode(d);
|
||||
|
||||
/* Process */
|
||||
for (i = 0; i < d.length; i++) {
|
||||
var type = 'string';
|
||||
|
@ -206,6 +203,7 @@ tvheadend.idnode_grid = function(panel, conf)
|
|||
id : 'uuid',
|
||||
totalProperty : 'total',
|
||||
fields : fields,
|
||||
remoteSort : true,
|
||||
baseParams : {
|
||||
op : 'list',
|
||||
}
|
||||
|
@ -309,11 +307,19 @@ tvheadend.idnode_grid = function(panel, conf)
|
|||
panel.add(grid);
|
||||
}
|
||||
|
||||
Ext.Ajax.request({
|
||||
url : conf.url,
|
||||
success : build,
|
||||
params : {
|
||||
op: 'class'
|
||||
}
|
||||
});
|
||||
/* Request data */
|
||||
if (!conf.fields) {
|
||||
Ext.Ajax.request({
|
||||
url : conf.url,
|
||||
params : {
|
||||
op: 'class'
|
||||
},
|
||||
success : function(d)
|
||||
{
|
||||
build(json_decode(d));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
build(conf.fields);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,38 @@
|
|||
|
||||
tvheadend.networks = function(panel)
|
||||
{
|
||||
var fields = [
|
||||
{
|
||||
type : 'str',
|
||||
id : 'name',
|
||||
caption : 'Network Name'
|
||||
},
|
||||
{
|
||||
type : 'u16',
|
||||
id : 'nid',
|
||||
caption : 'Network ID'
|
||||
},
|
||||
{
|
||||
type : 'bool',
|
||||
id : 'initscan',
|
||||
caption : 'Initial scan'
|
||||
},
|
||||
{
|
||||
type : 'bool',
|
||||
id : 'autodiscovery',
|
||||
caption : 'Auto-discovery'
|
||||
}
|
||||
];
|
||||
|
||||
tvheadend.idnode_grid(panel, {
|
||||
title : 'Networks',
|
||||
url : 'api/mpegts/network',
|
||||
title : 'Network',
|
||||
url : 'api/mpegts/network',
|
||||
//fields : fields,
|
||||
add : {
|
||||
url : 'api/mpegts/input',
|
||||
title : 'Network',
|
||||
select : {
|
||||
label : 'Input',
|
||||
caption : 'Input',
|
||||
params : { op: 'list', limit: -1 },
|
||||
displayField : 'fe_path',//displayname',
|
||||
valueField : 'uuid',
|
||||
|
|
Loading…
Add table
Reference in a new issue