Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
WEBUI JS: Show the disk space (free/total)
  • Loading branch information
perexg committed Jun 24, 2015
1 parent cd30716 commit 584e10f
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 18 deletions.
4 changes: 4 additions & 0 deletions src/dvr/dvr.h
Expand Up @@ -498,6 +498,10 @@ htsmsg_t *dvr_entry_class_duration_list(void *o, const char *not_set, int max, i

int dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly);

void dvr_disk_space_init(void);
void dvr_disk_space_done(void);
int dvr_get_disk_space(int64_t *bfree, int64_t *btotal);

/**
*
*/
Expand Down
2 changes: 2 additions & 0 deletions src/dvr/dvr_config.c
Expand Up @@ -1046,6 +1046,7 @@ dvr_init(void)
dvr_entry_init();
dvr_autorec_update();
dvr_timerec_update();
dvr_disk_space_init();
}

/**
Expand All @@ -1066,4 +1067,5 @@ dvr_done(void)
pthread_mutex_unlock(&global_lock);
dvr_autorec_done();
dvr_timerec_done();
dvr_disk_space_done();
}
106 changes: 106 additions & 0 deletions src/dvr/dvr_rec.c
Expand Up @@ -24,6 +24,14 @@
#include <sys/stat.h>
#include <libgen.h> /* basename */

#if ENABLE_ANDROID
#include <sys/vfs.h>
#define statvfs statfs
#define fstatvfs fstatfs
#else
#include <sys/statvfs.h>
#endif

#include "htsstr.h"

#include "tvheadend.h"
Expand All @@ -37,6 +45,7 @@
#include "htsp_server.h"
#include "atomic.h"
#include "intlconv.h"
#include "notify.h"

#include "muxer.h"

Expand Down Expand Up @@ -1100,3 +1109,100 @@ dvr_thread_epilog(dvr_entry_t *de)
if(cfg && cfg->dvr_postproc)
dvr_spawn_postproc(de,cfg->dvr_postproc);
}

/**
*
*/
static int64_t dvr_bfree;
static int64_t dvr_btotal;
static pthread_mutex_t dvr_disk_space_mutex;
static gtimer_t dvr_disk_space_timer;
static tasklet_t dvr_disk_space_tasklet;

/**
*
*/
static void
dvr_get_disk_space_update(const char *path)
{
struct statvfs diskdata;

if(statvfs(path, &diskdata) == -1)
return;

dvr_bfree = diskdata.f_bsize * (int64_t)diskdata.f_bavail;
dvr_btotal = diskdata.f_bsize * (int64_t)diskdata.f_blocks;
}

/**
*
*/
static void
dvr_get_disk_space_tcb(void *s, int dearmed)
{
dvr_config_t *cfg;
htsmsg_t *m;
char *path;

pthread_mutex_lock(&global_lock);
cfg = dvr_config_find_by_name_default(NULL);
path = tvh_strdupa(cfg->dvr_storage);
pthread_mutex_unlock(&global_lock);

m = htsmsg_create_map();
pthread_mutex_lock(&dvr_disk_space_mutex);
dvr_get_disk_space_update(path);
htsmsg_add_s64(m, "freediskspace", dvr_bfree);
htsmsg_add_s64(m, "totaldiskspace", dvr_btotal);
pthread_mutex_unlock(&dvr_disk_space_mutex);

notify_by_msg("diskspaceUpdate", m);
}

static void
dvr_get_disk_space_cb(void *aux)
{
tasklet_arm(&dvr_disk_space_tasklet, dvr_get_disk_space_tcb, NULL);
gtimer_arm(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, 60);
}

/**
*
*/
void
dvr_disk_space_init(void)
{
dvr_config_t *cfg = dvr_config_find_by_name_default(NULL);
pthread_mutex_init(&dvr_disk_space_mutex, NULL);
dvr_get_disk_space_update(cfg->dvr_storage);
gtimer_arm(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, 60);
}

/**
*
*/
void
dvr_disk_space_done(void)
{
tasklet_disarm(&dvr_disk_space_tasklet);
gtimer_disarm(&dvr_disk_space_timer);
}

