From 24ca5856dcc2995af4662d0c4eedb7f8452da53a Mon Sep 17 00:00:00 2001 From: Luca CPZ Date: Fri, 16 Feb 2018 17:21:09 +0100 Subject: [PATCH] fs: pure Gio implementation; #272 --- scripts/dfs | 397 -------------------------------------------------- widget/fs.lua | 133 +++++++++-------- wiki | 2 +- 3 files changed, 71 insertions(+), 461 deletions(-) delete mode 100755 scripts/dfs diff --git a/scripts/dfs b/scripts/dfs deleted file mode 100755 index 9e02a87..0000000 --- a/scripts/dfs +++ /dev/null @@ -1,397 +0,0 @@ -#!/usr/bin/env bash -# -# Adapted from Eridan's "fs" (cleanup, enhancements and switch to bash/Linux) -# JM, 10/12/2004 -# -# Integrated into Lain in september 2013 -# https://github.com/lcpz/lain - -# Requires gawk - -# ------------------------------------------------------------------------- -# Decoding options -# ------------------------------------------------------------------------- -USAGE="Usage: $0 [-h(elp)] | [-n(arrow mode)] | [-w(eb output) | --type= | --exclude-type=]" - -NARROW_MODE=0 -WEB_OUTPUT=0 -DF_OPTIONS="" - -while [ $# -gt 0 ]; do -case "$1" in -"-h" ) -echo $USAGE -exit -;; -"-d" ) -DEBUG=1 -;; -"-n" ) -NARROW_MODE=1 -;; -"-w" ) -WEB_OUTPUT=1 -;; ---type=*) -DF_OPTIONS+=" $1" -;; ---exclude-type=*) -DF_OPTIONS+=" $1" -;; -* ) -echo $USAGE -exit -;; -esac -shift -done - -# ------------------------------------------------------------------------- -# Preparations -# ------------------------------------------------------------------------- -SYSTEM=`uname -s` -PATTERN="/" - -case "$SYSTEM" in -"Linux" ) -DF_COMMAND="/usr/bin/env df -k" -SORT_COMMAND="/usr/bin/env sort -k6" -AWK_COMMAND="/usr/bin/env awk" -;; -* ) -DF_COMMAND="/bin/df -k" -SORT_COMMAND="/usr/bin/sort -k6" -AWK_COMMAND="/usr/bin/env gawk" -;; -esac - -# Add additional df options -DF_COMMAND+=$DF_OPTIONS - -# ------------------------------------------------------------------------- -# Grabbing "df" result -# ------------------------------------------------------------------------- -DF_RESULT=`$DF_COMMAND` -if [ ! -z $DEBUG ]; then -echo "--> DF_RESULT:" -echo "$DF_RESULT" -echo "" -fi - -# ------------------------------------------------------------------------- -# Preprocessing "df" result, to join split logical lines -# ------------------------------------------------------------------------- -PREPROCESSING_RESULT=` \ - echo "$DF_RESULT" | $AWK_COMMAND -v PATTERN=$PATTERN \ - ' - NF == 1 { - printf ("%s", $0) - } - -NF == 5 { - printf ("%s\n", $0) -} - -NF > 6 { -} - -NF == 6 { - printf ("%s\n", $0) -}' -` -if [ ! -z $DEBUG ]; then -echo "--> PREPROCESSING_RESULT:" -echo "$PREPROCESSING_RESULT" -echo "" -fi - -SORTED_FILE_SYSTEMS_INFO=`echo "$PREPROCESSING_RESULT" | $SORT_COMMAND` - -if [ ! -z $DEBUG ]; then -echo "--> SORTED_FILE_SYSTEMS_INFO:" -echo "$SORTED_FILE_SYSTEMS_INFO" -echo "" -fi - -# ------------------------------------------------------------------------- -# Computing mount point max length -# ------------------------------------------------------------------------- -MOUNT_POINT_MAX_LENGTH=` \ - echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v PATTERN=$PATTERN \ - ' - BEGIN { - mount_point_length_max = 15; - } - -END { - printf ("%d", mount_point_length_max); -} - -$0 ~ PATTERN { -# printf ("$6 = %s\n", $6); - - mount_point = $6; -# printf ("mount_point = %s\n", mount_point); - - mount_point_length = length (mount_point); -# printf ("mount_point_length = %d\n", mount_point_length); - - if (mount_point_length > mount_point_length_max) - mount_point_length_max = mount_point_length; -}' -` -if [ ! -z $DEBUG ]; then -echo "MOUNT_POINT_MAX_LENGTH: $MOUNT_POINT_MAX_LENGTH" -fi - -# ------------------------------------------------------------------------- -# Computing mount point data max size -# ------------------------------------------------------------------------- -MOUNT_POINT_MAX_SIZE=` \ - echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v PATTERN=$PATTERN \ - ' - BEGIN { - mount_point_size_max = 0; - } - -END { - printf ("%d", mount_point_size_max); -} - -$0 ~ PATTERN { -# df -k shows k_bytes! -# printf ("$2 = %s\n", $2); - - mount_point_size = $2 * 1024; -# printf ("mount_point_size = %d\n", mount_point_size); - - if (mount_point_size > mount_point_size_max) - mount_point_size_max = mount_point_size; -}' -` -if [ ! -z $DEBUG ]; then -echo "MOUNT_POINT_MAX_SIZE: $MOUNT_POINT_MAX_SIZE" -fi - -# ------------------------------------------------------------------------- -# Let's go! -# ------------------------------------------------------------------------- -echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v DEBUG=$DEBUG -v PATTERN=$PATTERN -v NARROW_MODE=$NARROW_MODE -v LEFT_COLUMN=$MOUNT_POINT_MAX_LENGTH -v MAX_SIZE=$MOUNT_POINT_MAX_SIZE -v SCALE=$SCALE -v WEB_OUTPUT=$WEB_OUTPUT \ - ' -# {printf ("$0 = %s\n", $0);} -# {printf ("$1 = %s\n", $1);} -# {printf ("PATTERN = %s\n", PATTERN);} -# {printf ("LEFT_COLUMN = %s\n", LEFT_COLUMN);} - - BEGIN { - k_bytes = 1024.0; - m_bytes = 1024.0 * k_bytes; - g_bytes = 1024.0 * m_bytes; - t_bytes = 1024.0 * g_bytes; - - if (WEB_OUTPUT) - { - all_stars = "**************************************************"; - current_date = strftime ("%d-%m-%Y @ %H:%M:%S", localtime (systime ())); - free_threshold = 10; # % - - printf ("\n"); - - printf ( \ - "\n" \ - "

