コード例 #1
0
        public FileOrganizationResult OrganizeWithCorrection(MovieFileOrganizationRequest request, MovieFileOrganizationOptions options, CancellationToken cancellationToken)
        {
            var result = _organizationService.GetResult(request.ResultId);

            try
            {
                Movie movie = null;

                if (request.NewMovieProviderIds.Count > 0)
                {
                    BaseItem targetFolder = null;

                    if (!string.IsNullOrEmpty(options.DefaultMovieLibraryPath))
                    {
                        targetFolder = _libraryManager.FindByPath(options.DefaultMovieLibraryPath, true);
                    }

                    // To avoid Series duplicate by mistake (Missing SmartMatch and wrong selection in UI)
                    movie = CreateNewMovie(request, targetFolder, result, options, cancellationToken);
                }

                if (movie == null)
                {
                    // Existing movie
                    movie = (Movie)_libraryManager.GetItemById(request.MovieId);
                    var newPath      = GetMoviePath(result.OriginalPath, movie, options);
                    var targetFolder = _libraryManager
                                       .GetVirtualFolders()
                                       .Where(i => string.Equals(i.CollectionType, CollectionType.Movies.ToString(), StringComparison.OrdinalIgnoreCase))
                                       .FirstOrDefault()
                                       .Locations
                                       .Where(i => movie.Path.Contains(i))
                                       .FirstOrDefault();
                    movie.Path = Path.Combine(targetFolder, newPath);
                }

                // We manually set the media as Movie
                result.Type = CurrentFileOrganizerType;

                OrganizeMovie(result.OriginalPath,
                              movie,
                              options,
                              null,
                              result,
                              cancellationToken);

                _organizationService.SaveResult(result, CancellationToken.None);
            }
            catch (Exception ex)
            {
                result.Status        = FileSortingStatus.Failure;
                result.StatusMessage = ex.Message;
                _logger.ErrorException("Error organizing file {0}", ex, result.OriginalPath);
            }

            return(result);
        }
コード例 #2
0
        private async Task <Series> AutoDetectSeries(
            string seriesName,
            int?seriesYear,
            TvFileOrganizationOptions options,
            CancellationToken cancellationToken)
        {
            if (options.AutoDetectSeries)
            {
                string   metadataLanguage    = null;
                string   metadataCountryCode = null;
                BaseItem targetFolder        = null;

                if (!string.IsNullOrEmpty(options.DefaultSeriesLibraryPath))
                {
                    targetFolder = _libraryManager.FindByPath(options.DefaultSeriesLibraryPath, true);
                }

                if (targetFolder != null)
                {
                    metadataLanguage    = targetFolder.GetPreferredMetadataLanguage();
                    metadataCountryCode = targetFolder.GetPreferredMetadataCountryCode();
                }

                var seriesInfo = new SeriesInfo
                {
                    Name = seriesName,
                    Year = seriesYear,
                    MetadataCountryCode = metadataCountryCode,
                    MetadataLanguage    = metadataLanguage
                };

                var searchResultsTask = await _providerManager.GetRemoteSearchResults <Series, SeriesInfo>(new RemoteSearchQuery <SeriesInfo>
                {
                    SearchInfo = seriesInfo
                }, targetFolder, cancellationToken);

                var finalResult = searchResultsTask.FirstOrDefault();

                if (finalResult != null)
                {
                    // We are in the good position, we can create the item
                    var organizationRequest = new EpisodeFileOrganizationRequest
                    {
                        NewSeriesName        = finalResult.Name,
                        NewSeriesProviderIds = finalResult.ProviderIds,
                        NewSeriesYear        = finalResult.ProductionYear,
                        TargetFolder         = options.DefaultSeriesLibraryPath
                    };

                    return(CreateNewSeries(organizationRequest, targetFolder, finalResult, options, cancellationToken));
                }
            }

            return(null);
        }
コード例 #3
0
        /// <summary>
        /// Gets the affected base item.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>BaseItem.</returns>
        private BaseItem GetAffectedBaseItem(string path)
        {
            BaseItem item = null;

            while (item == null && !string.IsNullOrEmpty(path))
            {
                item = _libraryManager.FindByPath(path, null);

                path = System.IO.Path.GetDirectoryName(path);
            }

            if (item != null)
            {
                // If the item has been deleted find the first valid parent that still exists
                while (!Directory.Exists(item.Path) && !File.Exists(item.Path))
                {
                    item = item.GetOwner() ?? item.GetParent();

                    if (item == null)
                    {
                        break;
                    }
                }
            }

            return(item);
        }
