From c9802126d9282185bf96e09727ebccb557f73cbc Mon Sep 17 00:00:00 2001 From: JackDandy Date: Tue, 9 Jan 2018 23:47:36 +0000 Subject: [PATCH] Add free space stat (if obtainable) of parent folder(s) to footer. --- CHANGES.md | 1 + gui/slick/interfaces/default/inc_bottom.tmpl | 28 ++++++++++ sickbeard/helpers.py | 59 ++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index faeef1e3..0121bca8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ [develop changelog] * Fix Events shutdown (a manual start-up is required after updating to this fix) +* Add free space stat (if obtainable) of parent folder(s) to footer ### 0.13.10 (2018-01-08 17:20:00 UTC) diff --git a/gui/slick/interfaces/default/inc_bottom.tmpl b/gui/slick/interfaces/default/inc_bottom.tmpl index 01a8a5f4..dffd3328 100644 --- a/gui/slick/interfaces/default/inc_bottom.tmpl +++ b/gui/slick/interfaces/default/inc_bottom.tmpl @@ -3,6 +3,7 @@ #import re #from sickbeard import db, sbdatetime #from sickbeard.common import * +#from sickbeard.helpers import df <% def sg_var(varname, default=False): return getattr(sickbeard, varname, default) %>#slurp# <% def sg_str(varname, default=''): return getattr(sickbeard, varname, default) %>#slurp# ## @@ -61,7 +62,14 @@ try: recent_search_timeleft = str(sickbeard.recentSearchScheduler.timeLeft()).split('.')[0] except AttributeError: recent_search_timeleft = 'soon' +diskfree, min_output = df() +if min_output: + avail = ', '.join(['%s %s' % (drive, free) for (drive, free) in diskfree]) %> + ## $shows_total shows ($shows_active active) | $ep_downloaded<%= @@ -74,6 +82,26 @@ except AttributeError: %> / $ep_total episodes downloaded $ep_percentage | recent search: $recent_search_timeleft | backlog search: $next_backlog_timeleft +#if diskfree + #if min_output +
free space  $avail + #else +
+ + + + #for i, drive in enumerate(diskfree) + + + + + + #end for + +
Free space stats for volume/path
#if not i#free space#end if#$drive[1]$drive[0]
+
+ #end if +#end if diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index c9124fe3..b856ebaf 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -1555,3 +1555,62 @@ def datetime_to_epoch(dt): dt = dt.replace(tzinfo=sb_timezone) utc_naive = dt.replace(tzinfo=None) - dt.utcoffset() return int((utc_naive - datetime.datetime(1970, 1, 1)).total_seconds()) + + +def df(): + """ + Return disk free space at known parent locations + + :return: string path, string value that is formatted size + :rtype: list of tuples + """ + result = [] + min_output = True + if sickbeard.ROOT_DIRS: + targets = [] + for path in sickbeard.ROOT_DIRS.split('|')[1:]: + location_parts = os.path.splitdrive(path) + target = location_parts[0] + if 'win32' == sys.platform: + if not re.match('(?i)[a-z]:(?:\\\\)?$', target): + # simple drive letter not found, fallback to full path + target = path + min_output = False + elif sys.platform.startswith(('linux', 'darwin', 'sunos5')) or 'bsd' in sys.platform: + target = path + min_output = False + if target and target not in targets: + targets += [target] + free = freespace(path) + if None is not free: + result += [(target, sizeof_fmt(free).replace(' ', ''))] + return result, min_output + + +def freespace(path=None): + """ + Return free space available at path location + + :param path: Example paths (Windows) = '\\\\192.168.0.1\\sharename\\existing_path', 'd:\\existing_path' + Untested with mount points under linux + :type path: basestring + :return: Size in bytes + :rtype: long + """ + result = None + + if 'win32' == sys.platform: + try: + import ctypes + if None is not ctypes: + max_val = (2 ** 64) - 1 + storage = ctypes.c_ulonglong(max_val) + ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(path), None, None, ctypes.pointer(storage)) + result = (storage.value, None)[max_val == storage.value] + except(StandardError, Exception): + pass + elif sys.platform.startswith(('linux', 'darwin', 'sunos5')) or 'bsd' in sys.platform: + storage = os.statvfs(path) + result = storage.f_bavail * storage.f_frsize + + return result