fix disk usage in the presence of hard links

git-svn-id: file:///root/webif/svn/pkg/webif/trunk@2501 2a923420-c742-0410-a762-8d5b09965624
This commit is contained in:
hummypkg 2015-10-16 21:24:25 +00:00
parent 2b6e29b1c2
commit 96eea155da
5 changed files with 9 additions and 456 deletions

View File

@ -1,7 +1,7 @@
Package: webif
Priority: optional
Section: web
Version: 1.2.5-2
Version: 1.2.5-3
Architecture: mipsel
Maintainer: af123@hummypkg.org.uk
Depends: webif-channelicons(>=1.1.18),lighttpd(>=1.4.35-2),jim(>=0.76),jim-oo,jim-sqlite3(>=0.76),jim-cgi(>=0.7),jim-binary(>=0.76),service-control(>=2.1),busybox(>=1.20.2-1),lsof(>=4.87),epg(>=1.2.0),hmt(>=2.0.7),ssmtp,anacron,trm(>=1.1),openssl-command,nicesplice,id3v2,file,rsvsync(>=1.0.2),webif-charts(>=1.2-1),stripts(>=1.2.5-3),smartmontools,tmenu(>=1.08),ffmpeg,id3v2,multienv(>=1.6),tcpping(>=1.1),e2fsprogs,wireless-tools(>=29-1),dbupdate,recmon(>=2.0.7)

View File

@ -5,16 +5,18 @@ source /mod/webif/lib/setup
httpheader "application/json"
set dir [cgi_get dir]
set dir [cgi_get dir "/media/My Video"]
set dlen [string length "$dir/"]
#9.4G /media/My Video/Archive
#1.4G /media/My Video/CSI_ Crime Scene Investigation
puts "{"
foreach line [split [exec /mod/bin/busybox/du -h -d 1 "$dir/"] "\n"] {
foreach line [split [exec /mod/bin/busybox/du -h -l -d 1 "$dir/"] "\n"] {
lassign [split $line "\t"] size node
set node [string range $node $dlen end]
puts "\"$node\" : \"$size\","
if {[string length $node]} {
puts "\"$node\": \"$size\","
}
}
# Handle symbolic links.
@ -35,6 +37,8 @@ foreach file [readdir $dir] {
}
}
puts "\"dummy\" : \"\""
lassign [split [exec /mod/bin/busybox/du -hs "$dir/"]] total
puts "\"\": \"$total\""
puts "}"

View File

@ -1,15 +0,0 @@
.tooltip
{
display: none;
background-color: #ffa;
border: 1px solid #cc9;
padding: 10px;
font-size: 13px;
width: 310px;
font-weight: bold;
-moz-box-shadow: 2px 2px 11px #666;
-webkit-box-shadow: 2px 2px 11px #666;
z-index: 1000;
}

View File

