Exemple #1
0
        /// <summary>
        /// Resolves the specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns>Season.</returns>
        protected override Season Resolve(ItemResolveArgs args)
        {
            if (args.Parent is Series series && args.IsDirectory)
            {
                var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();

                var path = args.Path;

                var seasonParserResult = SeasonPathParser.Parse(path, true, true);

                var season = new Season
                {
                    IndexNumber = seasonParserResult.SeasonNumber,
                    SeriesId    = series.Id,
                    SeriesName  = series.Name
                };

                if (!season.IndexNumber.HasValue || !seasonParserResult.IsSeasonFolder)
                {
                    var resolver = new Naming.TV.EpisodeResolver(namingOptions);

                    var folderName = System.IO.Path.GetFileName(path);
                    var testPath   = "\\\\test\\" + folderName;

                    var episodeInfo = resolver.Resolve(testPath, true);

                    if (episodeInfo != null)
                    {
                        if (episodeInfo.EpisodeNumber.HasValue && episodeInfo.SeasonNumber.HasValue)
                        {
                            _logger.LogDebug(
                                "Found folder underneath series with episode number: {0}. Season {1}. Episode {2}",
                                path,
                                episodeInfo.SeasonNumber.Value,
                                episodeInfo.EpisodeNumber.Value);

                            return(null);
                        }
                    }
                }

                if (season.IndexNumber.HasValue)
                {
                    var seasonNumber = season.IndexNumber.Value;

                    season.Name = seasonNumber == 0 ?
                                  args.LibraryOptions.SeasonZeroDisplayName :
                                  string.Format(
                        CultureInfo.InvariantCulture,
                        _localization.GetLocalizedString("NameSeasonNumber"),
                        seasonNumber,
                        args.GetLibraryOptions().PreferredMetadataLanguage);
                }

                return(season);
            }

            return(null);
        }
Exemple #2
0
        public static bool IsSeriesFolder(
            string path,
            IEnumerable <FileSystemMetadata> fileSystemChildren,
            IDirectoryService directoryService,
            IFileSystem fileSystem,
            ILogger logger,
            ILibraryManager libraryManager,
            LibraryOptions libraryOptions,
            bool isTvContentType)
        {
            foreach (var child in fileSystemChildren)
            {
                //if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                //{
                //    //logger.LogDebug("Igoring series file or folder marked hidden: {0}", child.FullName);
                //    continue;
                //}

                // Can't enforce this because files saved by Bitcasa are always marked System
                //if ((attributes & FileAttributes.System) == FileAttributes.System)
                //{
                //    logger.LogDebug("Igoring series subfolder marked system: {0}", child.FullName);
                //    continue;
                //}

                if (child.IsDirectory)
                {
                    if (IsSeasonFolder(child.FullName, isTvContentType, libraryManager))
                    {
                        logger.LogDebug("{Path} is a series because of season folder {Dir}.", path, child.FullName);
                        return(true);
                    }
                }
                else
                {
                    string fullName = child.FullName;
                    if (libraryManager.IsVideoFile(fullName, libraryOptions))
                    {
                        if (isTvContentType)
                        {
                            return(true);
                        }

                        var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions();

                        var episodeResolver = new Naming.TV.EpisodeResolver(namingOptions);

                        var episodeInfo = episodeResolver.Resolve(fullName, false, true, false, fillExtendedInfo: false);
                        if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
                        {
                            return(true);
                        }
                    }
                }
            }

            logger.LogDebug("{Path} is not a series folder.", path);
            return(false);
        }
Exemple #3
0
        public static bool IsSeriesFolder(
            string path,
            IEnumerable <FileSystemMetadata> fileSystemChildren,
            IDirectoryService directoryService,
            IFileSystem fileSystem,
            ILogger <SeriesResolver> logger,
            ILibraryManager libraryManager,
            bool isTvContentType)
        {
            foreach (var child in fileSystemChildren)
            {
                if (child.IsDirectory)
                {
                    if (IsSeasonFolder(child.FullName, isTvContentType, libraryManager))
                    {
                        logger.LogDebug("{Path} is a series because of season folder {Dir}.", path, child.FullName);
                        return(true);
                    }
                }
                else
                {
                    string fullName = child.FullName;
                    if (libraryManager.IsVideoFile(fullName))
                    {
                        if (isTvContentType)
                        {
                            return(true);
                        }

                        var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions();

                        var episodeResolver = new Naming.TV.EpisodeResolver(namingOptions);

                        var episodeInfo = episodeResolver.Resolve(fullName, false, true, false, fillExtendedInfo: false);
                        if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
                        {
                            return(true);
                        }
                    }
                }
            }

            logger.LogDebug("{Path} is not a series folder.", path);
            return(false);
        }
