annotate snp-fuse.py @ 64:b5cf2ec0c540 tip

planemo upload
author jpayne
date Sat, 29 Jun 2024 06:56:11 -0400
parents eefdd97a6749
children
rev   line source
jpayne@0 1 #! /usr/bin/env python3
jpayne@0 2
jpayne@0 3 from fuse import FUSE, FuseOSError, Operations, LoggingMixIn
jpayne@0 4 from multiprocessing import Process
jpayne@0 5
jpayne@0 6 import argparse
jpayne@0 7 import logging
jpayne@0 8 import os, os.path, sys
jpayne@0 9 import subprocess
jpayne@0 10 import tarfile
jpayne@0 11
jpayne@0 12
jpayne@0 13 class ArchiveDir(LoggingMixIn, Operations):
jpayne@0 14 "FUSE object to open a tar.bz file and expose it as a read-only directory"
jpayne@0 15 def __init__(self, archive):
jpayne@0 16 self.archive = archive
jpayne@0 17 self.openfiles = {}
jpayne@0 18
jpayne@0 19 def readdir(self, path, fh):
jpayne@0 20 for symbol in ['.','..']:
jpayne@0 21 yield symbol
jpayne@0 22 for name in self.archive.getnames():
jpayne@0 23 yield name
jpayne@0 24
jpayne@0 25 # def statfs(self, fh):
jpayne@0 26 # return dict(f_bavail=0,
jpayne@0 27 # f_bfree=0,
jpayne@0 28 # f_blocks=0,
jpayne@0 29 # f_bsize=0,
jpayne@0 30 # f_favail=0,
jpayne@0 31 # f_ffree=0,
jpayne@0 32 # f_files=0,
jpayne@0 33 # f_flag=0,
jpayne@0 34 # f_frsize=0,
jpayne@0 35 # f_namemax=0)
jpayne@0 36
jpayne@0 37 def getattr(self, path, fh=None):
jpayne@0 38 name = os.path.basename(path)
jpayne@0 39 info = self.archive.getmember(name)
jpayne@0 40 return dict(st_atime=info.mtime,
jpayne@0 41 st_ctime=info.mtime,
jpayne@0 42 st_gid=info.gid,
jpayne@0 43 st_mode=info.mode,
jpayne@0 44 st_nlink=2,
jpayne@0 45 st_size=info.size,
jpayne@0 46 st_mtime=info.mtime)
jpayne@0 47
jpayne@0 48 def open(self, path, flags):
jpayne@0 49 name = os.path.basename(path)
jpayne@0 50 self.openfiles[name] = self.archive.extractfile(name)
jpayne@0 51
jpayne@0 52 def release(self, path, fh):
jpayne@0 53 name = os.path.basename(path)
jpayne@0 54 self.openfiles[name].close()
jpayne@0 55 del self.openfiles[name]
jpayne@0 56
jpayne@0 57 def read(self, path, length, offset, fh):
jpayne@0 58 name = os.path.basename(path)
jpayne@0 59 fh = self.openfiles[name]
jpayne@0 60 fh.seek(offset)
jpayne@0 61 return fh.read(length=length)
jpayne@0 62
jpayne@0 63
jpayne@0 64 def start_fs(arch, mount_point):
jpayne@0 65 FUSE(ArchiveDir(arch),
jpayne@0 66 mount_point,
jpayne@0 67 nothreads=True,
jpayne@0 68 foreground=False,
jpayne@0 69 rdonly=True,
jpayne@0 70 volname="snp-fuse") #does this block?
jpayne@0 71
jpayne@0 72
jpayne@0 73 def main(archive, mount_point, command):
jpayne@0 74 with tarfile.open(archive, 'r:bz2') as arch:
jpayne@0 75 #t = Process(target=start_fs, args=(arch, mount_point), daemon=True)
jpayne@0 76 #t.start()
jpayne@0 77 start_fs(arch, mount_point)
jpayne@0 78 subprocess.check_call(command, shell=True, stdout=sys.stdout, stderr=sys.stderr)
jpayne@0 79 #t.terminate()
jpayne@0 80 #t.join()
jpayne@0 81
jpayne@0 82
jpayne@0 83 if __name__ == '__main__':
jpayne@0 84 # create the default logger used by the logging mixin
jpayne@0 85 logger = logging.getLogger('fuse.log-mixin')
jpayne@0 86 logger.setLevel(logging.DEBUG)
jpayne@0 87 # create console handler with a higher log level
jpayne@0 88 ch = logging.StreamHandler()
jpayne@0 89 ch.setLevel(logging.DEBUG)
jpayne@0 90 # add the handlers to the logger
jpayne@0 91 logger.addHandler(ch)
jpayne@0 92 parser = argparse.ArgumentParser(description="mount a bzip2 archive for reading")
jpayne@0 93 parser.add_argument('archive')
jpayne@0 94 parser.add_argument('mount_point')
jpayne@0 95 parser.add_argument('command')
jpayne@0 96 args = parser.parse_args()
jpayne@0 97 main(**vars(args))