Beispiel #1
0
        private async Task <bool> DownloadImage(BaseItem item, LibraryOptions libraryOptions,
                                                IRemoteImageProvider provider,
                                                RefreshResult result,
                                                IEnumerable <RemoteImageInfo> images,
                                                int minWidth,
                                                ImageType type,
                                                CancellationToken cancellationToken)
        {
            var eligibleImages = images
                                 .Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth))
                                 .ToList();

            if (EnableImageStub(item, type, libraryOptions) && eligibleImages.Count > 0)
            {
                SaveImageStub(item, type, eligibleImages.Select(i => i.Url));
                result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
                return(true);
            }

            foreach (var image in eligibleImages)
            {
                var url = image.Url;

                try
                {
                    var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false);

                    await _providerManager.SaveImage(item, response.Content, response.ContentType, type, null, cancellationToken).ConfigureAwait(false);

                    result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
                    return(true);
                }
                catch (HttpException ex)
                {
                    // Sometimes providers send back bad url's. Just move to the next image
                    if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
                    {
                        continue;
                    }
                    break;
                }
            }

            return(false);
        }
        public Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var infos = new List <RemoteImageInfo>();

            var person = AniDbSeriesProvider.GetPersonInfo(_paths.CachePath, item.Name);

            if (person != null)
            {
                infos.Add(new RemoteImageInfo
                {
                    Url          = person.Image,
                    Type         = ImageType.Primary,
                    ProviderName = Name
                });
            }

            return(Task.FromResult <IEnumerable <RemoteImageInfo> >(infos));
        }
Beispiel #3
0
        public static void SaveLibraryOptions(string path, LibraryOptions options)
        {
            lock (LibraryOptions)
            {
                LibraryOptions[path] = options;

                var clone = JsonSerializer.Deserialize <LibraryOptions>(JsonSerializer.SerializeToUtf8Bytes(options, _jsonOptions), _jsonOptions);
                foreach (var mediaPath in clone.PathInfos)
                {
                    if (!string.IsNullOrEmpty(mediaPath.Path))
                    {
                        mediaPath.Path = ApplicationHost.ReverseVirtualPath(mediaPath.Path);
                    }
                }

                XmlSerializer.SerializeToFile(clone, GetLibraryOptionsPath(path));
            }
        }
Beispiel #4
0
        public Task Save(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var path           = GetSavePath(item);
            var serializeditem = SerializeItem(item, ConfigurationManager, LibraryManager);
            var options        = new JsonSerializerOptions
            {
                WriteIndented = true,
                Encoder       = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            };

            options.Converters.Add(new DateTimeConverter("yyyy-MM-dd"));
            var json = JsonSerializer.Serialize(serializeditem, serializeditem.GetType(), options);

            FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path));
            FileSystem.SetAttributes(path, false, false);
            File.WriteAllText(path, json);
            return(Task.CompletedTask);
        }
