public async Task<RefreshResult> RefreshImages(IHasImages item, LibraryOptions libraryOptions, IEnumerable<IImageProvider> imageProviders, 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 providers = imageProviders.ToList(); 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; }
public void UpdateLibraryOptions(LibraryOptions options) { SaveLibraryOptions(Path, options); }
public static void SaveLibraryOptions(string path, LibraryOptions options) { lock (LibraryOptions) { LibraryOptions[path] = options; options.SchemaVersion = 3; XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path)); } }
private async Task DownloadBackdrops(IHasImages item, LibraryOptions libraryOptions, ImageType imageType, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken) { foreach (var image in images.Where(i => i.Type == imageType)) { if (item.GetImages(imageType).Count() >= limit) { break; } if (image.Width.HasValue && image.Width.Value < minWidth) { continue; } var url = image.Url; if (EnableImageStub(item, imageType, libraryOptions)) { SaveImageStub(item, imageType, new[] { url }); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; continue; } try { var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false); // If there's already an image of the same size, skip it if (response.ContentLength.HasValue) { try { if (item.GetImages(imageType).Any(i => new FileInfo(i.Path).Length == response.ContentLength.Value)) { response.Content.Dispose(); continue; } } catch (IOException ex) { _logger.ErrorException("Error examining images", ex); } } await _providerManager.SaveImage(item, response.Content, response.ContentType, imageType, null, cancellationToken).ConfigureAwait(false); result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate; } catch (HttpException ex) { // Sometimes providers send back bad url's. Just move onto the next image if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) { continue; } break; } } }
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; } }
private async Task<bool> DownloadImage(IHasImages 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; }
/// <summary> /// Refreshes from provider. /// </summary> /// <param name="item">The item.</param> /// <param name="provider">The provider.</param> /// <param name="refreshOptions">The refresh options.</param> /// <param name="savedOptions">The saved options.</param> /// <param name="backdropLimit">The backdrop limit.</param> /// <param name="screenshotLimit">The screenshot limit.</param> /// <param name="downloadedImages">The downloaded images.</param> /// <param name="result">The result.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> private async Task RefreshFromProvider(IHasImages item, LibraryOptions libraryOptions, IRemoteImageProvider provider, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit, ICollection<ImageType> downloadedImages, RefreshResult result, CancellationToken cancellationToken) { try { if (!item.SupportsRemoteImageDownloading) { return; } if (!refreshOptions.ReplaceAllImages && refreshOptions.ReplaceImages.Count == 0 && ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit)) { return; } _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery { ProviderName = provider.Name, IncludeAllLanguages = false, IncludeDisabledProviders = false, }, cancellationToken).ConfigureAwait(false); var list = images.ToList(); int minWidth; foreach (var imageType in _singularImages) { if (!IsEnabled(savedOptions, imageType, item)) continue; if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { minWidth = savedOptions.GetMinWidth(imageType); var downloaded = await DownloadImage(item, libraryOptions, provider, result, list, minWidth, imageType, cancellationToken).ConfigureAwait(false); if (downloaded) { downloadedImages.Add(imageType); } } } if (!item.LockedFields.Contains(MetadataFields.Backdrops)) { minWidth = savedOptions.GetMinWidth(ImageType.Backdrop); await DownloadBackdrops(item, libraryOptions, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); } if (!item.LockedFields.Contains(MetadataFields.Screenshots)) { var hasScreenshots = item as IHasScreenshots; if (hasScreenshots != null) { minWidth = savedOptions.GetMinWidth(ImageType.Screenshot); await DownloadBackdrops(item, libraryOptions, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); } } } catch (OperationCanceledException) { throw; } catch (Exception ex) { result.ErrorMessage = ex.Message; _logger.ErrorException("Error in {0}", ex, provider.Name); } }
internal void CreateRecordingFoldersInternal() { var recordingFolders = GetRecordingFolders(); var virtualFolders = _libraryManager.GetVirtualFolders() .ToList(); var allExistingPaths = virtualFolders.SelectMany(i => i.Locations).ToList(); var pathsAdded = new List<string>(); foreach (var recordingFolder in recordingFolders) { var pathsToCreate = recordingFolder.Locations .Where(i => !allExistingPaths.Contains(i, StringComparer.OrdinalIgnoreCase)) .ToList(); if (pathsToCreate.Count == 0) { continue; } var mediaPathInfos = pathsToCreate.Select(i => new MediaPathInfo { Path = i }).ToArray(); var libraryOptions = new LibraryOptions { PathInfos = mediaPathInfos }; try { _libraryManager.AddVirtualFolder(recordingFolder.Name, recordingFolder.CollectionType, libraryOptions, true); } catch (Exception ex) { _logger.ErrorException("Error creating virtual folder", ex); } pathsAdded.AddRange(pathsToCreate); } var config = GetConfiguration(); var pathsToRemove = config.MediaLocationsCreated .Except(recordingFolders.SelectMany(i => i.Locations)) .ToList(); if (pathsAdded.Count > 0 || pathsToRemove.Count > 0) { pathsAdded.InsertRange(0, config.MediaLocationsCreated); config.MediaLocationsCreated = pathsAdded.Except(pathsToRemove).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); _config.SaveConfiguration("livetv", config); } foreach (var path in pathsToRemove) { RemovePathFromLibrary(path); } }