Exemple #1
0
def test_add_linking_success(mocker: MockerFixture):
    api = mocker.Mock(spec=TransmissionApi)
    api.add_torrent_with_files.return_value = CommandResult(success=True)
    api.add_torrent.return_value = CommandResult(success=True)
    add_service = AddService(api)

    fs = MockFilesystem({"test_path"})
    locator: TorrentDataLocator = DefaultTorrentDataLocator(fs)
    find_service = FindService(locator)
    path = Path("/", "test_path")
    file = MetainfoFile(
        {
            "name": "meaningless",
            "info_hash": "meaningless and necessary",
            "info": {
                "length": 5
            },
        },
        path,
    )
    command = LinkingAddCommand(add_service, fs,
                                {TorrentData(file, Path("/some/place"))})

    output: LinkingAddOutput = command.run()

    assert not fs.exists(path)
    assert output.linked_torrents == {file: Path("/some/place")}
Exemple #2
0
def test_linking_add_run_display_failed(mocker: MockerFixture, capsys):
    api = mocker.Mock(spec=TransmissionApi)
    api.add_torrent_with_files.return_value = CommandResult(error="unknown",
                                                            success=False)
    api.add_torrent.return_value = CommandResult(error="unknown",
                                                 success=False)
    add_service = AddService(api)

    fs = MockFilesystem({"test_path"})
    locator: TorrentDataLocator = DefaultTorrentDataLocator(fs)
    find_service = FindService(locator)
    path = Path("/", "test_path")
    file = MetainfoFile(
        {
            "name": "meaningless",
            "info_hash": "meaningless and necessary",
            "info": {
                "length": 5
            },
        },
        path,
    )
    command = LinkingAddCommand(add_service, fs,
                                {TorrentData(file, Path("/some/place"))})

    output: LinkingAddOutput = command.run()
    output.display()

    result = capsys.readouterr().out

    assert result == "\n".join(["1 failed:", "meaningless because: unknown"
                                ]) + "\n"
Exemple #3
0
def test_find_missing():
    metainfo_path = Path("/", "metainfo.torrent")
    properties = {
        "info_hash": "meaningless and necessary",
        "name": "test_name",
        "info": {
            "files": [
                {
                    "path": ["file1"],
                    "length": 0
                },
                {
                    "path": ["file2"],
                    "length": 0
                },
            ]
        },
    }
    metainfo_file = MetainfoFile(properties, metainfo_path)
    fs = MockFilesystem({"data"})

    locator = DefaultTorrentDataLocator(fs)
    find_service = FindService(locator)

    command = FindCommand(find_service, {metainfo_file})
    output = command.run()

    assert output.found == set()
    assert output.missing == {metainfo_file}
Exemple #4
0
def find_factory(argv: Sequence[str],
                 dependencies: Mapping) -> CommandFactoryResult:
    reader = dependencies["metainfo_reader"]
    fs: Filesystem = dependencies["fs"]
    locator: FileLocator = dependencies["locator"]

    # parse arguments
    from clutchless.spec import find as find_command

    args = docopt(doc=find_command.__doc__, argv=argv)
    find_args = FindArgs(args, reader, fs, locator)

    data_directories = find_args.get_data_dirs()
    file_locator = MultipleDirectoryFileLocator(data_directories, fs)
    data_reader = DefaultTorrentDataReader(fs)
    data_locator = CustomTorrentDataLocator(file_locator, data_reader)
    service = FindService(data_locator)

    metainfo_files = find_args.get_torrent_files()
    if not metainfo_files:
        raise RuntimeError("Did not find any metainfo files")
    else:
        print(f"Found {len(metainfo_files)} metainfo files:")
        for file in metainfo_files:
            print(f"{file.name} at {file.path.parent}")
    return FindCommand(service, metainfo_files), args
Exemple #5
0
def test_find_run_output(capsys):
    metainfo_path = Path("/", "metainfo.torrent")
    properties = {
        "info_hash": "meaningless and necessary",
        "name": "test_name",
        "info": {
            "files": [
                {
                    "path": ["file1"],
                    "length": 0
                },
                {
                    "path": ["file2"],
                    "length": 0
                },
            ]
        },
    }
    metainfo_file = MetainfoFile(properties, metainfo_path)

    missing_properties = {
        "info_hash": "meaningless and necessary",
        "name": "another_name",
        "info": {
            "files": [
                {
                    "path": ["file3"],
                    "length": 0
                },
                {
                    "path": ["file4"],
                    "length": 0
                },
            ]
        },
    }
    missing_metainfo_file = MetainfoFile(missing_properties,
                                         Path("/missing.torrent"))
    fs = MockFilesystem({"data": {"test_name": {"file1", "file2"}}})

    locator = DefaultTorrentDataLocator(fs)
    find_service = FindService(locator)

    command = FindCommand(find_service, {metainfo_file, missing_metainfo_file})
    output = command.run()
    output.display()

    result = capsys.readouterr().out
    assert (result == "\n".join([
        "Starting search - press Ctrl+C to cancel",
        "1/2 test_name found at /data",
        "Found 1 torrents:",
        "\x1b[32m✓ test_name at /data",
        "Did not find 1 torrents:",
        "\x1b[31m✗ another_name",
    ]) + "\n")
Exemple #6
0
def add_factory(argv: Sequence[str],
                dependencies: Mapping) -> CommandFactoryResult:
    client = dependencies["client"]
    reader: MetainfoIO = dependencies["metainfo_reader"]

    # parse arguments
    from clutchless.spec import add as add_command

    args = docopt(doc=add_command.__doc__, argv=argv)
    fs: Filesystem = dependencies["fs"]
    if not args["--delete"]:
        fs = DryRunFilesystem()

    metainfo_file_paths = collect_metainfo_paths(fs, args["<metainfo>"])
    metainfo_files = {reader.from_path(path) for path in metainfo_file_paths}

    data_directories = get_valid_directories(fs, args["-d"])
    file_locator = MultipleDirectoryFileLocator(data_directories, fs)
    data_reader = DefaultTorrentDataReader(fs)
    data_locator = CustomTorrentDataLocator(file_locator, data_reader)

    add_service = AddService(client)

    # action
    command: Command = AddCommand(add_service, fs, metainfo_files)
    if len(data_directories) > 0:
        find_service = FindService(data_locator)
        if not args["--force"]:
            add_service = LinkOnlyAddService(client)

        torrent_data: Iterable[TorrentData] = find_service.find(metainfo_files)
        response = input("Continue? [Y/N]:")
        if response.strip().lower() != "y":
            raise RuntimeError("User decided not to continue")

        command = LinkingAddCommand(add_service, fs, torrent_data)
    return command, args
Exemple #7
0
def link_factory(argv: Sequence[str],
                 dependencies: Mapping) -> CommandFactoryResult:
    reader = dependencies["metainfo_reader"]
    client = dependencies["client"]
    fs = dependencies["fs"]

    data_service = LinkDataService(client, reader)
    link_service = LinkService(reader, data_service)

    # parse
    from clutchless.spec import link as link_command

    link_args = docopt(doc=link_command.__doc__, argv=argv)

    data_dirs: Set[Path] = get_valid_directories(fs, link_args.get("<data>"))
    file_locator = MultipleDirectoryFileLocator(data_dirs, fs)
    data_reader = DefaultTorrentDataReader(fs)
    data_locator = CustomTorrentDataLocator(file_locator, data_reader)
    find_service = FindService(data_locator)

    if link_args.get("--list"):
        return ListLinkCommand(link_service), link_args
    return LinkCommand(link_service, find_service), link_args