Beispiel #5
0
        public async Task<RefreshResult> RefreshImages(BaseItem item, LibraryOptions libraryOptions, List<IImageProvider> providers, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken)
        {
            if (refreshOptions.IsReplacingImage(ImageType.Backdrop))
            {
                ClearImages(item, ImageType.Backdrop);
            }
            if (refreshOptions.IsReplacingImage(ImageType.Screenshot))
            {
                ClearImages(item, ImageType.Screenshot);
            }

            var result = new RefreshResult { UpdateType = ItemUpdateType.None };

            var providerIds = new List<Guid>();

            // In order to avoid duplicates, only download these if there are none already
            var backdropLimit = savedOptions.GetLimit(ImageType.Backdrop);
            var screenshotLimit = savedOptions.GetLimit(ImageType.Screenshot);
            var downloadedImages = new List<ImageType>();

            foreach (var provider in providers)
            {
                var remoteProvider = provider as IRemoteImageProvider;

                if (remoteProvider != null)
                {
                    await RefreshFromProvider(item, libraryOptions, remoteProvider, refreshOptions, savedOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
                    providerIds.Add(provider.GetType().FullName.GetMD5());
                    continue;
                }

                var dynamicImageProvider = provider as IDynamicImageProvider;

                if (dynamicImageProvider != null)
                {
                    await RefreshFromProvider(item, dynamicImageProvider, refreshOptions, savedOptions, downloadedImages, result, cancellationToken).ConfigureAwait(false);
                    providerIds.Add(provider.GetType().FullName.GetMD5());
                }
            }

            result.Providers = providerIds;

            return result;
        }
        private bool EnableImageStub(IHasImages item, ImageType type, LibraryOptions libraryOptions)
        {
            if (item is LiveTvProgram)
            {
                return(true);
            }

            if (libraryOptions.DownloadImagesInAdvance)
            {
                return(false);
            }

            if (item.LocationType == LocationType.Remote || item.LocationType == LocationType.Virtual)
            {
                return(true);
            }

            if (!item.IsSaveLocalMetadataEnabled())
            {
                return(true);
            }

            if (item is IItemByName && !(item is MusicArtist))
            {
                var hasDualAccess = item as IHasDualAccess;
                if (hasDualAccess == null || hasDualAccess.IsAccessedByName)
                {
                    return(true);
                }
            }

            switch (type)
            {
            case ImageType.Primary:
                return(false);

            case ImageType.Thumb:
                return(false);

            default:
                return(true);
            }
        }
        public List <LocalImageInfo> GetImages(BaseItem item, LibraryOptions libraryOptions, IDirectoryService directoryService)
        {
            var parentPath = _fileSystem.GetDirectoryName(item.Path);

            var parentPathFiles = directoryService.GetFileSystemEntries(parentPath)
                                  .ToList();

            var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(item.Path);

            var metadataPath = Path.Combine(parentPath, "metadata");

            if (parentPathFiles.Any(i => string.Equals(i.FullName, metadataPath, StringComparison.OrdinalIgnoreCase)))
            {
                var filesInMetadataFolder = _fileSystem.GetFiles(metadataPath, BaseItem.SupportedImageExtensions, false, false);
                return(GetFilesFromParentFolder(nameWithoutExtension, filesInMetadataFolder));
            }

            return(new List <LocalImageInfo>());
        }
Beispiel #8
0
        private async Task SavePeopleMetadataAsync(List <PersonInfo> people, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            foreach (var person in people)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (person.ProviderIds.Count > 0 || !string.IsNullOrWhiteSpace(person.ImageUrl))
                {
                    var updateType = ItemUpdateType.MetadataDownload;

                    var saveEntity   = false;
                    var personEntity = LibraryManager.GetPerson(person.Name);
                    foreach (var id in person.ProviderIds)
                    {
                        if (!string.Equals(personEntity.GetProviderId(id.Key), id.Value, StringComparison.OrdinalIgnoreCase))
                        {
                            personEntity.SetProviderId(id.Key, id.Value);
                            saveEntity = true;
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary))
                    {
                        personEntity.SetImage(
                            new ItemImageInfo
                        {
                            Path = person.ImageUrl,
                            Type = ImageType.Primary
                        },
                            0);

                        saveEntity  = true;
                        updateType |= ItemUpdateType.ImageUpdate;
                    }

                    if (saveEntity)
                    {
                        await personEntity.UpdateToRepositoryAsync(updateType, cancellationToken).ConfigureAwait(false);
                    }
                }
            }
        }
Beispiel #9
0
        public Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var list = new List <RemoteImageInfo>();

            if (!string.IsNullOrEmpty(item.GetProviderId(Name)))
            {
                var cachePath = Path.Combine(_appPaths.CachePath, "douban", item.GetProviderId(Name), "image.txt");
                if (File.Exists(cachePath))
                {
                    var image = new RemoteImageInfo
                    {
                        ProviderName = Name,
                        Url          = File.ReadAllText(cachePath),
                        Type         = ImageType.Primary
                    };
                    list.Add(image);
                }
            }
            return(Task.FromResult <IEnumerable <RemoteImageInfo> >(list));
        }
Beispiel #10
0
        public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var list = new List <RemoteImageInfo>();

            var series = (Series)item;

            var id = series.GetProviderId(MetadataProviders.Tvdb);

            if (!string.IsNullOrEmpty(id))
            {
                // Bad id entered
                try
                {
                    await EnsureSeriesJson(id, cancellationToken).ConfigureAwait(false);
                }
                catch (HttpException ex)
                {
                    if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound)
                    {
                        throw;
                    }
                }

                var path = GetFanartJsonPath(id);

                try
                {
                    AddImages(list, path, cancellationToken);
                }
                catch (FileNotFoundException)
                {
                    // No biggie. Don't blow up
                }
                catch (IOException)
                {
                    // No biggie. Don't blow up
                }
            }

            return(list);
        }
Beispiel #11
0
        private void AddPersonImage(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken)
        {
            //if (libraryOptions.DownloadImagesInAdvance)
            //{
            //    try
            //    {
            //        await ProviderManager.SaveImage(personEntity, imageUrl, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);
            //        return;
            //    }
            //    catch (Exception ex)
            //    {
            //        Logger.LogError(ex, "Error in AddPersonImage");
            //    }
            //}

            personEntity.SetImage(new ItemImageInfo
            {
                Path = imageUrl,
                Type = ImageType.Primary
            }, 0);
        }