コード例 #4
0
        public async Task <IEnumerable <RemoteSubtitleInfo> > Search(SubtitleSearchRequest request, CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                var json = _jsonSerializer.SerializeToString(request);
                _logger.Debug($"SubdivX Search | Request-> {json}");
            });

            _logger.Debug($"SubdivX Search | UseOriginalTitle-> {_configuration?.UseOriginalTitle}");

            if (!string.Equals(request.TwoLetterISOLanguageName, "ES", StringComparison.OrdinalIgnoreCase))
            {
                return(Array.Empty <RemoteSubtitleInfo>());
            }

            var item = _libraryManager.FindByPath(request.MediaPath, false);

            if (request.ContentType == VideoContentType.Episode)
            {
                var name = request.SeriesName;

                if (_configuration?.UseOriginalTitle == true)
                {
                    if (!string.IsNullOrWhiteSpace(item.OriginalTitle))
                    {
                        name = item.OriginalTitle;
                    }
                }

                var query = $"{name} S{request.ParentIndexNumber:D2}E{request.IndexNumber:D2}";

                var subtitles = SearchSubtitles(query);
                if (subtitles?.Count > 0)
                {
                    return(subtitles);
                }
            }
            else
            {
                var name = request.Name;
                if (_configuration?.UseOriginalTitle == true)
                {
                    if (!string.IsNullOrWhiteSpace(item.OriginalTitle))
                    {
                        name = item.OriginalTitle;
                    }
                }

                var query = $"{name} {request.ProductionYear}";

                var subtitles = SearchSubtitles(query);
                if (subtitles?.Count > 0)
                {
                    return(subtitles);
                }
            }

            return(Array.Empty <RemoteSubtitleInfo>());
        }
コード例 #5
0
        public async Task <IEnumerable <RemoteSubtitleInfo> > Search(SubtitleSearchRequest request, CancellationToken cancellationToken)
        {
            var lang = _localizationManager.FindLanguageInfo(request.Language.AsSpan());

            if (request.IsForced.HasValue || request.IsPerfectMatch || GetLanguageId(lang) == null)
            {
                return(Array.Empty <RemoteSubtitleInfo>());
            }

            if (await Login())
            {
                BaseItem        item         = _libraryManager.FindByPath(request.MediaPath, false);
                var             legendatvIds = FindIds(request, item, cancellationToken);
                var             searchTasks  = new List <Task <IEnumerable <RemoteSubtitleInfo> > >();
                Action <string> addSearchTask;
                switch (request.ContentType)
                {
                // Series Episode
                case VideoContentType.Episode:
                {
                    addSearchTask = (id) =>
                    {
                        searchTasks.Add(Search(item.Id, cancellationToken, itemId: id, lang: lang, query: $"S{request.ParentIndexNumber:D02}E{request.IndexNumber:D02}"));
                        searchTasks.Add(Search(item.Id, cancellationToken, itemId: id, lang: lang, query: $"{request.ParentIndexNumber:D02}x{request.IndexNumber:D02}"));
                    };
                    break;
                }

                // Movie
                default:
                case VideoContentType.Movie:
                {
                    addSearchTask = (id) =>
                    {
                        searchTasks.Add(Search(item.Id, cancellationToken, lang: lang, itemId: id));
                    };

                    break;
                }
                }

                foreach (var id in legendatvIds)
                {
                    addSearchTask(id);
                }

                await Task.WhenAll(searchTasks);

                return(searchTasks.SelectMany(t => t.Result));
            }
            else
            {
                return(Array.Empty <RemoteSubtitleInfo>());
            }
        }
