Browse Source

HV: * Some pylint opinions are useful

git-svn-id: svn+ssh://code.jive.eu/code/svn/vbs_fs@60 5b2df0cb-e17b-44c8-90c8-480d528b6e0d
master
Harro Verkouter 2 years ago
parent
commit
650ab6b532
1 changed files with 28 additions and 29 deletions
  1. +28
    -29
      vbs_rm

+ 28
- 29
vbs_rm View File

@@ -5,14 +5,14 @@ import os, re, sys, glob, copy, struct, fnmatch, argparse, operator, itertools,
version = "$Id$"
flexbuff_pattern = '/mnt/disk*'
mark6_pattern = '/mnt/disks/*/*/data'
vbs_chunk = lambda recording: re.compile(r"^"+re.escape(recording)+"\.[0-9]{8}$")
vbs_chunk = lambda recording: re.compile(r"^"+re.escape(recording)+r"\.[0-9]{8}$")
description = """Remove FlexBuff/Mark6 recording(s) from the drives, much like rm(1), only specialized for scattered recordings"""
compose = lambda *funcs: lambda x: reduce(lambda v, f: f(v), reversed(funcs), x)
compose = lambda *funcs: lambda x: reduce(lambda v, f: f(v), reversed(funcs), x)
choice = lambda pred, t, f: lambda x: t(x) if pred(x) else f(x)
append = lambda l, e: l.append(e) or l
method = lambda f : lambda *args: f(*args)
mk = lambda **kwargs: type('', (), {'__init__':lambda o: functools.reduce(lambda a, av: setattr(a, av[0], copy.deepcopy(av[1])) or a, kwargs.iteritems(), o).__dict__.update()})
mk_rm_obj = lambda mp, p, **kwargs: mk(path=os.path.join(mp,p), recording=p, **kwargs)()
mk_rm_obj = lambda mp, p, **kwargs: mk(path=os.path.join(mp, p), recording=p, **kwargs)()