@ -1,358 +0,0 @@
/**
* @license
* jQuery Tools @VERSION Tooltip - UI essentials
*
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
*
* http://flowplayer.org/tools/tooltip/
*
* Since: November 2008
* Date: @DATE
*/
(function($) {
// static constructs
$.tools = $.tools || {version: '@VERSION'};
$.tools.tooltip = {
conf: {
// default effect variables
effect: 'toggle',
fadeOutSpeed: "fast",
predelay: 0,
delay: 30,
opacity: 1,
tip: 0,
fadeIE: false, // enables fade effect in IE
// 'top', 'bottom', 'right', 'left', 'center'
position: ['top', 'center'],
offset: [0, 0],
relative: false,
cancelDefault: true,
// type to event mapping
events: {
def: "mouseenter,mouseleave",
input: "focus,blur",
widget: "focus mouseenter,blur mouseleave",
tooltip: "mouseenter,mouseleave"
},
// 1.2
layout: '<div/>',
tipClass: 'tooltip'
},
addEffect: function(name, loadFn, hideFn) {
effects[name] = [loadFn, hideFn];
}
};
var effects = {
toggle: [
function(done) {
var conf = this.getConf(), tip = this.getTip(), o = conf.opacity;
if (o < 1) { tip.css({opacity: o}); }
tip.show();
done.call();
},
function(done) {
this.getTip().hide();
done.call();
}
],
fade: [
function(done) {
var conf = this.getConf();
if (!$.browser.msie || conf.fadeIE) {
this.getTip().fadeTo(conf.fadeInSpeed, conf.opacity, done);
}
else {
this.getTip().show();
done();
}
},
function(done) {
var conf = this.getConf();
if (!$.browser.msie || conf.fadeIE) {
this.getTip().fadeOut(conf.fadeOutSpeed, done);
}
else {
this.getTip().hide();
done();
}
}
]
};
/* calculate tip position relative to the trigger */
function getPosition(trigger, tip, conf) {
// get origin top/left position
var top = conf.relative ? trigger.position().top : trigger.offset().top,
left = conf.relative ? trigger.position().left : trigger.offset().left,
pos = conf.position[0];
top -= tip.outerHeight() - conf.offset[0];
left += trigger.outerWidth() + conf.offset[1];
// iPad position fix
if (/iPad/i.test(navigator.userAgent)) {
top -= $(window).scrollTop();
}
// adjust Y
var height = tip.outerHeight() + trigger.outerHeight();
if (pos == 'center') { top += height / 2; }
if (pos == 'bottom') { top += height; }
// adjust X
pos = conf.position[1];
var width = tip.outerWidth() + trigger.outerWidth();
if (pos == 'center') { left -= width / 2; }
if (pos == 'left') { left -= width; }
return {top: top, left: left};
}
function Tooltip(trigger, conf) {
var self = this,
fire = trigger.add(self),
tip,
timer = 0,
pretimer = 0,
title = trigger.attr("title"),
tipAttr = trigger.attr("data-tooltip"),
effect = effects[conf.effect],
shown,
// get show/hide configuration
isInput = trigger.is(":input"),
isWidget = isInput && trigger.is(":checkbox, :radio, select, :button, :submit"),
type = trigger.attr("type"),
evt = conf.events[type] || conf.events[isInput ? (isWidget ? 'widget' : 'input') : 'def'];
// check that configuration is sane
if (!effect) { throw "Nonexistent effect \"" + conf.effect + "\""; }
evt = evt.split(/,\s*/);
if (evt.length != 2) { throw "Tooltip: bad events configuration for " + type; }
// trigger --> show
trigger.on(evt[0], function(e) {
clearTimeout(timer);
if (conf.predelay) {
pretimer = setTimeout(function() { self.show(e); }, conf.predelay);
} else {
self.show(e);
}
// trigger --> hide
}).on(evt[1], function(e) {
clearTimeout(pretimer);
if (conf.delay) {
timer = setTimeout(function() { self.hide(e); }, conf.delay);
} else {
self.hide(e);
}
});
// remove default title
if (title && conf.cancelDefault) {
trigger.removeAttr("title");
trigger.data("title", title);
}
$.extend(self, {
show: function(e) {
// tip not initialized yet
if (!tip) {
// data-tooltip
if (tipAttr) {
tip = $(tipAttr);
// single tip element for all
} else if (conf.tip) {
tip = $(conf.tip).eq(0);
// autogenerated tooltip
} else if (title) {
tip = $(conf.layout).addClass(conf.tipClass).appendTo(document.body)
.hide().append(title);
// manual tooltip
} else {
tip = trigger.next();
if (!tip.length) { tip = trigger.parent().next(); }
}
if (!tip.length) { throw "Cannot find tooltip for " + trigger; }
}
if (self.isShown()) { return self; }
// stop previous animation
tip.stop(true, true);
// get position
var pos = getPosition(trigger, tip, conf);
// restore title for single tooltip element
if (conf.tip) {
tip.html(trigger.data("title"));
}
// onBeforeShow
e = $.Event();
e.type = "onBeforeShow";
fire.trigger(e, [pos]);
if (e.isDefaultPrevented()) { return self; }
// onBeforeShow may have altered the configuration
pos = getPosition(trigger, tip, conf);
// set position
tip.css({position:'absolute', top: pos.top, left: pos.left});
shown = true;
// invoke effect
effect[0].call(self, function() {
e.type = "onShow";
shown = 'full';
fire.trigger(e);
});
// tooltip events
var event = conf.events.tooltip.split(/,\s*/);
if (!tip.data("__set")) {
tip.off(event[0]).on(event[0], function() {
clearTimeout(timer);
clearTimeout(pretimer);
});
if (event[1] && !trigger.is("input:not(:checkbox, :radio), textarea")) {
tip.off(event[1]).on(event[1], function(e) {
// being moved to the trigger element
if (e.relatedTarget != trigger[0]) {
trigger.trigger(evt[1].split(" ")[0]);
}
});
}
// bind agein for if same tip element
if (!conf.tip) tip.data("__set", true);
}
return self;
},
hide: function(e) {
if (!tip || !self.isShown()) { return self; }
// onBeforeHide
e = $.Event();
e.type = "onBeforeHide";
fire.trigger(e);
if (e.isDefaultPrevented()) { return; }
shown = false;
effects[conf.effect][1].call(self, function() {
e.type = "onHide";
fire.trigger(e);
});
return self;
},
isShown: function(fully) {
return fully ? shown == 'full' : shown;
},
getConf: function() {
return conf;
},
getTip: function() {
return tip;
},
getTrigger: function() {
return trigger;
}
});
// callbacks
$.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","), function(i, name) {
// configuration
if ($.isFunction(conf[name])) {
$(self).on(name, conf[name]);
}
// API
self[name] = function(fn) {
if (fn) { $(self).on(name, fn); }
return self;
};
});
}
// jQuery plugin implementation
$.fn.tooltip = function(conf) {
// return existing instance
var api = this.data("tooltip");
if (api) { return api; }
conf = $.extend(true, {}, $.tools.tooltip.conf, conf);
// position can also be given as string
if (typeof conf.position == 'string') {
conf.position = conf.position.split(/,?\s/);
}
// install tooltip for each entry in jQuery object
this.each(function() {
api = new Tooltip($(this), conf);
$(this).data("tooltip", api);
});
return conf.api ? api: this;
};
}) (jQuery);