コード例 #6
0
        public static SearchInfo GetSearchInfo(
            SubtitleSearchRequest request,
            ILocalizationManager localize,
            ILibraryManager lib,
            string episode_format = "",
            string season_format  = "",
            Dictionary <string, string> inconsistentTvs    = null,
            Dictionary <string, string> inconsistentMovies = null
            )
        {
            var res = new SearchInfo();

            res.VideoType = request.ContentType;

#if EMBY
            res.LanguageInfo = localize.FindLanguageInfo(request.Language.AsSpan());
#else
            res.LanguageInfo = localize.FindLanguageInfo(request.Language);
#endif
            res.Lang = res.LanguageInfo.TwoLetterISOLanguageName.ToLower();

            BaseItem libItem = lib.FindByPath(request.MediaPath, false);
            if (libItem == null)
            {
                return(res);
            }

            if (res.VideoType == VideoContentType.Movie)
            {
                Movie       mv    = libItem as Movie;
                MediaStream media = mv.GetDefaultVideoStream();
                if (media != null)
                {
                    res.VideoFps = media.AverageFrameRate;
                }

                res.SearchText = !String.IsNullOrEmpty(mv.OriginalTitle) ? mv.OriginalTitle : mv.Name;
                if (inconsistentMovies != null)
                {
                    res.SearchText = inconsistentMovies.Aggregate(res.SearchText, (current, value) =>
                                                                  Regex.Replace(current, Regex.Escape(value.Key), value.Value, RegexOptions.IgnoreCase));
                }

                mv.ProviderIds.TryGetValue("Imdb", out res.ImdbId);

                res.TitleMovie = res.SearchText;
                res.MvInfo     = Parser.Movie.ParsePath(mv.Path);
                if (res.MvInfo != null && res.MvInfo.Year == 0)
                {
                    res.MvInfo.Year = request.ProductionYear ?? 0;
                }
            }
            else
            if (res.VideoType == VideoContentType.Episode && !String.IsNullOrEmpty(episode_format))
            {
                res.SeasonNumber  = request.ParentIndexNumber;
                res.EpisodeNumber = request.IndexNumber;

                Episode     ep    = libItem as Episode;
                MediaStream media = ep.GetDefaultVideoStream();
                if (media != null)
                {
                    res.VideoFps = media.AverageFrameRate;
                }

                string title = !String.IsNullOrEmpty(ep.Series.OriginalTitle) ? ep.Series.OriginalTitle : ep.Series.Name;
                if (inconsistentTvs != null)
                {
                    title = inconsistentTvs.Aggregate(title, (current, value) =>
                                                      Regex.Replace(current, Regex.Escape(value.Key), value.Value, RegexOptions.IgnoreCase));
                }

                // episode format {0} - series name, {1} - season, {2} - episode
                if (res.SeasonNumber != null && res.EpisodeNumber != null)
                {
                    res.SearchText = String.Format(episode_format,
                                                   title,
                                                   res.SeasonNumber,
                                                   res.EpisodeNumber);
                }

                // season format {0} - series name, {1} - season
                if (res.SeasonNumber != null)
                {
                    res.SearchSeason = String.Format(season_format,
                                                     title,
                                                     res.SeasonNumber);
                }

                string titleEp = !String.IsNullOrEmpty(ep.OriginalTitle) ? ep.OriginalTitle : ep.Name;
                if (titleEp.ContainsIgnoreCase(title))
                {
                    res.SearchEpByName = titleEp;
                }
                else
                {
                    res.SearchEpByName = String.Format("{0} {1}", title, titleEp);
                }

                ep.Series.ProviderIds.TryGetValue("Imdb", out res.ImdbId);
                ep.ProviderIds.TryGetValue("Imdb", out res.ImdbIdEpisode);

                res.TitleSeries = title;
                res.TitleMovie  = res.SearchEpByName;
                res.EpInfo      = Parser.Episode.ParsePath(ep.Path);
                if (res.EpInfo != null && res.EpInfo.SeriesTitleInfo.Year == 0)
                {
                    res.EpInfo.SeriesTitleInfo.Year = request.ProductionYear ?? 0;
                }
            }

            res.SearchText     = res.SearchText.Replace(':', ' ').Replace("  ", " ");
            res.SearchEpByName = res.SearchEpByName.Replace(':', ' ').Replace("  ", " ");

            var regexImdbId = new Regex(@"tt(\d+)");

            if (!String.IsNullOrWhiteSpace(res.ImdbId))
            {
                var match = regexImdbId.Match(res.ImdbId);
                if (match.Success && match.Groups.Count > 1)
                {
                    res.ImdbIdInt = int.Parse(match.Groups[1].ToString());
                }
            }

            if (!String.IsNullOrWhiteSpace(res.ImdbIdEpisode))
            {
                var match = regexImdbId.Match(res.ImdbIdEpisode);
                if (match.Success && match.Groups.Count > 1)
                {
                    res.ImdbIdEpisodeInt = int.Parse(match.Groups[1].ToString());
                }
            }

            res.Year = request.ProductionYear;

            return(res);
        }