Beispiel #12
0
        private bool CanRefresh(
            IMetadataProvider provider,
            BaseItem item,
            LibraryOptions libraryOptions,
            bool includeDisabled,
            bool forceEnableInternetMetadata)
        {
            if (!includeDisabled)
            {
                // If locked only allow local providers
                if (item.IsLocked && !(provider is ILocalMetadataProvider) && !(provider is IForcedProvider))
                {
                    return(false);
                }

                if (provider is IRemoteMetadataProvider)
                {
                    if (!forceEnableInternetMetadata && !_baseItemManager.IsMetadataFetcherEnabled(item, libraryOptions, provider.Name))
                    {
                        return(false);
                    }
                }
            }

            if (!item.SupportsLocalMetadata && provider is ILocalMetadataProvider)
            {
                return(false);
            }

            // If this restriction is ever lifted, movie xml providers will have to be updated to prevent owned items like trailers from reading those files
            if (!item.OwnerId.Equals(Guid.Empty))
            {
                if (provider is ILocalMetadataProvider || provider is IRemoteMetadataProvider)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #13
0
        private async Task AddPersonImage(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken)
        {
            if (libraryOptions.DownloadImagesInAdvance)
            {
                try
                {
                    await ProviderManager.SaveImage(personEntity, imageUrl, ImageType.Primary, null, cancellationToken).ConfigureAwait(false);

                    return;
                }
                catch (Exception ex)
                {
                    Logger.ErrorException("Error in AddPersonImage", ex);
                }
            }

            personEntity.SetImage(new ItemImageInfo
            {
                Path = imageUrl,
                Type = ImageType.Primary
            }, 0);
        }
        public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var list = new List <RemoteImageInfo>();

            var series = (Series)item;

            var idType   = "imdb";
            var seriesId = series.GetProviderId(MetadataProviders.Imdb);

            if (string.IsNullOrEmpty(seriesId))
            {
                idType   = "tmdb";
                seriesId = string.Format(BaseTmdbId, series.GetProviderId(MetadataProviders.Tmdb));
            }

            if (string.IsNullOrEmpty(seriesId))
            {
                idType   = "tvdb";
                seriesId = series.GetProviderId(MetadataProviders.Tvdb);
            }

            if (!string.IsNullOrEmpty(seriesId))
            {
                try
                {
                    await AddImages(list, idType, seriesId, cancellationToken).ConfigureAwait(false);
                }
                catch (FileNotFoundException)
                {
                    // No biggie. Don't blow up
                }
                catch (IOException)
                {
                    // No biggie. Don't blow up
                }
            }

            return(list);
        }
Beispiel #15
0
        private bool EnableImageStub(BaseItem item, LibraryOptions libraryOptions)
        {
            if (item is LiveTvProgram)
            {
                return(true);
            }

            if (!item.IsFileProtocol)
            {
                return(true);
            }

            if (item is IItemByName && !(item is MusicArtist))
            {
                var hasDualAccess = item as IHasDualAccess;
                if (hasDualAccess == null || hasDualAccess.IsAccessedByName)
                {
                    return(true);
                }
            }
            // We always want to use prefetched images
            return(false);
        }
Beispiel #16
0
        public async Task <MetadataResult <T> > GetMetadata(ItemInfo info,
                                                            LibraryOptions libraryOptions,
                                                            IDirectoryService directoryService,
                                                            CancellationToken cancellationToken)
        {
            var result = new MetadataResult <T>();

            var file = GetXmlFile(info, directoryService);

            if (file == null)
            {
                return(result);
            }

            var path = file.FullName;

            Logger.Debug("{0} will fetch xml from {1}", GetType().Name, path);

            try
            {
                result.Item = new T();

                await Fetch(result, path, cancellationToken).ConfigureAwait(false);

                result.HasMetadata = true;
            }
            catch (FileNotFoundException)
            {
                result.HasMetadata = false;
            }
            catch (IOException)
            {
                result.HasMetadata = false;
            }

            return(result);
        }
Beispiel #17
0
        private bool CanRefresh(
            IImageProvider provider,
            BaseItem item,
            LibraryOptions libraryOptions,
            ImageRefreshOptions refreshOptions,
            bool includeDisabled)
        {
            if (!includeDisabled)
            {
                // If locked only allow local providers
                if (item.IsLocked && !(provider is ILocalImageProvider))
                {
                    if (refreshOptions.ImageRefreshMode != MetadataRefreshMode.FullRefresh)
                    {
                        return(false);
                    }
                }

                if (provider is IRemoteImageProvider || provider is IDynamicImageProvider)
                {
                    if (!_baseItemManager.IsImageFetcherEnabled(item, libraryOptions, provider.Name))
                    {
                        return(false);
                    }
                }
            }

            try
            {
                return(provider.Supports(item));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "{ProviderName} failed in Supports for type {ItemType} at {ItemPath}", provider.GetType().Name, item.GetType().Name, item.Path);
                return(false);
            }
        }
