Add a bit of fun colors to drives

This commit is contained in:
Oleksii Shevchuk 2016-10-20 14:39:53 +03:00
parent 3bc35a9e25
commit 28dc448e18
2 changed files with 155 additions and 48 deletions

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from pupylib.PupyModule import *
from pupylib.utils.rpyc_utils import redirected_stdio
from pupylib.utils.term import colorize
__class_name__="Drives"
@ -28,21 +29,124 @@ class Drives(PupyModule):
self.client.conn.modules['pupwinutils.drives'].list_drives()
elif self.client.is_linux():
mountinfo = self.client.conn.modules['mount'].mounts()
tier1 = ( 'network', 'fuse', 'dm', 'block' )
rmount = self.client.conn.modules['mount']
ros = self.client.conn.modules['os']
mountinfo = rmount.mounts()
uid = ros.getuid()
gid = ros.getgid()
option_colors = {
'rw': 'yellow',
'nosuid': 'green',
'nodev': 'green',
'noexec': 'green',
'uid': {
'0': 'green',
str(uid): 'red'
},
'gid': {
'0': 'green',
str(gid): 'red'
},
'ro': 'green',
'user_id': {
'0':'green',
str(uid): 'red'
},
'group_id': {
'0':'green',
str(gid): 'red'
},
'allow_other': 'yellow',
'xattr': 'yellow',
'acl': 'yellow',
'username': 'red',
'domain': 'red',
'forceuid': 'yellow',
'forcegid': 'yellow',
'addr': 'red',
'unix': 'red'
}
def colorize_option(option):
if len(option) > 1:
k, v = option
else:
k = option[0]
v = None
color = option_colors.get(k)
if color:
if type(color) == dict:
if v in color:
return colorize(
'='.join([x for x in [k, v] if x]), color.get(v)
)
else:
return '='.join([x for x in [k, v] if x])
else:
return colorize(
'='.join([x for x in [k, v] if x]), color
)
else:
return '='.join([x for x in [k, v] if x])
for fstype in mountinfo.iterkeys():
if fstype in ('regular', 'dm'):
if fstype in tier1:
continue
print '{}:'.format(fstype)
print '{}:'.format(colorize(fstype, 'yellow'))
dst_max = max([len(x.dst) for x in mountinfo[fstype]])
fsname_max = max([len(x.fsname) for x in mountinfo[fstype]])
free_max = max([len(x.hfree) if x.total else 0 for x in mountinfo[fstype]])
for info in mountinfo[fstype]:
print info
fmt = '{{:<{}}} {{:<{}}} {{:>{}}} {{}}'.format(
dst_max, fsname_max, ( free_max + 3 + 4 ) if free_max else 0
)
print fmt.format(
info.dst, info.fsname, (
colorize(
('{{:>3}}% ({{:>{}}})'.format(free_max)).format(
info.pused, info.hfree
),
'white' if info.pused < 90 else 'yellow'
)
) if info.total else '',
','.join([colorize_option(option) for option in info.options])
)
print ''
for fstype in [ 'regular', 'dm' ]:
for fstype in tier1:
if not fstype in mountinfo:
continue
print '{}: '.format(fstype)
src_max = max([len(x.src) for x in mountinfo[fstype]])
dst_max = max([len(x.dst) for x in mountinfo[fstype]])
fsname_max = max([len(x.fsname) for x in mountinfo[fstype]])
free_max = max([len(x.hfree) if x.total else 0 for x in mountinfo[fstype]])
print '{}:'.format(colorize(fstype, 'green'))
for info in mountinfo[fstype]:
print info
fmt = '{{:<{}}} {{:<{}}} {{:<{}}} {{:>{}}} {{}}'.format(
dst_max, src_max, fsname_max, ( free_max + 3 + 4 ) if free_max else 0
)
print fmt.format(
info.dst, info.src, info.fsname, (
colorize(
('{{:>3}}% ({{:>{}}})'.format(free_max)).format(
info.pused, info.hfree
),
'white' if info.pused < 90 else 'yellow'
)
) if info.total else '',
','.join([colorize_option(option) for option in info.options])
)
print ''

View File