Exemple #4
0
        private bool IsSeriesFolder(
            string path,
            IEnumerable <FileSystemMetadata> fileSystemChildren,
            bool isTvContentType)
        {
            foreach (var child in fileSystemChildren)
            {
                if (child.IsDirectory)
                {
                    if (IsSeasonFolder(child.FullName, isTvContentType))
                    {
                        _logger.LogDebug("{Path} is a series because of season folder {Dir}.", path, child.FullName);
                        return(true);
                    }
                }
                else
                {
                    string fullName = child.FullName;
                    if (VideoResolver.IsVideoFile(path, _namingOptions))
                    {
                        if (isTvContentType)
                        {
                            return(true);
                        }

                        var namingOptions = _namingOptions;

                        var episodeResolver = new Naming.TV.EpisodeResolver(namingOptions);

                        var episodeInfo = episodeResolver.Resolve(fullName, false, true, false, fillExtendedInfo: false);
                        if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
                        {
                            return(true);
                        }
                    }
                }
            }

            _logger.LogDebug("{Path} is not a series folder.", path);
            return(false);
        }
Exemple #5
0
        public async Task <FileOrganizationResult> OrganizeEpisodeFile(string path, TvFileOrganizationOptions options, bool overwriteExisting, CancellationToken cancellationToken)
        {
            _logger.Info("Sorting file {0}", path);

            var result = new FileOrganizationResult
            {
                Date             = DateTime.UtcNow,
                OriginalPath     = path,
                OriginalFileName = Path.GetFileName(path),
                Type             = FileOrganizerType.Episode,
                FileSize         = new FileInfo(path).Length
            };

            var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
            var resolver      = new Naming.TV.EpisodeResolver(namingOptions, new Naming.Logging.NullLogger());

            var episodeInfo = resolver.Resolve(path, FileInfoType.File) ??
                              new Naming.TV.EpisodeInfo();

            var seriesName = episodeInfo.SeriesName;

            if (!string.IsNullOrEmpty(seriesName))
            {
                var season = episodeInfo.SeasonNumber;

                result.ExtractedSeasonNumber = season;

                if (season.HasValue)
                {
                    // Passing in true will include a few extra regex's
                    var episode = episodeInfo.EpisodeNumber;

                    result.ExtractedEpisodeNumber = episode;

                    if (episode.HasValue)
                    {
                        _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode);

                        var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;

                        result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;

                        await OrganizeEpisode(path, seriesName, season.Value, episode.Value, endingEpisodeNumber, options, overwriteExisting, result, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        var msg = string.Format("Unable to determine episode number from {0}", path);
                        result.Status        = FileSortingStatus.Failure;
                        result.StatusMessage = msg;
                        _logger.Warn(msg);
                    }
                }
                else
                {
                    var msg = string.Format("Unable to determine season number from {0}", path);
                    result.Status        = FileSortingStatus.Failure;
                    result.StatusMessage = msg;
                    _logger.Warn(msg);
                }
            }
            else
            {
                var msg = string.Format("Unable to determine series name from {0}", path);
                result.Status        = FileSortingStatus.Failure;
                result.StatusMessage = msg;
                _logger.Warn(msg);
            }

            var previousResult = _organizationService.GetResultBySourcePath(path);

            if (previousResult != null)
            {
                // Don't keep saving the same result over and over if nothing has changed
                if (previousResult.Status == result.Status && result.Status != FileSortingStatus.Success)
                {
                    return(previousResult);
                }
            }

            await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);

            return(result);
        }
        public async Task<FileOrganizationResult> OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken)
        {
            _logger.Info("Sorting file {0}", path);

            var result = new FileOrganizationResult
            {
                Date = DateTime.UtcNow,
                OriginalPath = path,
                OriginalFileName = Path.GetFileName(path),
                Type = FileOrganizerType.Episode,
                FileSize = new FileInfo(path).Length
            };

            if (_libraryMonitor.IsPathLocked(path))
            {
                result.Status = FileSortingStatus.Failure;
                result.StatusMessage = "Path is locked by other processes. Please try again later.";
                return result;
            }

            var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
            var resolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger());

            var episodeInfo = resolver.Resolve(path, false) ??
                new Naming.TV.EpisodeInfo();

            var seriesName = episodeInfo.SeriesName;

            if (!string.IsNullOrEmpty(seriesName))
            {
                var seasonNumber = episodeInfo.SeasonNumber;

                result.ExtractedSeasonNumber = seasonNumber;

                // Passing in true will include a few extra regex's
                var episodeNumber = episodeInfo.EpisodeNumber;

                result.ExtractedEpisodeNumber = episodeNumber;

                var premiereDate = episodeInfo.IsByDate ?
                    new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
                    (DateTime?)null;

                if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue))
                {
                    if (episodeInfo.IsByDate)
                    {
                        _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value);
                    }
                    else
                    {
                        _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber);
                    }

                    var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;

                    result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;

                    await OrganizeEpisode(path,
                        seriesName,
                        seasonNumber,
                        episodeNumber,
                        endingEpisodeNumber,
                        premiereDate,
                        options,
                        overwriteExisting,
                        false,
                        result,
                        cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    var msg = string.Format("Unable to determine episode number from {0}", path);
                    result.Status = FileSortingStatus.Failure;
                    result.StatusMessage = msg;
                    _logger.Warn(msg);
                }
            }
            else
            {
                var msg = string.Format("Unable to determine series name from {0}", path);
                result.Status = FileSortingStatus.Failure;
                result.StatusMessage = msg;
                _logger.Warn(msg);
            }

            var previousResult = _organizationService.GetResultBySourcePath(path);

            if (previousResult != null)
            {
                // Don't keep saving the same result over and over if nothing has changed
                if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
                {
                    return previousResult;
                }
            }

            await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);

            return result;
        }
        public async Task <FileOrganizationResult> OrganizeEpisodeFile(string path, AutoOrganizeOptions options, bool overwriteExisting, CancellationToken cancellationToken)
        {
            _logger.Info("Sorting file {0}", path);

            var result = new FileOrganizationResult
            {
                Date             = DateTime.UtcNow,
                OriginalPath     = path,
                OriginalFileName = Path.GetFileName(path),
                Type             = FileOrganizerType.Episode,
                FileSize         = new FileInfo(path).Length
            };

            if (_libraryMonitor.IsPathLocked(path))
            {
                result.Status        = FileSortingStatus.Failure;
                result.StatusMessage = "Path is locked by other processes. Please try again later.";
                return(result);
            }

            var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
            var resolver      = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger());

            var episodeInfo = resolver.Resolve(path, false) ??
                              new Naming.TV.EpisodeInfo();

            var seriesName = episodeInfo.SeriesName;

            if (!string.IsNullOrEmpty(seriesName))
            {
                var seasonNumber = episodeInfo.SeasonNumber;

                result.ExtractedSeasonNumber = seasonNumber;

                // Passing in true will include a few extra regex's
                var episodeNumber = episodeInfo.EpisodeNumber;

                result.ExtractedEpisodeNumber = episodeNumber;

                var premiereDate = episodeInfo.IsByDate ?
                                   new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
                                   (DateTime?)null;

                if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue))
                {
                    if (episodeInfo.IsByDate)
                    {
                        _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value);
                    }
                    else
                    {
                        _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber);
                    }

                    var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;

                    result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;

                    await OrganizeEpisode(path,
                                          seriesName,
                                          seasonNumber,
                                          episodeNumber,
                                          endingEpisodeNumber,
                                          premiereDate,
                                          options,
                                          overwriteExisting,
                                          false,
                                          result,
                                          cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    var msg = string.Format("Unable to determine episode number from {0}", path);
                    result.Status        = FileSortingStatus.Failure;
                    result.StatusMessage = msg;
                    _logger.Warn(msg);
                }
            }
            else
            {
                var msg = string.Format("Unable to determine series name from {0}", path);
                result.Status        = FileSortingStatus.Failure;
                result.StatusMessage = msg;
                _logger.Warn(msg);
            }

            var previousResult = _organizationService.GetResultBySourcePath(path);

            if (previousResult != null)
            {
                // Don't keep saving the same result over and over if nothing has changed
                if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
                {
                    return(previousResult);
                }
            }

            await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);

            return(result);
        }