Beispiel #18
0
        public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            _logger.LogCallerInfo($"[DOUBAN] GetImages for item: {item.Name}");

            var list = new List <RemoteImageInfo>();
            var sid  = item.GetProviderId(ProviderID);

            if (string.IsNullOrWhiteSpace(sid))
            {
                _logger.LogCallerInfo($"[DOUBAN] Got images failed because the sid of \"{item.Name}\" is empty!");
                return(list);
            }

            var primaryList = await GetPrimary(sid, item is Movie? "movie" : "tv", cancellationToken);

            list.AddRange(primaryList);

            // TODO(Libitum): Add backdrop back.
            var backdropList = await GetBackdrop(sid, cancellationToken);

            list.AddRange(backdropList);

            return(list);
        }
Beispiel #19
0
        private void SavePeopleMetadata(List <PersonInfo> people, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            foreach (var person in people)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (person.ProviderIds.Any() || !string.IsNullOrWhiteSpace(person.ImageUrl))
                {
                    var updateType = ItemUpdateType.MetadataDownload;

                    var saveEntity   = false;
                    var personEntity = LibraryManager.GetPerson(person.Name);
                    foreach (var id in person.ProviderIds)
                    {
                        if (!string.Equals(personEntity.GetProviderId(id.Key), id.Value, StringComparison.OrdinalIgnoreCase))
                        {
                            personEntity.SetProviderId(id.Key, id.Value);
                            saveEntity = true;
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary))
                    {
                        AddPersonImage(personEntity, libraryOptions, person.ImageUrl, cancellationToken);

                        saveEntity = true;
                        updateType = updateType | ItemUpdateType.ImageUpdate;
                    }

                    if (saveEntity)
                    {
                        personEntity.UpdateToRepository(updateType, cancellationToken);
                    }
                }
            }
        }
        public Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var seriesId = item.GetProviderId(ProviderNames.AniList);

            return(GetImages(seriesId, cancellationToken));
        }
Beispiel #21
0
        private IEnumerable <IMetadataProvider <T> > GetMetadataProvidersInternal <T>(BaseItem item, LibraryOptions libraryOptions, MetadataOptions globalMetadataOptions, bool includeDisabled, bool forceEnableInternetMetadata)
            where T : BaseItem
        {
            // Avoid implicitly captured closure
            var currentOptions = globalMetadataOptions;

            return(_metadataProviders.OfType <IMetadataProvider <T> >()
                   .Where(i => CanRefresh(i, item, libraryOptions, includeDisabled, forceEnableInternetMetadata))
                   .OrderBy(i => GetConfiguredOrder(item, i, libraryOptions, globalMetadataOptions))
                   .ThenBy(GetDefaultOrder));
        }
Beispiel #22
0
        /// <summary>
        /// Gets the metadata providers for the provided item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="libraryOptions">The library options.</param>
        /// <typeparam name="T">The type of metadata provider.</typeparam>
        /// <returns>The metadata providers.</returns>
        public IEnumerable <IMetadataProvider <T> > GetMetadataProviders <T>(BaseItem item, LibraryOptions libraryOptions)
            where T : BaseItem
        {
            var globalMetadataOptions = GetMetadataOptions(item);

            return(GetMetadataProvidersInternal <T>(item, libraryOptions, globalMetadataOptions, false, false));
        }
