|
|
@@ -0,0 +1,110 @@ |
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
|
|
|
import datetime |
|
|
|
import os |
|
|
|
import subprocess |
|
|
|
import sys |
|
|
|
|
|
|
|
import inotify.adapters |
|
|
|
|
|
|
|
def extract_zip(path, dest): |
|
|
|
p = subprocess.run(['unzip', '-o', '-qq', path, '-d', dest]) |
|
|
|
if p.returncode != 0: |
|
|
|
raise Exception('failed to extract ' + path) |
|
|
|
|
|
|
|
def extract_rar(path, dest): |
|
|
|
if not dest.endswith('/'): |
|
|
|
dest += '/' |
|
|
|
p = subprocess.run(['unrar', 'x', '-idq', '-y', path, dest]) |
|
|
|
if p.returncode != 0: |
|
|
|
raise Exception('failed to extract ' + path) |
|
|
|
|
|
|
|
def extract_tar_gz(path, dest): |
|
|
|
if not dest.endswith('/'): |
|
|
|
dest += '/' |
|
|
|
p = subprocess.run([ |
|
|
|
'tar', |
|
|
|
'-C', dest, # goes first cuz reasons? |
|
|
|
'-x', '-z', |
|
|
|
'-f', path]) |
|
|
|
if p.returncode != 0: |
|
|
|
raise Exception('failed to extract ' + path) |
|
|
|
|
|
|
|
ARCHIVE_HANDLERS = { |
|
|
|
'.zip': extract_zip, |
|
|
|
'.rar': extract_rar, |
|
|
|
'.tar.gz': extract_tar_gz |
|
|
|
} |
|
|
|
|
|
|
|
def convert_name(path): |
|
|
|
base = os.path.basename(path) |
|
|
|
date = str(datetime.date.today()) |
|
|
|
return str(date) + '-' + ''.join(c for c in base if c.isalpha()) |
|
|
|
|
|
|
|
def process_file(path, extractdir): |
|
|
|
filename = os.path.basename(path) |
|
|
|
for (ext, handler) in ARCHIVE_HANDLERS.items(): |
|
|
|
if path.endswith(ext): |
|
|
|
# Set up the directory |
|
|
|
destdir = os.path.realpath(os.path.join(extractdir, convert_name(path))) |
|
|
|
os.makedirs(destdir, exist_ok=True) |
|
|
|
|
|
|
|
# Actually extract it |
|
|
|
print('Processing', filename, '...') |
|
|
|
handler(path, destdir) |
|
|
|
print('Extracted', filename, 'to', destdir) |
|
|
|
return True |
|
|
|
|
|
|
|
# If we did nothing, just ignore it. |
|
|
|
print('File', filename, 'doesn\'t seem to be an archive, ignoring') |
|
|
|
return False |
|
|
|
|
|
|
|
def main(args): |
|
|
|
if len(args) != 3: |
|
|
|
print('usage: ./crowsnest.py <watchdir(s)> <extractdir>') |
|
|
|
return 1 |
|
|
|
|
|
|
|
# Do setup and sanity checking |
|
|
|
watchdirs = args[1].split(',') |
|
|
|
extractdir = args[2] |
|
|
|
for d in watchdirs: |
|
|
|
if not os.path.exists(d): |
|
|
|
print('This watch path does not exist:', d) |
|
|
|
return 1 |
|
|
|
if not os.path.exists(extractdir): |
|
|
|
print('extract path does not exist') |
|
|
|
return 1 |
|
|
|
|
|
|
|
# Set up the watch |
|
|
|
watch = inotify.adapters.Inotify() |
|
|
|
for d in watchdirs: |
|
|
|
real = os.path.realpath(d) |
|
|
|
watch.add_watch(real) |
|
|
|
print('Added watch for:', real) |
|
|
|
|
|
|
|
# Start watching |
|
|
|
for event in watch.event_gen(yield_nones=False): |
|
|
|
(_, type_names, path, filename) = event |
|
|
|
|
|
|
|
# Do some checking to see if it was something we care about. |
|
|
|
wasclosewrite = False |
|
|
|
for tns in type_names: |
|
|
|
if tns == 'IN_CLOSE_WRITE': |
|
|
|
wasclosewrite = True |
|
|
|
if not wasclosewrite: |
|
|
|
continue |
|
|
|
|
|
|
|
# Actually deal with it. |
|
|
|
try: |
|
|
|
fullpath = os.path.join(path, filename) |
|
|
|
did_something = process_file(fullpath, extractdir) |
|
|
|
if did_something: |
|
|
|
os.remove(fullpath) |
|
|
|
except Exception as err: |
|
|
|
print('Failed to process file:', str(err)) |
|
|
|
|
|
|
|
# Probs won't get here. |
|
|
|
return 0 |
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
sys.exit(main(sys.argv)) |