/**
*
*/
int
dvr_get_disk_space(int64_t *bfree, int64_t *btotal)
{
int res = 0;

pthread_mutex_lock(&dvr_disk_space_mutex);
if (dvr_bfree || dvr_btotal) {
*bfree = dvr_bfree;
*btotal = dvr_btotal;
} else {
res = -EINVAL;
}
pthread_mutex_unlock(&dvr_disk_space_mutex);
return res;
}
22 changes: 6 additions & 16 deletions src/htsp_server.c
Expand Up @@ -51,19 +51,12 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#if ENABLE_ANDROID
#include <sys/vfs.h>
#define statvfs statfs
#define fstatvfs fstatfs
#else
#include <sys/statvfs.h>
#endif
#include "settings.h"
#include <sys/stat.h>
#include <sys/time.h>
#include <limits.h>
#include "settings.h"

/* **************************************************************************
* Datatypes and variables
Expand Down Expand Up @@ -1069,17 +1062,14 @@ static htsmsg_t *
htsp_method_getDiskSpace(htsp_connection_t *htsp, htsmsg_t *in)
{
htsmsg_t *out;
struct statvfs diskdata;
dvr_config_t *cfg = dvr_config_find_by_name_default(NULL);
int64_t bfree, btotal;

if(statvfs(cfg->dvr_storage,&diskdata) == -1)
if (dvr_get_disk_space(&bfree, &btotal))
return htsp_error("Unable to stat path");

out = htsmsg_create_map();
htsmsg_add_s64(out, "freediskspace",
diskdata.f_bsize * (int64_t)diskdata.f_bavail);
htsmsg_add_s64(out, "totaldiskspace",
diskdata.f_bsize * (int64_t)diskdata.f_blocks);
htsmsg_add_s64(out, "freediskspace", bfree);
htsmsg_add_s64(out, "totaldiskspace", btotal);
return out;
}

Expand Down
10 changes: 9 additions & 1 deletion src/webui/comet.c
Expand Up @@ -31,6 +31,7 @@

#include "tvheadend.h"
#include "http.h"
#include "dvr/dvr.h"
#include "webui/webui.h"
#include "access.h"
#include "tcp.h"
Expand Down Expand Up @@ -142,16 +143,23 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb)

htsmsg_t *m = htsmsg_create_map();
const char *username = hc->hc_access ? (hc->hc_access->aa_username ?: "") : "";
int64_t bfree, btotal;
int dvr = !http_access_verify(hc, ACCESS_RECORDER);

htsmsg_add_str(m, "notificationClass", "accessUpdate");

if (!access_noacl)
htsmsg_add_str(m, "username", username);
if (hc->hc_peer_ipstr)
htsmsg_add_str(m, "address", hc->hc_peer_ipstr);
htsmsg_add_u32(m, "dvr", !http_access_verify(hc, ACCESS_RECORDER));
htsmsg_add_u32(m, "dvr", dvr);
htsmsg_add_u32(m, "admin", !http_access_verify(hc, ACCESS_ADMIN));

if (dvr && !dvr_get_disk_space(&bfree, &btotal)) {
htsmsg_add_s64(m, "freediskspace", bfree);
htsmsg_add_s64(m, "totaldiskspace", btotal);
}

if(cmb->cmb_messages == NULL)
cmb->cmb_messages = htsmsg_create_list();
htsmsg_add_msg(cmb->cmb_messages, NULL, m);
Expand Down
6 changes: 6 additions & 0 deletions src/webui/static/app/ext.css
Expand Up @@ -42,6 +42,12 @@
float: right;
}

.x-tab-strip span.x-tab-diskspace {
vertical-align: middle;
white-space: nowrap;
padding:4px 0px;
}

.x-tree-col {
float: left;
overflow: hidden;
Expand Down
42 changes: 41 additions & 1 deletion src/webui/static/app/tvheadend.js
Expand Up @@ -334,6 +334,11 @@ tvheadend.VideoPlayer = function(url) {
win.show();
};

function diskspaceUpdate(o) {
if ('freediskspace' in o && 'totaldiskspace' in o)
tvheadend.rootTabPanel.setDiskSpace(o.freediskspace, o.totaldiskspace);
}

/**
* This function creates top level tabs based on access so users without
* access to subsystems won't see them.
Expand All @@ -349,6 +354,8 @@ function accessUpdate(o) {
tvheadend.rootTabPanel.setLogin(o.username);
if ('address' in o)
tvheadend.rootTabPanel.setAddress(o.address);
if ('freediskspace' in o && 'totaldiskspace' in o)
tvheadend.rootTabPanel.setDiskSpace(o.freediskspace, o.totaldiskspace);

if (tvheadend.autorecButton)
tvheadend.autorecButton.setDisabled(o.dvr != true);
Expand Down Expand Up @@ -532,8 +539,23 @@ tvheadend.RootTabPanel = Ext.extend(Ext.TabPanel, {
item.tabEl.select('a').on('click', this.onLoginCmdClicked, this, {preventDefault: true});
this.loginCmdItem = item;

if (!this.diskSpaceTpl) {
var tt = new Ext.Template(
'<li class="x-tab-login" id="{id}">',
'<span class="x-tab-diskspace"></span></li>'
);
tt.disableFormats = true;
tt.compile();
tvheadend.RootTabPanel.prototype.diskSpaceTpl = tt;
}
var item = new Ext.Component();
var p = this.getTemplateArgs(item);
var el = this.diskSpaceTpl.insertBefore(before, p);
item.tabEl = Ext.get(el);
this.diskSpaceItem = item;

this.on('beforetabchange', function(tp, p) {
if (p == this.loginItem || p == this.loginCmdItem)
if (p == this.loginItem || p == this.loginCmdItem || p == this.diskSpaceItem)
return false;
});
},
Expand All @@ -543,6 +565,8 @@ tvheadend.RootTabPanel = Ext.extend(Ext.TabPanel, {
return this.loginItem;
if (comp === this.loginCmdItem.id || comp == this.loginCmdItem)
return this.loginCmdItem;
if (comp === this.diskSpaceItem.id || comp == this.diskSpaceItem)
return this.diskSpaceItem;
return tvheadend.RootTabPanel.superclass.getComponent.call(this, comp);
},

Expand All @@ -566,6 +590,20 @@ tvheadend.RootTabPanel = Ext.extend(Ext.TabPanel, {
Ext.get(this.loginItem.tabEl).child('span.x-tab-strip-login', true).qtip = addr;
},

setDiskSpace: function(bfree, btotal) {
human = function(val) {
if (val > 1000000000)
val = parseInt(val / 1000000000) + _('GB');
if (val > 1000000)
val = parseInt(val / 1000000) + _('MB');
if (val > 1000)
val = parseInt(val / 1000) + _('KB');
return val;
};
text = _('Disk space:') + '&nbsp;<b>' + human(bfree) + '/' + human(btotal) + '</b>';
Ext.get(this.diskSpaceItem.tabEl).child('span.x-tab-diskspace', true).innerHTML = text;
},

onLoginCmdClicked: function(e) {
window.location.href = this.login ? 'logout' : 'login';
}
Expand Down Expand Up @@ -630,6 +668,8 @@ tvheadend.app = function() {

tvheadend.comet.on('accessUpdate', accessUpdate);

tvheadend.comet.on('diskspaceUpdate', diskspaceUpdate);

tvheadend.comet.on('setServerIpPort', setServerIpPort);

tvheadend.comet.on('logmessage', function(m) {
Expand Down

2 comments on commit 584e10f

@mario-tux
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personal opinion: such big, always present, string on the top of the screen is quiet awful. I like the previous clean interface used before. Note that I've disabled any authentication feature, so no login/logout widgets on top for me. IMHO.

@ProfYaffle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this 'in the wild' as I haven't built a recent version - I've only seen @PiterEL's screenshot on another post.

I was thinking previously about how you could add a disc space display, and wondered if it belongs in the About... tab instead. That would allow a table, more like the output of df -h - that would show all mounted filsystems, use, free space, etc.; if you wanted to be really adventurous, you could have architecture/CPU use or similar, although that's all decoration and not really necessary. Knowing where your free disc space is, though, is more useful.

Similar "" to above.

Please sign in to comment.