Beispiel #23
0
        public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
        {
            var list = new List <RemoteImageInfo>();

            var httpRequestOptions = new HttpRequestOptions
            {
                CancellationToken = cancellationToken,
            };

            if (item is MusicAlbum || item is Book)
            {
                if (item.ProviderIds.TryGetValue("isbn", out string isbn))
                {
                    httpRequestOptions.Url = $"{baseUrl}ISBN:{isbn}";
                    using (var resp = await _httpClient.GetResponse(httpRequestOptions).ConfigureAwait(false))
                    {
                        var openLibrarySearch = await _json.DeserializeFromStreamAsync <Dictionary <string, OpenLibraryResp> >(resp.Content).ConfigureAwait(false);

                        foreach (var book in openLibrarySearch)
                        {
                            list.Add(new RemoteImageInfo
                            {
                                Url          = book.Value.cover.large,
                                ThumbnailUrl = book.Value.cover.medium,
                                ProviderName = Name
                            });
                        }
                    }
                }
                else
                {
                    httpRequestOptions.Url = $"{searchUrl}\"{HttpUtility.UrlEncode(item.Name)}\"";

                    using (var resp = await _httpClient.GetResponse(httpRequestOptions).ConfigureAwait(false))
                    {
                        var openLibrarySearch = await _json.DeserializeFromStreamAsync <OpenLibrarySearch>(resp.Content).ConfigureAwait(false);

                        foreach (var book in openLibrarySearch.docs)
                        {
                            list.Add(new RemoteImageInfo
                            {
                                Url          = $"https://covers.openlibrary.org/b/id/{book.cover_i}-L.jpg",
                                ThumbnailUrl = $"https://covers.openlibrary.org/b/id/{book.cover_i}-M.jpg",
                                ProviderName = Name
                            });
                        }
                    }
                }
            }
            if (item is MusicArtist)
            {
                httpRequestOptions.Url = $"{authorUrl}\"{HttpUtility.UrlEncode(item.Name)}\"";

                using (var resp = await _httpClient.GetResponse(httpRequestOptions).ConfigureAwait(false))
                {
                    var openLibrarySearch = await _json.DeserializeFromStreamAsync <OpenLibrarySearch>(resp.Content).ConfigureAwait(false);

                    foreach (var book in openLibrarySearch.docs)
                    {
                        list.Add(new RemoteImageInfo
                        {
                            Url          = $"https://covers.openlibrary.org/a/olid/{book.key}-L.jpg",
                            ThumbnailUrl = $"https://covers.openlibrary.org/a/olid/{book.key}-M.jpg",
                            ProviderName = Name
                        });
                    }
                }
            }

            return(list);
        }
Beispiel #24
0
        private void FetchEmbeddedInfo(Video video, Model.MediaInfo.MediaInfo data, MetadataRefreshOptions refreshOptions, LibraryOptions libraryOptions)
        {
            var isFullRefresh = refreshOptions.MetadataRefreshMode == MetadataRefreshMode.FullRefresh;

            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.OfficialRating))
            {
                if (!string.IsNullOrWhiteSpace(data.OfficialRating) || isFullRefresh)
                {
                    video.OfficialRating = data.OfficialRating;
                }
            }

            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Genres))
            {
                if (video.Genres.Length == 0 || isFullRefresh)
                {
                    video.Genres = Array.Empty <string>();

                    foreach (var genre in data.Genres)
                    {
                        video.AddGenre(genre);
                    }
                }
            }

            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Studios))
            {
                if (video.Studios.Length == 0 || isFullRefresh)
                {
                    video.SetStudios(data.Studios);
                }
            }

            if (data.ProductionYear.HasValue)
            {
                if (!video.ProductionYear.HasValue || isFullRefresh)
                {
                    video.ProductionYear = data.ProductionYear;
                }
            }
            if (data.PremiereDate.HasValue)
            {
                if (!video.PremiereDate.HasValue || isFullRefresh)
                {
                    video.PremiereDate = data.PremiereDate;
                }
            }
            if (data.IndexNumber.HasValue)
            {
                if (!video.IndexNumber.HasValue || isFullRefresh)
                {
                    video.IndexNumber = data.IndexNumber;
                }
            }
            if (data.ParentIndexNumber.HasValue)
            {
                if (!video.ParentIndexNumber.HasValue || isFullRefresh)
                {
                    video.ParentIndexNumber = data.ParentIndexNumber;
                }
            }

            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Name))
            {
                if (!string.IsNullOrWhiteSpace(data.Name) && libraryOptions.EnableEmbeddedTitles)
                {
                    // Don't use the embedded name for extras because it will often be the same name as the movie
                    if (!video.ExtraType.HasValue)
                    {
                        video.Name = data.Name;
                    }
                }
            }

            // If we don't have a ProductionYear try and get it from PremiereDate
            if (video.PremiereDate.HasValue && !video.ProductionYear.HasValue)
            {
                video.ProductionYear = video.PremiereDate.Value.ToLocalTime().Year;
            }

            if (!video.IsLocked && !video.LockedFields.Contains(MetadataFields.Overview))
            {
                if (string.IsNullOrWhiteSpace(video.Overview) || isFullRefresh)
                {
                    video.Overview = data.Overview;
                }
            }
        }