# Partition a list into two lists: matching and non-matching
def partition(pred, l):
@@ -30,8 +30,8 @@ def partition(pred, l):
mk_obj = lambda **kwargs: type('', (), kwargs)()
mk6_hdr_f = '<5I'
mk6_hdr_sz = struct.calcsize(mk6_hdr_f)
is_mk6 = compose(choice(lambda x: len(x)==mk6_hdr_sz,
compose(lambda y: y[0]==0xfeed6666 and y[1]==2, functools.partial(struct.unpack, mk6_hdr_f)),
is_mk6 = compose(choice(lambda x: len(x) == mk6_hdr_sz,
compose(lambda y: y[0] == 0xfeed6666 and y[1] == 2, functools.partial(struct.unpack, mk6_hdr_f)),
lambda z: None),
operator.methodcaller('read', mk6_hdr_sz), open)

@@ -40,22 +40,21 @@ is_mk6 = compose(choice(lambda x: len(x)==mk6_hdr_sz,
def index(acc, mp_patterns):
(mountpoint, patterns) = mp_patterns

# process unique set of file, dir entries even if multiple patterns match
# process unique set of file, dir entries even if multiple patterns match
for (rec, path) in map(lambda match: (match, os.path.join(mountpoint, match)),
reduce(lambda b, pattern: b.update(fnmatch.filter(os.listdir(mountpoint), pattern)) or b,
patterns, set())):
# Directories under mountpoints are possible vbs recordings,
# Directories under mountpoints are possible vbs recordings,
if os.path.isdir(path):
# figure out if there is at least one entry of the form "maybe_rec/maybe_rec.XXXXXXXX"
# Note that we do *not* compile a full list of all chunks. If deleting a lot of
# recordings the mem'ry consumption might get unwieldy
contents = os.listdir(path)
acc[rec].dirs.append(mk_rm_obj(mountpoint, rec, is_empty = not contents,
is_vbs = next(itertools.dropwhile(compose(operator.not_, vbs_chunk(rec).match), contents), None)
))
acc[rec].dirs.append(mk_rm_obj(mountpoint, rec, is_empty=not contents,
is_vbs=next(itertools.dropwhile(compose(operator.not_, vbs_chunk(rec).match), contents), None)))
# files may be Mk6 recordings
elif os.path.isfile(path) and is_mk6(path):
acc[rec].files.append( mk_rm_obj(mountpoint, rec) )
acc[rec].files.append(mk_rm_obj(mountpoint, rec))
return acc

# Functions to remove a directory or a file
@@ -73,21 +72,21 @@ skip = lambda x: (skip, False)

def ask(x):
ans = (raw_input("{0}? [N/y/a/q] ".format(x)) or "n").lower()
return (ask, True) if ans=="y" else \
((ask, False) if ans=="n" else \
((dont_ask, True) if ans=="a" else \
((skip, False) if ans=="q" else ask(x))))
return (ask, True) if ans == "y" else \
((ask, False) if ans == "n" else \
((dont_ask, True) if ans == "a" else \
((skip, False) if ans == "q" else ask(x))))

# return True if the entry contains anything that can be removed
# entry is a tuple of (recording, object.{files, dirs})
def maybe_remove(entry):
(empty, vbs) = zip(*map(operator.attrgetter('is_empty', 'is_vbs'), entry[1].dirs))
# check dirs - only OK to remove if all empty or at least one has detected VBS
# note: have to add check for non-empty dirs because all([]) == True ...
# note: have to add check for non-empty dirs because all([]) == True ...
# making "all([]) or any([])" evaluate to True which would be Wrong (tm)
return bool(entry[1].files or (entry[1].dirs and (all(empty) or any(vbs))))

# entry is a tuple of (recording, object.{files, dirs}), and we know either files and/or dirs is non-empty
# entry is a tuple of (recording, object.{files, dirs}), and we know either files and/or dirs is non-empty
def remove(ask_fn, entry):
summary = ', '.join(map(functools.partial(str.format, "{0[0]} {0[1]}"),
filter(operator.itemgetter(0), zip(map(len, [entry[1].files, entry[1].dirs]), ["files", "dirs"]))))
@@ -114,17 +113,17 @@ def remove(ask_fn, entry):
class AppendList(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
super(AppendList, self).__init__(option_strings, dest, nargs=nargs, **kwargs)
if not ((isinstance(nargs, str) and len(nargs)==1 and nargs[0] in '+*') or
(isinstance(nargs, int) and nargs>=0) or
(nargs == argparse.REMAINDER) ):
if not ((isinstance(nargs, str) and len(nargs) == 1 and nargs[0] in '+*') or
(isinstance(nargs, int) and nargs >= 0) or
(nargs == argparse.REMAINDER)):
raise RuntimeError, "nargs must be '+', '*', an integer >= 0 or argparse.REMAINDER for this action"

def __call__(self, p, ns, values, option_string):
setattr(ns, self.dest, values) if not hasattr(ns, self.dest) else setattr(ns, self.dest, getattr(ns, self.dest)+values)

class PrintHelp(argparse.Action):
def __call__(self, parsert, *args):
parsert.print_help() or sys.exit( 0 )
def __call__(self, p, *args):
p.print_help() or sys.exit(0)

parsert = argparse.ArgumentParser(description=description, add_help=False)
parsert.add_argument('--help', nargs=0, action=PrintHelp, help="show this help message and exit succesfully")
@@ -139,15 +138,15 @@ parsert.add_argument('-i', action="store_const", default=ask, dest='confirmation
parsert.add_argument('--watch-the-blood-dripping', default=None, action="store_true", dest="watch_the_blood_dripping",
help=argparse.SUPPRESS)
parsert.add_argument("-R", nargs=1, action=AppendList, dest='rootDirs',
help="Append directories matching the pattern to the vbs_rm search path. Shell-style wildcards ('*?') are supported. This option may be present multiple times to add multiple patterns" )
help="Append directories matching the pattern to the vbs_rm search path. Shell-style wildcards ('*?') are supported. This option may be present multiple times to add multiple patterns")
parsert.add_argument('--version', action='version', version=version, help="Print current version and exit succesfully")
parsert.add_argument("pattern", nargs='+',
help="Delete recordings matching these pattern(s). Shell-style wildcards ('*?') are supported." )
help="Delete recordings matching these pattern(s). Shell-style wildcards ('*?') are supported.")

# deal with command line
userinput = parsert.parse_args()

# If there is a pattern that is built of only wildcards [i.e. which would match all recordings, i.e. a request to
# If there is a pattern that is built of only wildcards [i.e. which would match all recordings, i.e. a request to
# delete all recordings ...] we'll ask the user to confirm that this is his/her true intent
if filter(re.compile(r'^((\*[\*\?]*)|([\*\?]*\*)|(\?+\*[\*\?]*))$').match, userinput.pattern) and \
not (userinput.confirmation is dont_ask and userinput.watch_the_blood_dripping is True):
@@ -158,16 +157,16 @@ if filter(re.compile(r'^((\*[\*\?]*)|([\*\?]*\*)|(\?+\*[\*\?]*))$').match, useri
print " For this program to accept this and proceed, you MUST run it"
print " with the following command line flags, to indicate you've "
print " understood the possible consequences:"
print
print
print " $> vbs_rm -f --watch-the-blood-dripping *"
print
print
print
print " >>>> You might want to run 'vbs_ls -l' first to <<<<"
print " >>>> get an overview of what you're about to delete <<<<"
print
print
print
print "###############################################################"
sys.exit( 1 )
sys.exit(1)

####################################################################################
# Analyze what the user actually wanted


Loading…
Cancel
Save