status: some additional status information about connections

also re-jigged UI layout (I'm sure people will moan) and some code
re-layout too.
This commit is contained in:
Adam Sutton 2013-11-11 17:11:41 +00:00
parent 1b22e08ab9
commit 73c6bc9f48
11 changed files with 154 additions and 97 deletions

View file

@ -113,6 +113,7 @@ SRCS = src/version.c \
SRCS += \
src/api.c \
src/api/api_status.c \
src/api/api_idnode.c \
src/api/api_input.c \
src/api/api_channel.c \

View file

@ -122,4 +122,5 @@ void api_init ( void )
api_channel_init();
api_epg_init();
api_epggrab_init();
api_status_init();
}

View file

@ -63,6 +63,7 @@ void api_channel_init ( void );
void api_mpegts_init ( void );
void api_epg_init ( void );
void api_epggrab_init ( void );
void api_status_init ( void );
/*
* IDnode

View file

@ -26,36 +26,6 @@
#include "access.h"
#include "api.h"
static int
api_input_status
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
int c = 0;
htsmsg_t *l, *e;
tvh_input_t *ti;
tvh_input_stream_t *st;
tvh_input_stream_list_t stl = { 0 };
TVH_INPUT_FOREACH(ti)
ti->ti_get_streams(ti, &stl);
l = htsmsg_create_list();
while ((st = LIST_FIRST(&stl))) {
e = tvh_input_stream_create_msg(st);
htsmsg_add_msg(l, NULL, e);
tvh_input_stream_destroy(st);
LIST_REMOVE(st, link);
free(st);
c++;
}
*resp = htsmsg_create_map();
htsmsg_add_msg(*resp, "entries", l);
htsmsg_add_u32(*resp, "totalCount", c);
return 0;
}
static idnode_set_t *
api_input_hw_tree ( void )
{
@ -69,7 +39,6 @@ api_input_hw_tree ( void )
void api_input_init ( void )
{
static api_hook_t ah[] = {
{ "input/status", ACCESS_ANONYMOUS, api_input_status, NULL },
{ "hardware/tree", ACCESS_ADMIN, api_idnode_tree, api_input_hw_tree },
{ NULL },
};

View file

@ -24,9 +24,41 @@
#include "subscriptions.h"
#include "access.h"
#include "api.h"
#include "tcp.h"
#include "input.h"
static int
api_subscription_list
api_status_inputs
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
int c = 0;
htsmsg_t *l, *e;
tvh_input_t *ti;
tvh_input_stream_t *st;
tvh_input_stream_list_t stl = { 0 };
TVH_INPUT_FOREACH(ti)
ti->ti_get_streams(ti, &stl);
l = htsmsg_create_list();
while ((st = LIST_FIRST(&stl))) {
e = tvh_input_stream_create_msg(st);
htsmsg_add_msg(l, NULL, e);
tvh_input_stream_destroy(st);
LIST_REMOVE(st, link);
free(st);
c++;
}
*resp = htsmsg_create_map();
htsmsg_add_msg(*resp, "entries", l);
htsmsg_add_u32(*resp, "totalCount", c);
return 0;
}
static int
api_status_subscriptions
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
int c;
@ -43,16 +75,27 @@ api_subscription_list
*resp = htsmsg_create_map();
htsmsg_add_msg(*resp, "entries", l);
htsmsg_add_msg(*resp, "totalCount", c);
htsmsg_add_u32(*resp, "totalCount", c);
return 0;
}
void api_service_init ( void )
static int
api_status_connections
( void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
pthread_mutex_lock(&global_lock);
*resp = tcp_server_connections();
pthread_mutex_unlock(&global_lock);
return 0;
}
void api_status_init ( void )
{
extern const idclass_t service_class;
static api_hook_t ah[] = {
{ "subscription/list", ACCESS_ANONYMOUS, api_subscribtion_list, NULL },
{ "status/connections", ACCESS_ADMIN, api_status_connections, NULL },
{ "status/subscriptions", ACCESS_ADMIN, api_status_subscriptions, NULL },
{ "status/inputs", ACCESS_ADMIN, api_status_inputs, NULL },
{ NULL },
};

View file

@ -30,6 +30,7 @@
#include "plumbing/tsfix.h"
#include "imagecache.h"
#include "descrambler.h"
#include "notify.h"
#if ENABLE_TIMESHIFT
#include "timeshift.h"
#endif
@ -1873,6 +1874,7 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m)
htsp->htsp_logname, username);
tvh_str_update(&htsp->htsp_username, username);
htsp_update_logname(htsp);
notify_reload("connections");
}
if(htsmsg_get_bin(m, "digest", &digest, &digestlen))

View file

@ -33,6 +33,7 @@
#include "tcp.h"
#include "http.h"
#include "access.h"
#include "notify.h"
static void *http_server;
@ -497,8 +498,9 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)
n = base64_decode(authbuf, argv[1], sizeof(authbuf) - 1);
authbuf[n] = 0;
if((n = http_tokenize((char *)authbuf, argv, 2, ':')) == 2) {
hc->hc_username = strdup(argv[0]);
hc->hc_password = strdup(argv[1]);
hc->hc_username = strdup(argv[0]);
hc->hc_password = strdup(argv[1]);
// No way to actually track this
}
}
}

View file

@ -397,8 +397,6 @@ typedef struct tcp_server_launch {
static LIST_HEAD(, tcp_server_launch) tcp_server_launches = { 0 };
static gtimer_t tcp_server_status_timer;
/**
*
*/
@ -438,6 +436,7 @@ tcp_server_start(void *aux)
time(&tsl->started);
pthread_mutex_lock(&global_lock);
LIST_INSERT_HEAD(&tcp_server_launches, tsl, link);
notify_reload("connections");
pthread_mutex_unlock(&global_lock);
tsl->ops.start(tsl->fd, &tsl->opaque, &tsl->peer, &tsl->self);
@ -445,6 +444,7 @@ tcp_server_start(void *aux)
if (tsl->ops.stop) tsl->ops.stop(tsl->opaque);
pthread_mutex_lock(&global_lock);
LIST_REMOVE(tsl, link);
notify_reload("connections");
pthread_mutex_unlock(&global_lock);
free(tsl);
@ -600,20 +600,19 @@ tcp_server_create
/*
* Connections status
*/
static void
tcp_server_status_callback ( void *opaque )
htsmsg_t *
tcp_server_connections ( void )
{
tcp_server_launch_t *tsl;
lock_assert(&global_lock);
htsmsg_t *l, *e, *m;
char buf[1024];
int c = 0;
/* RE-arm */
gtimer_arm(&tcp_server_status_timer, tcp_server_status_callback, NULL, 1);
/* Build list */
l = htsmsg_create_list();
LIST_FOREACH(tsl, &tcp_server_launches, link) {
c++;
e = htsmsg_create_map();
tcp_get_ip_str((struct sockaddr*)&tsl->peer, buf, sizeof(buf));
htsmsg_add_str(e, "peer", buf);
@ -625,7 +624,8 @@ tcp_server_status_callback ( void *opaque )
/* Output */
m = htsmsg_create_map();
htsmsg_add_msg(m, "entries", l);
notify_by_msg("tcp_connections", m);
htsmsg_add_u32(m, "totalCount", c);
return m;
}
/**
@ -641,9 +641,4 @@ tcp_server_init(int opt_ipv6)
tcp_server_poll = tvhpoll_create(10);
tvhthread_create(&tid, NULL, tcp_server_loop, NULL, 1);
/* Status timer */
gtimer_arm(&tcp_server_status_timer, tcp_server_status_callback, NULL, 1);
}