Beispiel #25
0
        private void CheckForMetadata(object sender, ElapsedEventArgs eventArgs)
        {
            try
            {
                queuedUpdateCheck.ToList().ForEach(async updateCheck =>
                {
                    Guid itemId = updateCheck.Key;

                    _logger.Debug("{0} queued for recheck", itemId.ToString());

                    BaseItem item = _libraryManager.GetItemById(itemId);

                    LibraryOptions itemLibraryOptions = _libraryManager.GetLibraryOptions(item);
                    DiscordOptions options            = Plugin.Instance.Configuration.Options.FirstOrDefault(opt => opt.MediaAddedOverride == true);
                    PublicSystemInfo sysInfo          = await _applicationHost.GetPublicSystemInfo(CancellationToken.None);
                    ServerConfiguration serverConfig  = _serverConfiguration.Configuration;

                    if (!isInVisibleLibrary(options.MediaBrowserUserId, item))
                    {
                        queuedUpdateCheck.Remove(itemId);
                        _logger.Debug("User does not have access to library, skipping...");
                        return;
                    }

                    // for whatever reason if you have extraction on during library scans then it waits for the extraction to finish before populating the metadata.... I don't get why the f**k it goes in that order
                    // its basically impossible to make a prediction on how long it could take as its dependent on the bitrate, duration, codec, and processing power of the system
                    Boolean localMetadataFallback = queuedUpdateCheck[itemId] >= (itemLibraryOptions.ExtractChapterImagesDuringLibraryScan ? Constants.MaxRetriesBeforeFallback * 5.5 : Constants.MaxRetriesBeforeFallback);

                    if (item.ProviderIds.Count > 0 || localMetadataFallback)
                    {
                        _logger.Debug("{0}[{1}] has metadata, sending notification", item.Id, item.Name);

                        string serverName  = options.ServerNameOverride ? serverConfig.ServerName : "Emby Server";
                        string LibraryType = item.GetType().Name;

                        // build primary info
                        DiscordMessage mediaAddedEmbed = new DiscordMessage
                        {
                            username   = options.Username,
                            avatar_url = options.AvatarUrl,
                            embeds     = new List <DiscordEmbed>()
                            {
                                new DiscordEmbed()
                                {
                                    color  = DiscordWebhookHelper.FormatColorCode(options.EmbedColor),
                                    footer = new Footer
                                    {
                                        text     = $"From {serverName}",
                                        icon_url = options.AvatarUrl
                                    },
                                    timestamp = DateTime.Now
                                }
                            },
                        };

                        // populate title

                        string titleText;

                        if (LibraryType == "Episode")
                        {
                            titleText = $"{item.Parent.Parent.Name} {(item.ParentIndexNumber != null ? $"S{formatIndex(item.ParentIndexNumber)}" : "")}{(item.IndexNumber != null ? $"E{formatIndex(item.IndexNumber)}" : "")} {item.Name}";
                        }
                        else
                        {
                            titleText = $"{item.Name} {(!String.IsNullOrEmpty(item.ProductionYear.ToString()) ? $"({item.ProductionYear.ToString()})" : "")}";
                        }

                        mediaAddedEmbed.embeds.First().title = _localizationManager.GetLocalizedString("ValueHasBeenAddedToLibrary").Replace("{0}", titleText).Replace("{1}", serverName);

                        // populate description
                        if (LibraryType == "Audio")
                        {
                            List <BaseItem> artists = _libraryManager.GetAllArtists(item);

                            IEnumerable <string> artistsFormat = artists.Select(artist =>
                            {
                                if (artist.ProviderIds.Count() > 0)
                                {
                                    KeyValuePair <string, string> firstProvider = artist.ProviderIds.FirstOrDefault();

                                    string providerUrl = firstProvider.Key == "MusicBrainzArtist" ? $"https://musicbrainz.org/artist/{firstProvider.Value}" : $"https://theaudiodb.com/artist/{firstProvider.Value}";

                                    return($"[{artist.Name}]({providerUrl})");
                                }
                                else
                                {
                                    return(artist.Name);
                                }
                            });

                            if (artists.Count() > 0)
                            {
                                mediaAddedEmbed.embeds.First().description = $"By {string.Join(", ", artistsFormat)}";
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(item.Overview))
                            {
                                mediaAddedEmbed.embeds.First().description = item.Overview;
                            }
                        }

                        // populate title URL
                        if (!String.IsNullOrEmpty(sysInfo.WanAddress) && !options.ExcludeExternalServerLinks)
                        {
                            mediaAddedEmbed.embeds.First().url = $"{sysInfo.WanAddress}/web/index.html#!/item?id={itemId}&serverId={sysInfo.Id}";
                        }

                        // populate images
                        if (item.HasImage(ImageType.Primary))
                        {
                            string imageUrl = "";

                            if (!item.GetImageInfo(ImageType.Primary, 0).IsLocalFile)
                            {
                                imageUrl = item.GetImagePath(ImageType.Primary);
                            }
                            else if (serverConfig.EnableRemoteAccess == true && !options.ExcludeExternalServerLinks) // in the future we can proxy images through memester server if people want to hide their server address
                            {
                                imageUrl = $"{sysInfo.WanAddress}/emby/Items/{itemId}/Images/Primary";
                            }
                            else
                            {
                                string localPath = item.GetImagePath(ImageType.Primary);
                                Stream imageData = _fileSystem.OpenRead(localPath);

                                try
                                {
                                    imageUrl = await MemesterServiceHelper.UploadImage(imageData, _jsonSerializer, _httpClient);
                                }
                                catch (Exception e)
                                {
                                    _logger.ErrorException("Failed to proxy image", e);
                                }
                            }

                            mediaAddedEmbed.embeds.First().thumbnail = new Thumbnail
                            {
                                url = imageUrl
                            };
                        }


                        if (options.MentionType == MentionTypes.Everyone)
                        {
                            mediaAddedEmbed.content = "@everyone";
                        }
                        else if (options.MentionType == MentionTypes.Here)
                        {
                            mediaAddedEmbed.content = "@here";
                        }

                        // populate external URLs
                        List <Field> providerFields = new List <Field>();

                        if (!localMetadataFallback)
                        {
                            item.ProviderIds.ToList().ForEach(provider =>
                            {
                                Field field = new Field
                                {
                                    name = "External Details"
                                };

                                Boolean didPopulate = true;

                                switch (provider.Key.ToLower())
                                {
                                case "imdb":
                                    field.value = $"[IMDb](https://www.imdb.com/title/{provider.Value}/)";
                                    break;

                                case "tmdb":
                                    field.value = $"[TMDb](https://www.themoviedb.org/{(LibraryType == "Movie" ? "movie" : "tv")}/{provider.Value})";
                                    break;

                                case "musicbrainztrack":
                                    field.value = $"[MusicBrainz Track](https://musicbrainz.org/track/{provider.Value})";
                                    break;

                                case "musicbrainzalbum":
                                    field.value = $"[MusicBrainz Album](https://musicbrainz.org/release/{provider.Value})";
                                    break;

                                case "theaudiodbalbum":
                                    field.value = $"[TADb Album](https://theaudiodb.com/album/{provider.Value})";
                                    break;

                                default:
                                    didPopulate = false;
                                    break;
                                }

                                if (didPopulate == true)
                                {
                                    providerFields.Add(field);
                                }
                            });

                            if (providerFields.Count() > 0)
                            {
                                mediaAddedEmbed.embeds.First().fields = providerFields;
                            }
                        }

                        pendingSendQueue.Add(mediaAddedEmbed, options);

                        queuedUpdateCheck.Remove(itemId);
                    }
                    else
                    {
                        queuedUpdateCheck[itemId]++;

                        _logger.Debug("Attempt: {0}", queuedUpdateCheck[itemId]);
                    }
                });
            }
            catch (Exception e)
            {
                _logger.ErrorException("Something unexpected happened in the update checker", e);
            }
        }