%s -- STATUS OF ALCOR FILE SYSTEMS


\n", - current_date ) - - printf ("\n"); - - printf ( \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" ); - } - else - { - narrow_margin = " "; -# printf ("%-*s", LEFT_COLUMN + 2, "Mount point"); - if (NARROW_MODE) - printf ("\n%s", narrow_margin); - else - printf ("%-*s", LEFT_COLUMN + 2, ""); - print " Used Free Total "; - if (! NARROW_MODE) - print " "; - } - } - -END { - if (WEB_OUTPUT) - { - printf ("
Mount point%% Usato (*)" \ - " - %% Free (*)%% UsedFreeTotal
\n"); - - printf ("\n"); - } - else - { - if (NARROW_MODE) - printf ("%s", narrow_margin); - else - printf ("%-*s", LEFT_COLUMN + 2, ""); - print "|----|----|----|----|----|----|----|----|----|----|" - if (NARROW_MODE) - printf ("\n%s", narrow_margin); - else - printf ("%-*s", LEFT_COLUMN + 2, ""); - print "0 10 20 30 40 50 60 70 80 90 100"; - print ""; - } -} - -$0 ~ PATTERN { - - if (index ($0, "members") == 0 && index ($0, "Download") == 0 && index ($0, "admin") == 0) - { -# df -k shows k_bytes! - - total_size = $2 * k_bytes; - free_size = $4 * k_bytes; - percentage_occupied = substr($5, 0, 3); - mount_point = $6; - - percentage_free = int (100 - percentage_occupied); - -# reduction_factor: 2 - stars_number = int (percentage_occupied / 2); - - if (WEB_OUTPUT) - { - posGroup = index (mount_point, "scratch"); - if (posGroup == 0) - posGroup = index (mount_point, "u1"); - if (posGroup == 0) - posGroup = index (mount_point, "u2"); - if (posGroup == 0) - posGroup = index (mount_point, "u4"); - if (posGroup == 0) - posGroup = index (mount_point, "u5"); - - printf ("\n"); - - if (posGroup > 0 || percentage_free < free_threshold) - { - if (percentage_free < free_threshold) - { - class = "titlered"; - if (posGroup == 0) - posGroup = 1; # to display the whole mount_point in this color anyway - } - else if ((index (mount_point, "scratch") != 0) || (index (mount_point, "u1") != 0) || (index (mount_point, "u2") != 0)) - { - class = "titleorange"; - posGroup = 1; # to display the whole mount_point in this color - } - else if ((index (mount_point, "u4") != 0) || (index (mount_point, "u5") != 0)) - { - class = "titlebrown"; - posGroup = 1; # to display the whole mount_point in this color - } - - printf ( \ - "%s%s\n", - substr (mount_point, 1, posGroup - 1), - class, - substr (mount_point, posGroup) ); - } - else - { - printf ("%s\n", mount_point); - } - - printf ( \ - "%s%s\n", - substr (all_stars, 1, stars_number), substr (all_stars, stars_number + 1, 49) ); - - if (percentage_free < free_threshold) - { - color_beginning = ""; - color_end = "" - } - else - { - color_beginning = ""; - color_end = "" - } - - if (total_size > 1 * t_bytes) - printf ( \ - "%s%3d%%%s%5.1f Tb%5.1f Tb\n", \ - color_beginning, percentage_occupied, color_end, free_size / t_bytes, total_size / t_bytes \ - ); - else if (total_size > 1 * g_bytes) - printf ( \ - "%s%3d%%%s%5.1f Gb%5.1f Gb\n", \ - color_beginning, percentage_occupied, color_end, free_size / g_bytes, total_size / g_bytes \ - ); - else if (total_size > 1 * m_byptes) - printf ( \ - "%s%3d%%%s%5.1f Mb%5.1f Mb\n", \ - color_beginning, percentage_occupied, color_end, free_size / m_bytes, total_size / m_bytes \ - ); - else - printf ( \ - "%s%3d%%%s%5.1f Kb%5.1f Kb\n", \ - color_beginning, percentage_occupied, color_end, free_size / k_bytes, total_size / k_bytes \ - ); - - printf ("\n"); - } - - else - { -# printf ("percentage_occupied = %d\n", percentage_occupied); -# printf ("percentage_free = %d\n", percentage_free); - - printf ("%-*s", LEFT_COLUMN + 2, mount_point); - if (NARROW_MODE) - printf ("\n%s", narrow_margin); - -# printf ("stars_number = %d\n", stars_number); - - printf ("|"); - for (i = 1; i <= stars_number && i <= 49; i++) - { - printf ("%s", "*"); - } - for (i = stars_number + 1; i <= 49; i++) - { - printf ("%s", "-"); - } - - - if (total_size > 1 * t_bytes) - printf ( \ - "| %3d%% %6.1f %6.1f Tb\n", \ - percentage_occupied, free_size / t_bytes, total_size / t_bytes \ - ); - else if (total_size > 1 * g_bytes) - printf ( \ - "| %3d%% %6.1f %6.1f Gb\n", \ - percentage_occupied, free_size / g_bytes, total_size / g_bytes \ - ); - else if (total_size > 1 * m_byptes) - printf ( \ - "| %3d%% %6.1f %6.1f Mb\n", \ - percentage_occupied, free_size / m_bytes, total_size / m_bytes \ - ); - else - printf ( \ - "| %3d%% %6.1f %6.1f Kb\n", \ - percentage_occupied, free_size / k_bytes, total_size / k_bytes \ - ); - } - } # if -}' diff --git a/widget/fs.lua b/widget/fs.lua index ca6fb4d..5e18491 100644 --- a/widget/fs.lua +++ b/widget/fs.lua @@ -1,23 +1,38 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2018, Uli Schlacter + * (c) 2018, Otto Modinos * (c) 2013, Luca CPZ --]] -local helpers = require("lain.helpers") -local shell = require("awful.util").shell -local focused = require("awful.screen").focused -local wibox = require("wibox") -local naughty = require("naughty") -local string = string -local tonumber = tonumber +local helpers = require("lain.helpers") +local Gio = require("lgi").Gio +local focused = require("awful.screen").focused +local wibox = require("wibox") +local naughty = require("naughty") +local math = math +local sformat = string.format +local tconcat = table.concat +local tonumber = tonumber +local query_size = Gio.FILE_ATTRIBUTE_FILESYSTEM_SIZE +local query_free = Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE +local query_used = Gio.FILE_ATTRIBUTE_FILESYSTEM_USED +local query = query_size .. "," .. query_free .. "," .. query_used --- File system disk space usage +-- File systems info -- lain.widget.fs local function factory(args) - local fs = { unit = { ["mb"] = 1024, ["gb"] = 1024^2 }, widget = wibox.widget.textbox() } + local fs = { + widget = wibox.widget.textbox(), + units = { + [1] = "Kb", [2] = "Mb", [3] = "Gb", + [4] = "Tb", [5] = "Pb", [6] = "Eb", + [7] = "Zb", [8] = "Yb" + } + } function fs.hide() if not fs.notification then return end @@ -26,29 +41,20 @@ local function factory(args) end function fs.show(seconds, scr) - fs.update() - fs.hide() - - if fs.followtag then - fs.notification_preset.screen = focused() - else - fs.notification_preset.screen = scr or 1 - end - - fs.notification = naughty.notify({ + fs.hide(); fs.update() + fs.notification_preset.screen = fs.followtag and focused() or scr or 1 + fs.notification = naughty.notify { preset = fs.notification_preset, timeout = seconds or 5 - }) + } end - local args = args or {} - local timeout = args.timeout or 600 - local partition = args.partition or "/" - local showpopup = args.showpopup or "on" - local notify = args.notify or "on" - local settings = args.settings or function() end + local args = args or {} + local timeout = args.timeout or 600 + local partition = args.partition + local showpopup = args.showpopup or "on" + local settings = args.settings or function() end - fs.options = args.options fs.followtag = args.followtag or false fs.notification_preset = args.notification_preset @@ -60,54 +66,55 @@ local function factory(args) } end - helpers.set_map(partition, false) - function fs.update() - fs_info, fs_now = {}, {} - helpers.async({ shell, "-c", "/usr/bin/env LC_ALL=C df -k --output=target,size,used,avail,pcent" }, function(f) - for line in string.gmatch(f, "\n[^\n]+") do - local m,s,u,a,p = string.match(line, "(/.-%s).-(%d+).-(%d+).-(%d+).-([%d]+)%%") - m = m:gsub(" ", "") -- clean target from any whitespace + local notifytable = { [1] = sformat("%-10s %-5s %s\t%s\t\n", "fs", "used", "free", "size") } + fs_now = {} - fs_info[m .. " size_mb"] = string.format("%.1f", tonumber(s) / fs.unit["mb"]) - fs_info[m .. " size_gb"] = string.format("%.1f", tonumber(s) / fs.unit["gb"]) - fs_info[m .. " used_mb"] = string.format("%.1f", tonumber(u) / fs.unit["mb"]) - fs_info[m .. " used_gb"] = string.format("%.1f", tonumber(u) / fs.unit["gb"]) - fs_info[m .. " used_p"] = p - fs_info[m .. " avail_mb"] = string.format("%.1f", tonumber(a) / fs.unit["mb"]) - fs_info[m .. " avail_gb"] = string.format("%.1f", tonumber(a) / fs.unit["gb"]) - fs_info[m .. " avail_p"] = string.format("%d", 100 - tonumber(p)) + for _, mount in ipairs(Gio.unix_mounts_get()) do + local path = Gio.unix_mount_get_mount_path(mount) + local root = Gio.File.new_for_path(path) + local info = root:query_filesystem_info(query) + local size = info:get_attribute_uint64(query_size) + local used = info:get_attribute_uint64(query_used) + local free = info:get_attribute_uint64(query_free) + + if size > 0 then + local units = math.floor(math.log(size)/math.log(1024)) + + fs_now[path] = { + units = fs.units[units], + percentage = math.floor(100 * used / size), -- used percentage + size = size / math.pow(1024, math.floor(units)), + used = used / math.pow(1024, math.floor(units)), + free = free / math.pow(1024, math.floor(units)) + } + + -- don't notify unused file systems + if fs_now[path].percentage > 0 then + notifytable[#notifytable+1] = sformat("\n%-10s %-5s %3.2f\t%3.2f\t%s", path, + fs_now[path].percentage .. "%", fs_now[path].free, fs_now[path].size, + fs_now[path].units) + end end + end - fs_now.size_mb = fs_info[partition .. " size_mb"] or "N/A" - fs_now.size_gb = fs_info[partition .. " size_gb"] or "N/A" - fs_now.used = fs_info[partition .. " used_p"] or "N/A" - fs_now.used_mb = fs_info[partition .. " used_mb"] or "N/A" - fs_now.used_gb = fs_info[partition .. " used_gb"] or "N/A" - fs_now.available = fs_info[partition .. " avail_p"] or "N/A" - fs_now.available_mb = fs_info[partition .. " avail_mb"] or "N/A" - fs_now.available_gb = fs_info[partition .. " avail_gb"] or "N/A" + widget = fs.widget + settings() - notification_preset = fs.notification_preset - widget = fs.widget - settings() - - if notify == "on" and tonumber(fs_now.used) and tonumber(fs_now.used) >= 99 and not helpers.get_map(partition) then - naughty.notify({ + if partition and fs_now[partition] and fs_now[partition].used >= 99 then + if not helpers.get_map(partition) then + naughty.notify { preset = naughty.config.presets.critical, title = "Warning", text = partition .. " is full", - }) + } helpers.set_map(partition, true) else helpers.set_map(partition, false) end - end) + end - local notifycmd = (fs.options and string.format("dfs %s", fs.options)) or "dfs" - helpers.async(helpers.scripts_dir .. notifycmd, function(ws) - fs.notification_preset.text = ws:gsub("\n*$", "") - end) + fs.notification_preset.text = tconcat(notifytable) end if showpopup == "on" then @@ -115,7 +122,7 @@ local function factory(args) fs.widget:connect_signal('mouse::leave', function () fs.hide() end) end - helpers.newtimer(partition, timeout, fs.update) + helpers.newtimer(partition or "fs", timeout, fs.update) return fs end diff --git a/wiki b/wiki index 2859d40..e8860c7 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 2859d4049cf9b96ffa8ac2c872428d730b6477c9 +Subproject commit e8860c7593f86584b45ada7d5232f32915ba20a6