@ -11,7 +11,7 @@ class MountInfo(object):
self.src = src
self.dst = dst
self.fsname = fsname
self._options = options.split(',')
self._options = [ option.split('=') for option in options.split(',') ]
try:
vfsstat = os.statvfs(self.dst)
@ -19,25 +19,52 @@ class MountInfo(object):
self.total = vfsstat.f_blocks*vfsstat.f_bsize
self.files = vfsstat.f_files
self.exception = None
Kb = 1024
Mb = 1024*Kb
Gb = 1024*Mb
Tb = 1024*Gb
if self.total > 0:
if self.free > Tb:
self.hfree = '{}Tb'.format(self.free / Tb)
elif self.free > Gb:
self.hfree = '{}Gb'.format(self.free / Gb)
elif self.free > Mb:
self.hfree = '{}Mb'.format(self.free / Mb)
elif self.free > Kb:
self.hfree = '{}Kb'.format(self.free / Kb)
else:
self.hfree = '{}b'.format(self.free)
self.pused = 100 - int(self.free/float(self.total)*100)
except Exception as e:
self.exception = e.message
self.total = None
self.free = None
self.files = None
self.hfree = None
self.pfree = None
if self.fsname == 'tmpfs':
self.fstype = 'tmpfs'
elif self.fsname in ('smb', 'cifs', 'nfs', 'nfsv3', 'nfs4'):
self.fstype = 'network'
elif self.fsname.startswith('cgroup'):
self.fstype = 'cgroup'
elif self.src.startswith('/dev/mapper'):
self.fstype = 'dm'
elif fsname.startswith('fuse.'):
elif fsname.startswith('fuse'):
self.fstype = 'fuse'
elif self.src == 'systemd-1' and self.fsname == 'autofs':
self.fstype = 'automount'
elif self.src == 'sunrpc':
self.fstype = 'rpc'
elif src == fsname:
elif src == fsname or fsname in (
'devtmpfs', 'sysfs', 'proc', 'devpts', 'securityfs',
'pstore', 'mqueue', 'hugetlbfs', 'debugfs', 'binfmt_misc'
):
self.fstype = 'kernel'
else:
self.fstype = 'block'
@ -46,49 +73,25 @@ class MountInfo(object):
def options(self):
return [
option for option in self._options if not any([
option.startswith(value) for value in (
'relatime', 'fd', 'pgrp', 'timeout',
'minproto', 'maxproto', 'direct', 'pipe_ino',
'iocharset', 'codepage', 'lazytime', 'background_gc',
'inline_data', 'discard', 'flush_merge', 'extent_cache',
'mode', 'active_logs', 'commit', 'data', 'nr_inodes', 'size',
'shortnames', 'utf8', 'errors'
option[0].startswith(value) for value in (
'relatime', 'fd', 'pgrp', 'timeout', 'minproto',
'maxproto', 'direct', 'pipe_ino', 'iocharset',
'codepage', 'lazytime', 'background_gc', 'inline_data',
'discard', 'flush_merge', 'extent_cache', 'mode',
'active_logs', 'commit', 'data', 'nr_inodes', 'size',
'shortnames', 'utf8', 'errors', 'cache', 'rsize',
'wsize', 'echo_interval', 'actime', 'blksize',
'serverino', 'posixpaths', 'mapposix'
)
])
]
def __repr__(self):
if self.fsname in ( 'tmpfs', 'cgroup', 'fuse', 'automount', 'rpc', 'kernel' ):
return '{} type={} options={}'.format(
self.dst, self.fstype, ','.join(self.options)
)
else:
Kb = 1024
Mb = 1024*Kb
Gb = 1024*Mb
Tb = 1024*Gb
if self.total > 0:
if self.free > Tb:
free = '{}Tb'.format(self.free / Tb)
elif self.free > Gb:
free = '{}Gb'.format(self.free / Gb)
elif self.free > Mb:
free = '{}Mb'.format(self.free / Mb)
elif self.free > Kb:
free = '{}Kb'.format(self.free / Kb)
else:
free = '{}b'.format(self.free)
free = ' free={}%({})'.format(int(self.free/float(self.total)*100), free)
elif self.exception:
free = ' free=(error: {})'.format(self.exception)
else:
free = ' '
return '{} src={} fs={} options={}{}'.format(
self.dst, self.src, self.fsname, ','.join(self.options), free
)
return ' '.join([
'"{}"'.format(getattr(self, x)) for x in [
'src', 'dst', 'fsname', 'free'
] + ','.join([ '='.join(kv) for kv in self._options ])
])
def mounts():
mountinfo = {}