Beispiel #26
0
        protected IEnumerable <IMetadataProvider> GetProviders(BaseItem item, LibraryOptions libraryOptions, MetadataRefreshOptions options, bool isFirstRefresh, bool requiresRefresh)
        {
            // Get providers to refresh
            var providers = ((ProviderManager)ProviderManager).GetMetadataProviders <TItemType>(item, libraryOptions).ToList();

            var metadataRefreshMode = options.MetadataRefreshMode;

            // Run all if either of these flags are true
            var runAllProviders = options.ReplaceAllMetadata ||
                                  metadataRefreshMode == MetadataRefreshMode.FullRefresh ||
                                  (isFirstRefresh && metadataRefreshMode >= MetadataRefreshMode.Default) ||
                                  (requiresRefresh && metadataRefreshMode >= MetadataRefreshMode.Default);

            if (!runAllProviders)
            {
                var providersWithChanges = providers
                                           .Where(i =>
                {
                    if (i is IHasItemChangeMonitor hasFileChangeMonitor)
                    {
                        return(HasChanged(item, hasFileChangeMonitor, options.DirectoryService));
                    }

                    return(false);
                })
                                           .ToList();

                if (providersWithChanges.Count == 0)
                {
                    providers = new List <IMetadataProvider <TItemType> >();
                }
                else
                {
                    var anyRemoteProvidersChanged = providersWithChanges.OfType <IRemoteMetadataProvider>()
                                                    .Any();

                    var anyLocalProvidersChanged = providersWithChanges.OfType <ILocalMetadataProvider>()
                                                   .Any();

                    var anyLocalPreRefreshProvidersChanged = providersWithChanges.OfType <IPreRefreshProvider>()
                                                             .Any();

                    providers = providers.Where(i =>
                    {
                        // If any provider reports a change, always run local ones as well
                        if (i is ILocalMetadataProvider)
                        {
                            return(anyRemoteProvidersChanged || anyLocalProvidersChanged || anyLocalPreRefreshProvidersChanged);
                        }

                        // If any remote providers changed, run them all so that priorities can be honored
                        if (i is IRemoteMetadataProvider)
                        {
                            if (options.MetadataRefreshMode == MetadataRefreshMode.ValidationOnly)
                            {
                                return(false);
                            }

                            return(anyRemoteProvidersChanged);
                        }

                        // Run custom refresh providers if they report a change or any remote providers change
                        return(anyRemoteProvidersChanged || providersWithChanges.Contains(i));
                    }).ToList();
                }
            }

            return(providers);
        }