Exemple #8
0
        public static bool IsSeriesFolder(string path,
                                          IEnumerable <FileSystemInfo> fileSystemChildren,
                                          IDirectoryService directoryService,
                                          IFileSystem fileSystem,
                                          ILogger logger,
                                          ILibraryManager libraryManager,
                                          bool isTvContentType)
        {
            foreach (var child in fileSystemChildren)
            {
                var attributes = child.Attributes;

                if ((attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                {
                    //logger.Debug("Igoring series file or folder marked hidden: {0}", child.FullName);
                    continue;
                }

                // Can't enforce this because files saved by Bitcasa are always marked System
                //if ((attributes & FileAttributes.System) == FileAttributes.System)
                //{
                //    logger.Debug("Igoring series subfolder marked system: {0}", child.FullName);
                //    continue;
                //}

                if ((attributes & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    if (IsSeasonFolder(child.FullName, isTvContentType))
                    {
                        //logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
                        return(true);
                    }
                }
                else
                {
                    string fullName = child.FullName;
                    if (libraryManager.IsVideoFile(fullName))
                    {
                        if (isTvContentType)
                        {
                            return(true);
                        }

                        var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions();

                        // In mixed folders we need to be conservative and avoid expressions that may result in false positives (e.g. movies with numbers in the title)
                        if (!isTvContentType)
                        {
                            namingOptions.EpisodeExpressions = namingOptions.EpisodeExpressions
                                                               .Where(i => i.IsNamed && !i.IsOptimistic)
                                                               .ToList();
                        }

                        var episodeResolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger());
                        var episodeInfo     = episodeResolver.Resolve(fullName, false, false);
                        if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
                        {
                            return(true);
                        }
                    }
                }
            }

            logger.Debug("{0} is not a series folder.", path);
            return(false);
        }