Skip to content

Instantly share code, notes, and snippets.

@sheljohn
Last active August 22, 2018 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sheljohn/9ec9ea7f79aad598010bd19d96791360 to your computer and use it in GitHub Desktop.
Save sheljohn/9ec9ea7f79aad598010bd19d96791360 to your computer and use it in GitHub Desktop.
Python 3 wrapper for os.stat_result
import os, stat, math
import pwd, grp
from datetime import datetime
'''
Wrapper for os.stat_result, which contains all the information I usually need,
in a form that is simple to interact with.
For example:
x = FileStat( '/path/to/file.zip' )
# permissions
if not x.perm['urw']:
print 'Needs read+write permission!'
# size
if x.size['GB'] > 1:
print 'File is too big'
print(x.size) # auto-select correct unit
# user/group info
x.owner.name
x.group.id
print(x.owner) # prints: name (id)
'''
# ------------------------------------------------------------------------
class _FileSize:
__slots__ = ('bytes', 'scale', 'units')
def __init__(self, bsize):
self.bytes = bsize
self.scale = math.log(max([ bsize, 1 ]))
self.scale = int(self.scale // math.log(1024))
self.units = ['B','kB','MB','GB','TB','PB']
def __getitem__(self, key):
try:
if isinstance(key,str):
s = self.units.index(key)
else:
s = int(key)
except:
raise ValueError('Unknown scale: {}'.format(key))
return self.bytes / 1024**s
def __str__(self):
s = min([ len(self.units)-1, self.scale ])
return '%.2f %s' % ( self[s], self.units[s] )
# ---------- ===== ----------
class _FileTime:
# access, modify, create/metadata
__slots__ = ('a', 'm', 'c')
def __init__(self, a,m,c, convert=False):
if convert:
self.a = datetime.fromtimestamp(a)
self.m = datetime.fromtimestamp(m)
self.c = datetime.fromtimestamp(c)
else:
self.a = a
self.m = m
self.c = c
# ------------------------------------------------------------------------
class _FileOwner:
__slots__ = ('id', 'name')
def __init__(self,uid):
self.id = uid
self.name = pwd.getpwuid(uid).pw_name
def __str__(self):
return '%s (%d)' % (self.name, self.id)
# ---------- ===== ----------
class _FileGroup:
__slots__ = ('id', 'name')
def __init__(self, gid):
self.id = gid
self.name = grp.getgrgid(gid).gr_name
def __str__(self):
return '%s (%d)' % (self.name, self.id)
# ---------- ===== ----------
class _FilePerm:
__slots__ = ('mode', 'octal', 'code')
def __init__(self, mode):
self.mode = mode
self.octal = oct(stat.S_IMODE(mode))
self.code = {
'u': {'r': stat.S_IRUSR, 'w': stat.S_IWUSR, 'x': stat.S_IXUSR},
'g': {'r': stat.S_IRGRP, 'w': stat.S_IWGRP, 'x': stat.S_IXGRP},
'o': {'r': stat.S_IROTH, 'w': stat.S_IWOTH, 'x': stat.S_IXOTH},
}
def __getitem__(self, key):
"""
Key should be: ur, ux, urw, grw
I.e. first letter owner, rest permission
"""
x = key[0]
k = key[1:]
for y in k:
if not bool(self.mode & self.code[x][y]):
return False
return True
def __str__(self):
return str(self.octal)
# ------------------------------------------------------------------------
class FileStat:
__slots__ = ('perm', 'size', 'owner', 'group', 'time')
def __init__(self, fstat, convert=False):
if isinstance(fstat,str):
fstat = os.stat(fstat)
# see also:
# st_rsize on OSX
# st_birthtime on FreeBSD
self.size = _FileSize( fstat.st_size )
self.perm = _FilePerm( fstat.st_mode )
self.owner = _FileOwner( fstat.st_uid )
self.group = _FileGroup( fstat.st_gid )
self.time = _FileTime( fstat.st_atime, fstat.st_mtime, fstat.st_ctime )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment