Having written many programs that work with groups of files, the zero programs were written based on a simple batch engine in the zero
utility. All of the other programs import the first program to take advantage of its batch processor while supplementing there own functionality in place of zeroing out file data. This is committed for archival to be run under Python 2.5 or later versions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | # ==============================================================================
# zero.py
# ==============================================================================
import os
import sys
ERROR = False
def main(function):
try:
arguments = sys.argv[1:]
assert arguments
for path in arguments:
assert os.path.isdir(path)
for path in arguments:
engine(path, function)
except:
sys.stdout.write('Usage: %s <directory>' % os.path.basename(sys.argv[0]))
def engine(path, function):
global ERROR
for root, dirs, files in os.walk(path):
for name in files:
path = os.path.join(root, name)
try:
function(path)
except:
sys.stderr.write('%sError: %s' % (ERROR and '\n' or '', path))
ERROR = True
def zero(path):
size = os.path.getsize(path)
if size:
data = open(path, 'wb')
todo = size
if todo >= 2 ** 20:
buff = '\x00' * 2 ** 20
while todo >= 2 ** 20:
data.write(buff)
todo = size - data.tell()
data.write('\x00' * todo)
data.close()
if __name__ == '__main__':
main(zero)
# ==============================================================================
# upper.py
# ==============================================================================
import zero
def upper(path):
root, ext = zero.os.path.splitext(path)
upper = ext.upper()
if ext != upper:
zero.os.rename(path, root + upper)
if __name__ == '__main__':
zero.main(upper)
# ==============================================================================
# untar.py
# ==============================================================================
import zero
import tarfile
if __name__ == '__main__':
zero.main(lambda path: tarfile.open(path).extractall(
zero.os.path.dirname(path)))
# ==============================================================================
# remove.py
# ==============================================================================
import zero
if __name__ == '__main__':
zero.main(zero.os.remove)
# ==============================================================================
# one.py
# ==============================================================================
import zero
def one(path):
size = zero.os.path.getsize(path)
if size:
data = open(path, 'wb')
todo = size
if todo >= 2 ** 20:
buff = '\xFF' * 2 ** 20
while todo >= 2 ** 20:
data.write(buff)
todo = size - data.tell()
data.write('\xFF' * todo)
data.close()
if __name__ == '__main__':
zero.main(one)
# ==============================================================================
# lower.py
# ==============================================================================
import zero
def lower(path):
root, ext = zero.os.path.splitext(path)
lower = ext.lower()
if ext != lower:
zero.os.rename(path, root + lower)
if __name__ == '__main__':
zero.main(lower)
# ==============================================================================
# random.py
# ==============================================================================
import zero
def kaos(path):
size = zero.os.path.getsize(path)
if size:
data = open(path, 'wb')
todo = size
while todo:
data.write(zero.os.urandom(min(todo, 2 ** 20)))
todo = size - data.tell()
data.close()
if __name__ == '__main__':
zero.main(kaos)
# ==============================================================================
# name.py
# ==============================================================================
import zero
import random
STRING = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
def ident(path):
d, b = zero.os.path.split(path)
zero.os.rename(path, zero.os.path.join(d, ''.join(random.sample(
STRING, len(STRING))) + zero.os.path.splitext(b)[1]))
if __name__ == '__main__':
zero.main(ident)
# ==============================================================================
# newlines.py
# ==============================================================================
import zero
TABLE = ''.join(map(chr, range(256)))
DELETECHARS = ''.join(c for c in TABLE if len(repr(c)) != 6)
def convert(path):
if not file(path, 'rb').read(2 ** 20).translate(TABLE, DELETECHARS):
data = file(path, 'r').read()
file(path, 'w').write(data)
if __name__ == '__main__':
zero.main(convert)
# ==============================================================================
# extension.py
# ==============================================================================
import zero
def bias(path):
root, ext = zero.os.path.splitext(path)
if not ext[1:]:
zero.os.rename(path, root + '.txt')
if __name__ == '__main__':
zero.main(bias)
|
Please ensure that you understand a program before running it. There utilities work on groups of files and can cause quite a mess if not used responsibly.
Interesting approach -- sort of like plug-ins in reverse. Seems like it would make equal (or perhaps more) sense to make each file a module that
zero
would import and run one of them based on a command-line argument. In fact one could establish a whole plug-in API that would effectively make each utility an object that could be asked to perform additional tasks, such as provide instructions for usage or post-processing statistics -- all with the same generic front-end.Implementation-wise, I don't care for each utility accessing modules imported by the
zero
module because it's longer, slower, and creates undesirable dependencies between each and how the latter is implemented. It's also an unnecessary optimization becausesys.modules
effectively keeps a cache of the modules that have been imported already and avoids doing so a second time.