View file

@ -59,4 +59,6 @@ int tcp_read_timeout(int fd, void *buf, size_t len, int timeout);
char *tcp_get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen);
htsmsg_t *tcp_server_connections ( void );
#endif /* TCP_H_ */

View file

@ -44,7 +44,6 @@
#include "epggrab/private.h"
#include "config2.h"
#include "lang_codes.h"
#include "subscriptions.h"
#include "imagecache.h"
#include "timeshift.h"
#include "tvhtime.h"
@ -1332,40 +1331,6 @@ extjs_dvrlist_failed(http_connection_t *hc, const char *remain, void *opaque)
return extjs_dvrlist(hc, remain, opaque, is_dvr_entry_failed, dvr_sort_start_descending);
}
/**
*
*/
static int
extjs_subscriptions(http_connection_t *hc, const char *remain, void *opaque)
{
htsbuf_queue_t *hq = &hc->hc_reply;
htsmsg_t *out, *array;
th_subscription_t *s;
pthread_mutex_lock(&global_lock);
if(http_access_verify(hc, ACCESS_ADMIN)) {
pthread_mutex_unlock(&global_lock);
return HTTP_STATUS_UNAUTHORIZED;
}
out = htsmsg_create_map();
array = htsmsg_create_list();
LIST_FOREACH(s, &subscriptions, ths_global_link)
htsmsg_add_msg(array, NULL, subscription_create_msg(s));
pthread_mutex_unlock(&global_lock);
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;
}
/**
*
*/
@ -1795,7 +1760,6 @@ extjs_start(void)
http_path_add("/dvrlist_finished", NULL, extjs_dvrlist_finished, ACCESS_WEB_INTERFACE);
http_path_add("/dvrlist_failed", NULL, extjs_dvrlist_failed, ACCESS_WEB_INTERFACE);
http_path_add("/dvr_containers", NULL, extjs_dvr_containers, ACCESS_WEB_INTERFACE);
http_path_add("/subscriptions", NULL, extjs_subscriptions, ACCESS_WEB_INTERFACE);
http_path_add("/ecglist", NULL, extjs_ecglist, ACCESS_WEB_INTERFACE);
http_path_add("/config", NULL, extjs_config, ACCESS_WEB_INTERFACE);
http_path_add("/languages", NULL, extjs_languages, ACCESS_WEB_INTERFACE);

