Esempio n. 1
0
        public async Task <List <RelocatableTorrentCandidate> > FindRelocatableTorrentCandidatesAsync(MapTorrentsToDiskRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            var relocatableTorrentCandidates = new List <RelocatableTorrentCandidate>();

            if (request.PathsToScan == null || request.TorrentIds == null)
            {
                return(relocatableTorrentCandidates);
            }

            var torrents = await _torrentClient.GetTorrentsByIDsAsync(request.TorrentIds);

            _logger.LogDebug("Found {0} torrents", torrents.Count());

            var extensionsWhitelist = torrents
                                      .SelectMany(t => t.Files)
                                      .Select(tf => Path.GetExtension(tf.FileLocationInTorrent))
                                      .Distinct()
                                      .ToArray();

            var filePathsByFileNameLookup = GetFilePathsByFileNameLookup(request.PathsToScan, extensionsWhitelist);

            _logger.LogDebug("Found {0} files to go through", filePathsByFileNameLookup.Count);

            foreach (var torrent in torrents)
            {
                _logger.LogDebug("Looking for data matching torrent {0}", torrent.Name);
                var largestFileSize      = torrent.Files.Max(f => f.SizeInBytes);
                var biggestFileInTorrent = torrent.Files.First(f => f.SizeInBytes == largestFileSize);
                var fileNameToSearch     = Path.GetFileName(biggestFileInTorrent.FileLocationInTorrent);

                _logger.LogDebug("Searching for a file named '{0}' with a size around {1}B", fileNameToSearch, largestFileSize);
                var matchingFiles = filePathsByFileNameLookup.Contains(fileNameToSearch)
                    ? filePathsByFileNameLookup[fileNameToSearch].Select(f => new FileInfo(f))
                    : Array.Empty <FileInfo>();

                _logger.LogDebug("Found {0} matches by filename: {1}", matchingFiles.Count(),
                                 string.Join(", ", matchingFiles.Select(fi => $"<{fi.Name}, {fi.Length}B>")));

                matchingFiles = matchingFiles
                                .Where(fi => fi.Length == biggestFileInTorrent.SizeInBytes)
                                .ToArray();

                if (!matchingFiles.Any())
                {
                    _logger.LogDebug("No matching files found by filename and size");
                }
                else
                {
                    _logger.LogDebug("Found {0} matches by filename and size: {1}", matchingFiles.Count(),
                                     string.Join(", ", matchingFiles.Select(fi => $"<{fi.Name}, {fi.Length}B>")));
                }

                var candidates = CreateTorrentRelocateCandidates(biggestFileInTorrent, matchingFiles);
                candidates = GetCandidatesThatMatchAllTorrentFiles(torrent, candidates);

                relocatableTorrentCandidates.Add(new RelocatableTorrentCandidate
                {
                    TorrentID        = torrent.ID,
                    TorrentName      = torrent.Name,
                    TorrentFilePaths = torrent.Files.Select(t => t.FileLocationInTorrent).ToList(),
                    RelocateOptions  = candidates,
                    ChosenOption     = candidates.FirstOrDefault()
                });
            }

            return(relocatableTorrentCandidates);
        }