""" This file is part of Picopore. Picopore is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Picopore is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Picopore. If not, see <http://www.gnu.org/licenses/>. """ import os from time import sleep from watchdog.observers import Observer from watchdog.events import PatternMatchingEventHandler from picopore.multiprocess import Multiprocessor from picopore.runner import PicoporeCompressionRunner from picopore.compress import chooseCompressFunc from picopore.parse_args import parseArgs, checkSure from picopore.util import log class ReadsFolder(object): def __init__(self, runner): self.runner = runner self.event_handler = PatternMatchingEventHandler(patterns=["*.fast5"], ignore_patterns=[], ignore_directories=True) self.event_handler.on_created = self.on_created self.event_handler.on_moved = self.on_moved self.observer = Observer() self.observedPaths = [] for path in self.runner.input: if os.path.isdir(path): self.observer.schedule(self.event_handler, path, recursive=True) self.observedPaths.append(path) log("Monitoring {} in real time. Press Ctrl+C to exit.".format(", ".join(self.observedPaths))) def start(self): self.observer.start() self.runner.run(postprocess=False) def add_file(self, path): self.runner.process([path]) def on_created(self, event): if self.runner.skip_root and os.path.dirname(event.src_path) in self.observedPaths: return 0 elif self.runner.prefix is not None and os.path.basename(event.src_path).startswith(self.runner.prefix): return 0 else: self.add_file(event.src_path) return 0 def on_moved(self, event): if self.runner.skip_root and os.path.dirname(event.src_path) in self.observedPaths and os.path.dirname(event.dest_path) not in self.observedPaths: self.add_file(event.dest_path) def stop(self): log("Processing in-progress files. Press Ctrl-C again to abort.") try: self.runner.stop() except KeyboardInterrupt: log("Aborted.") pass self.observer.stop() self.observer.join() class PicoporeRealtimeRunner(PicoporeCompressionRunner): def __init__(self, args): super(PicoporeRealtimeRunner, self).__init__(args) _, name = chooseCompressFunc(self.revert, self.mode, self.fastq, self.summary, self.manual, realtime=True) log(name + "...",end='') if self.y: log() elif checkSure(): self.y = True else: exit(1) self.readsFolder = ReadsFolder(self) def execute(self): self.readsFolder.start() try: while True: sleep(5) except KeyboardInterrupt: log("\nExiting Picopore.") self.readsFolder.stop() return 0 __description = """"picopore-realtime monitors a directory for new reads and compresses them in real time""" def main(): args = parseArgs(description=__description, prog='picopore-realtime') runner = PicoporeRealtimeRunner(args) return runner.execute() if __name__ == "__main__": exit(main())