View file

@ -31,7 +31,7 @@ tvheadend.status_subs = function() {
type : 'date',
dateFormat : 'U' /* unix time */
} ],
url : 'subscriptions',
url : 'api/status/subscriptions',
autoLoad : true,
id : 'id'
});
@ -131,7 +131,7 @@ tvheadend.status_subs = function() {
loadMask : true,
stripeRows : true,
disableSelection : true,
title : 'Active subscriptions',
title : 'Subscriptions',
iconCls : 'eye',
store : tvheadend.subsStore,
cm : subsCm,
@ -176,7 +176,7 @@ tvheadend.status_streams = function() {
name : 'bps'
},
],
url : 'api/input/status',
url : 'api/status/inputs',
autoLoad : true,
id : 'uuid'
});
@ -272,16 +272,93 @@ tvheadend.status_streams = function() {
return panel;
}
tvheadend.status = function() {
/**
*
*/
tvheadend.status_conns = function() {
var panel = new Ext.Panel({
border: false,
layout : 'vbox',
title : 'Status',
var store = new Ext.data.JsonStore({
root : 'entries',
totalProperty : 'totalCount',
fields : [ {
name : 'id'
}, {
name : 'type'
}, {
name : 'peer'
}, {
name : 'user'
}, {
name : 'started',
type : 'date',
dateFormat : 'U' /* unix time */
} ],
url : 'api/status/connections',
autoLoad : true,
id : 'id'
});
tvheadend.comet.on('connections', function(m) {
if (m.reload != null) store.reload();
});
function renderDate(value) {
var dt = new Date(value);
return dt.format('Y-m-d H:i:s');
}
var cm = new Ext.grid.ColumnModel([{
width : 50,
id : 'type',
header : "Type",
dataIndex : 'type'
}, {
width : 50,
id : 'peer',
header : "IP Address",
dataIndex : 'peer'
}, {
width : 50,
id : 'user',
header : "Username",
dataIndex : 'user'
}, {
width : 50,
id : 'started',
header : "Started",
dataIndex : 'started',
renderer : renderDate
} ]);
var panel = new Ext.grid.GridPanel({
border: false,
loadMask : true,
stripeRows : true,
disableSelection : true,
title : 'Connections',
iconCls : 'eye',
items : [ new tvheadend.status_subs, new tvheadend.status_streams ]
});
store : store,
cm : cm,
flex: 1,
viewConfig : {
forceFit : true
}
});
return panel;
}
tvheadend.status = function() {
var panel = new Ext.TabPanel({
title : 'Status',
autoScroll : true,
activeTab : 0,
iconCls : 'eye',
items : [
new tvheadend.status_subs,
new tvheadend.status_streams,
new tvheadend.status_conns
]
});
return panel;
}