View File

@ -1,78 +0,0 @@
/**
* @license
* jQuery Tools @VERSION / Tooltip Slide Effect
*
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
*
* http://flowplayer.org/tools/tooltip/slide.html
*
* Since: September 2009
* Date: @DATE
*/
(function($) {
// version number
var t = $.tools.tooltip;
// extend global configuragion with effect specific defaults
$.extend(t.conf, {
direction: 'up', // down, left, right
bounce: false,
slideOffset: 10,
slideInSpeed: 200,
slideOutSpeed: 200,
slideFade: !$.browser.msie
});
// directions for slide effect
var dirs = {
up: ['-', 'top'],
down: ['+', 'top'],
left: ['-', 'left'],
right: ['+', 'left']
};
/* default effect: "slide" */
t.addEffect("slide",
// show effect
function(done) {
// variables
var conf = this.getConf(),
tip = this.getTip(),
params = conf.slideFade ? {opacity: conf.opacity} : {},
dir = dirs[conf.direction] || dirs.up;
// direction
params[dir[1]] = dir[0] +'='+ conf.slideOffset;
// perform animation
if (conf.slideFade) { tip.css({opacity:0}); }
tip.show().animate(params, conf.slideInSpeed, done);
},
// hide effect
function(done) {
// variables
var conf = this.getConf(),
offset = conf.slideOffset,
params = conf.slideFade ? {opacity: 0} : {},
dir = dirs[conf.direction] || dirs.up;
// direction
var sign = "" + dir[0];
if (conf.bounce) { sign = sign == '+' ? '-' : '+'; }
params[dir[1]] = sign +'='+ offset;
// perform animation
this.getTip().animate(params, conf.slideOutSpeed, function() {
$(this).hide();
done.call();
});
}
);
})(jQuery);