def test_CopyTask_fails_on_existing_dst(tmp_path): """CopyTask fails if dst file exists""" src = tmp_path.joinpath("foo") dst = tmp_path.joinpath("bar") src.touch() op = tasks.CopyTask(src, dst) op.start() with pytest.raises(FileExistsAndIsIdenticalError): op.start() with pytest.raises(FileExistsAndIsIdenticalError): tasks.CopyTask(src, dst).__validate__()
def test_CopyTask_can_be_serialized(tmp_path): """CopyTask can be serialized to a dict""" src = tmp_path.joinpath("foo") dst = tmp_path.joinpath("bar") src.touch() tsk = tasks.CopyTask(src, dst) # validate gets overwritten by from_dict assert tsk == tasks.Task.from_dict(tsk.__dict__)
def test_CopyTask(tmp_path): """CopyTask copies a file""" src = tmp_path.joinpath("foo") dst = tmp_path.joinpath("bar") src.touch() op = tasks.CopyTask(src, dst) assert Path(op.src).exists() assert not Path(op.dst).exists() op.start() assert Path(op.src).exists() assert Path(op.dst).exists()
def test_TaskQueue_fetch(tmp_path): """TaskQueue.fetch() fetches the contents of the queue without modifying it""" src = tmp_path.joinpath("foo") src.touch() q = tasks.TaskQueue(tmp_path.joinpath("qop.db")) q.put(tasks.CopyTask(src, tmp_path.joinpath("copied_file"))) q.put(tasks.DeleteTask(tmp_path.joinpath("copied_file"), validate=False)) q.put(tasks.DeleteTask(tmp_path.joinpath("foo"))) # all three are pending assert len(q.fetch(status=None, n=5)) == 3 assert len(q.fetch(status=(Status.PENDING, Status.OK), n=3)) == 3 assert len(q.fetch(status=None, n=None)) == 3 assert len(q.fetch(status=(Status.PENDING, ), n=None)) == 3 q.start() sleep(0.5) assert len(q.fetch(status=None, n=5)) == 3 assert len(q.fetch(status=Status.FAIL, n=5)) == 0 assert len(q.fetch(status=Status.OK, n=5)) == 3
def test_TaskQueue_can_run_baisc_tasks(tmp_path): """TaskQueue can queue and run tasks""" src = tmp_path.joinpath("foo") src.touch() q = tasks.TaskQueue(tmp_path.joinpath("qop.db")) q.put(tasks.CopyTask(src, tmp_path.joinpath("copied_file"))) q.start() wait_for_queue(q) assert tmp_path.joinpath("copied_file").is_file() q.put( tasks.MoveTask(tmp_path.joinpath("copied_file"), tmp_path.joinpath("moved_file"))) q.start() wait_for_queue(q) assert not tmp_path.joinpath("copied_file").is_file() assert tmp_path.joinpath("moved_file").is_file() q.put(tasks.DeleteTask(tmp_path.joinpath("moved_file"))) q.start() wait_for_queue(q) assert not tmp_path.joinpath("moved_file").is_file() assert src.is_file() assert q.active_processes() == 0
def handle_copy_convert_move(args, client) -> Dict: sources = args.paths[:-1] dst_dir = Path(args.paths[-1]).resolve() is_queue_active = client.is_queue_active() assert isinstance(dst_dir, Path) assert len(sources) > 0 assert sources != dst_dir # for use by `qop re` args_cache = Path( appdirs.user_cache_dir('qop')).joinpath('last_args.pickle') if args_cache.exists(): args_cache.unlink() with open(args_cache, 'wb') as f: args.parser = None pickle.dump(args, f, pickle.HIGHEST_PROTOCOL) # setup scanner if args.include is not None: scanner = scanners.IncludeScanner(args.include) elif args.exclude is not None: scanner = scanners.ExcludeScanner(args.exclude) elif args.mode == "convert": scanner = scanners.Scanner() else: scanner = scanners.PassScanner() # setup converter (if necessary) if args.mode == "convert": conv = converters.PydubConverter(remove_art=args.remove_art, parameters=args.parameters) # TODO conv_copy = converters.CopyConverter(remove_art=args.remove_art) if args.convert_only is not None: conv_mode = "include" conv_exts = ["." + e for e in args.convert_only] elif args.convert_not is not None: conv_mode = "exclude" conv_exts = ["." + e for e in args.convert_not] elif args.convert_none: conv_mode = "none" conv_exts = None else: conv_mode = "all" conv_exts = None else: conv_mode = None conv_exts = None conv = None conv_copy = None for source in sources: root = Path(source).resolve().parent children = scanner.scan(source) for src in children: lg.debug(f"inserting {src}") src = Path(src).resolve() dst = Path(dst_dir).resolve().joinpath(src.relative_to(root)) # setup convert task if args.mode == "convert": if conv_mode == "all": dst = dst.with_suffix("." + conv.ext) tsk = tasks.ConvertTask(src=src, dst=dst, converter=conv) elif conv_mode == "include" and src.suffix in conv_exts: dst = dst.with_suffix("." + conv.ext) tsk = tasks.ConvertTask(src=src, dst=dst, converter=conv) elif conv_mode == "exclude" and src.suffix not in conv_exts: dst = dst.with_suffix("." + conv.ext) tsk = tasks.ConvertTask(src=src, dst=dst, converter=conv) elif args.remove_art: tsk = tasks.SimpleConvertTask(src=src, dst=dst, converter=conv_copy) else: tsk = tasks.CopyTask(src=src, dst=dst) elif args.mode == "move": tsk = tasks.MoveTask(src=src, dst=dst) elif args.mode == "copy": tsk = tasks.CopyTask(src=src, dst=dst) else: raise ValueError rsp = client.send_command(Command.QUEUE_PUT, payload=tsk) if not is_queue_active and not args.enqueue_only: client.send_command(Command.QUEUE_START) is_queue_active = True if args.verbose: print(format_response(rsp)) print(format_response_summary(client.stats), end="\r") if not args.enqueue_only: client.send_command(Command.QUEUE_START) return {"status": Status.OK, "msg": "enqueue finished"}