Beispiel #27
0
 public async Task <IEnumerable <RemoteImageInfo> > GetImages(BaseItem item, LibraryOptions libraryOptions, CancellationToken cancellationToken)
Beispiel #28
0
 public void UpdateLibraryOptions(LibraryOptions options)
 {
     SaveLibraryOptions(Path, options);
 }
Beispiel #29
0
        private async Task <IEnumerable <RemoteSearchResult> > GetRemoteSearchResults <TItemType, TLookupType>(RemoteSearchQuery <TLookupType> searchInfo, BaseItem referenceItem, CancellationToken cancellationToken)
            where TItemType : BaseItem, new()
            where TLookupType : ItemLookupInfo
        {
            LibraryOptions libraryOptions;

            if (referenceItem == null)
            {
                // Give it a dummy path just so that it looks like a file system item
                var dummy = new TItemType
                {
                    Path     = Path.Combine(_appPaths.InternalMetadataPath, "dummy"),
                    ParentId = Guid.NewGuid()
                };

                dummy.SetParent(new Folder());

                referenceItem  = dummy;
                libraryOptions = new LibraryOptions();
            }
            else
            {
                libraryOptions = _libraryManager.GetLibraryOptions(referenceItem);
            }

            var options = GetMetadataOptions(referenceItem);

            var providers = GetMetadataProvidersInternal <TItemType>(referenceItem, libraryOptions, options, searchInfo.IncludeDisabledProviders, false)
                            .OfType <IRemoteSearchProvider <TLookupType> >();

            if (!string.IsNullOrEmpty(searchInfo.SearchProviderName))
            {
                providers = providers.Where(i => string.Equals(i.Name, searchInfo.SearchProviderName, StringComparison.OrdinalIgnoreCase));
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage))
            {
                searchInfo.SearchInfo.MetadataLanguage = _configurationManager.Configuration.PreferredMetadataLanguage;
            }

            if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode))
            {
                searchInfo.SearchInfo.MetadataCountryCode = _configurationManager.Configuration.MetadataCountryCode;
            }

            var resultList = new List <RemoteSearchResult>();

            foreach (var provider in providers)
            {
                try
                {
                    var results = await GetSearchResults(provider, searchInfo.SearchInfo, cancellationToken).ConfigureAwait(false);

                    foreach (var result in results)
                    {
                        var existingMatch = resultList.FirstOrDefault(i => i.ProviderIds.Any(p => string.Equals(result.GetProviderId(p.Key), p.Value, StringComparison.OrdinalIgnoreCase)));

                        if (existingMatch == null)
                        {
                            resultList.Add(result);
                        }
                        else
                        {
                            foreach (var providerId in result.ProviderIds)
                            {
                                if (!existingMatch.ProviderIds.ContainsKey(providerId.Key))
                                {
                                    existingMatch.ProviderIds.Add(providerId.Key, providerId.Value);
                                }
                            }

                            if (string.IsNullOrWhiteSpace(existingMatch.ImageUrl))
                            {
                                existingMatch.ImageUrl = result.ImageUrl;
                            }
                        }
                    }
                }
#pragma warning disable CA1031 // do not catch general exception types
                catch (Exception ex)
#pragma warning restore CA1031 // do not catch general exception types
                {
                    _logger.LogError(ex, "Provider {ProviderName} failed to retrieve search results", provider.Name);
                }
            }

            return(resultList);
        }
Beispiel #30
0
 public LibraryOptions GetLibraryOptions()
 {
     return(LibraryOptions ?? (LibraryOptions = Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent)));
 }