view snp-fuse.py @ 33:b6bc9158666c

planemo upload commit 7f6183b769772449fbcee903686b8d5ec5b7439f-dirty
author jpayne
date Thu, 01 Feb 2018 17:46:04 -0500 (2018-02-01)
parents eefdd97a6749
children
line wrap: on
line source
#! /usr/bin/env python3

from fuse import FUSE, FuseOSError, Operations, LoggingMixIn
from multiprocessing import Process

import argparse
import logging
import os, os.path, sys
import subprocess
import tarfile


class ArchiveDir(LoggingMixIn, Operations):
	"FUSE object to open a tar.bz file and expose it as a read-only directory"
	def __init__(self, archive):
		self.archive = archive
		self.openfiles = {}

	def readdir(self, path, fh):
		for symbol in ['.','..']:
			yield symbol
		for name in self.archive.getnames():
			yield name

	# def statfs(self, fh):
	# 	return dict(f_bavail=0,
	# 				f_bfree=0,
	# 				f_blocks=0,
	# 				f_bsize=0,
	# 				f_favail=0,
	# 				f_ffree=0,
	# 				f_files=0,
	# 				f_flag=0,
	# 				f_frsize=0,
	# 				f_namemax=0)

	def getattr(self, path, fh=None):
		name = os.path.basename(path)
		info = self.archive.getmember(name)
		return dict(st_atime=info.mtime,
					st_ctime=info.mtime,
					st_gid=info.gid,
					st_mode=info.mode,
					st_nlink=2,
					st_size=info.size,
					st_mtime=info.mtime)

	def open(self, path, flags):
		name = os.path.basename(path)
		self.openfiles[name] = self.archive.extractfile(name)

	def release(self, path, fh):
		name = os.path.basename(path)
		self.openfiles[name].close()
		del self.openfiles[name]

	def read(self, path, length, offset, fh):
		name = os.path.basename(path)
		fh = self.openfiles[name]
		fh.seek(offset)
		return fh.read(length=length)


def start_fs(arch, mount_point):
	FUSE(ArchiveDir(arch), 
		 mount_point, 
		 nothreads=True, 
		 foreground=False, 
		 rdonly=True, 
		 volname="snp-fuse") #does this block?


def main(archive, mount_point, command):
	with tarfile.open(archive, 'r:bz2') as arch:
		#t = Process(target=start_fs, args=(arch, mount_point), daemon=True)
		#t.start()
		start_fs(arch, mount_point)
		subprocess.check_call(command, shell=True, stdout=sys.stdout, stderr=sys.stderr)
		#t.terminate()
		#t.join()


if __name__ == '__main__':
		 # create the default logger used by the logging mixin
	logger = logging.getLogger('fuse.log-mixin')
	logger.setLevel(logging.DEBUG)
	# create console handler with a higher log level
	ch = logging.StreamHandler()
	ch.setLevel(logging.DEBUG)
	# add the handlers to the logger
	logger.addHandler(ch)
	parser = argparse.ArgumentParser(description="mount a bzip2 archive for reading")
	parser.add_argument('archive')
	parser.add_argument('mount_point')
	parser.add_argument('command')
	args = parser.parse_args()
	main(**vars(args))