public LibraryImage GetImage(string path, bool canBeProcessed, BaseItem item) {
            LibraryImage image = null;
            bool cached = false;

            lock(cache){
                cached = cache.TryGetValue(path, out image);
            }

            if (!cached && image == null) {
                try {

                    foreach (var resolver in Kernel.Instance.ImageResolvers) {
                        image = resolver(path, canBeProcessed, item);
                        if (image != null) break;
                    }

                    if (image == null) {
                       image = new FilesystemImage();
                    }

                    image.Path = path;
                    image.Init(canBeProcessed, item);

                } catch (Exception ex) {
                    Logger.ReportException("Failed to load image: " + path + " ", ex);
                    image = null;
                }
            }

            lock (cache) {
                cache[path] = image;
            }

            return image;
        }
        /// <summary>
        /// Fetches the specified item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));

            if (metadataFile != null)
            {
                var path = metadataFile.FullName;

                await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    new BaseItemXmlParser<Season>(Logger).Fetch((Season)item, path, cancellationToken);
                }
                finally
                {
                    XmlParsingResourcePool.Release();
                }

                SetLastRefreshed(item, DateTime.UtcNow);

                return true;
            }

            return false;
        }
示例#3
0
        /// <summary>
        /// Sets the initial item values.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="args">The args.</param>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="libraryManager">The library manager.</param>
        public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem, ILibraryManager libraryManager)
        {
            // If the resolver didn't specify this
            if (string.IsNullOrEmpty(item.Path))
            {
                item.Path = args.Path;
            }

            // If the resolver didn't specify this
            if (args.Parent != null)
            {
                item.Parent = args.Parent;
            }

            item.Id = libraryManager.GetNewItemId(item.Path, item.GetType());

            // Make sure the item has a name
            EnsureName(item, args.FileInfo);

            item.IsLocked = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 ||
                item.Parents.Any(i => i.IsLocked);

            // Make sure DateCreated and DateModified have values
            EnsureDates(fileSystem, item, args, true);
        }
示例#4
0
        /// <summary>
        /// Saves the specified item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public void Save(BaseItem item, CancellationToken cancellationToken)
        {
            var builder = new StringBuilder();

            builder.Append("<Item>");

            XmlSaverHelpers.AddCommonNodes(item, builder);

            if (item.ProductionLocations.Count > 0)
            {
                builder.Append("<PlaceOfBirth>" + SecurityElement.Escape(item.ProductionLocations[0]) + "</PlaceOfBirth>");
            }

            builder.Append("</Item>");

            var xmlFilePath = GetSavePath(item);

            XmlSaverHelpers.Save(builder, xmlFilePath, new[]
                {
                    "PlaceOfBirth"
                });

            // Set last refreshed so that the provider doesn't trigger after the file save
            PersonProviderFromXml.Current.SetLastRefreshed(item, DateTime.UtcNow);
        }
        public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
        {
            var releaseId = item.GetProviderId(MetadataProviders.Musicbrainz);
            var releaseGroupId = item.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);

            if (string.IsNullOrEmpty(releaseId))
            {
                var result = await GetReleaseResult((MusicAlbum)item, cancellationToken).ConfigureAwait(false);

                if (!string.IsNullOrEmpty(result.ReleaseId))
                {
                    releaseId = result.ReleaseId;
                    item.SetProviderId(MetadataProviders.Musicbrainz, releaseId);
                }

                if (!string.IsNullOrEmpty(result.ReleaseGroupId))
                {
                    releaseGroupId = result.ReleaseGroupId;
                    item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId);
                }
            }

            // If we have a release Id but not a release group Id...
            if (!string.IsNullOrEmpty(releaseId) && string.IsNullOrEmpty(releaseGroupId))
            {
                releaseGroupId = await GetReleaseGroupId(releaseId, cancellationToken).ConfigureAwait(false);

                item.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, releaseGroupId);
            }

            SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
            return true;
        }
        public Task<IEnumerable<RemoteImageInfo>> GetAllImages(BaseItem item, CancellationToken cancellationToken)
        {
            var seriesId = item.GetProviderId(MetadataProviders.Tvdb);

            if (!string.IsNullOrEmpty(seriesId))
            {
                // Process images
                var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId);

                var path = Path.Combine(seriesDataPath, "banners.xml");

                try
                {
                    var result = GetImages(path, cancellationToken);

                    return Task.FromResult(result);
                }
                catch (FileNotFoundException)
                {
                    // No tvdb data yet. Don't blow up
                }
            }

            return Task.FromResult<IEnumerable<RemoteImageInfo>>(new RemoteImageInfo[] { });
        }
示例#7
0
        /// <summary>
        /// Sets the initial item values.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="libraryManager">The library manager.</param>
        /// <param name="directoryService">The directory service.</param>
        /// <exception cref="System.ArgumentException">Item must have a path</exception>
        public static void SetInitialItemValues(BaseItem item, Folder parent, IFileSystem fileSystem, ILibraryManager libraryManager, IDirectoryService directoryService)
        {
            // This version of the below method has no ItemResolveArgs, so we have to require the path already being set
            if (string.IsNullOrWhiteSpace(item.Path))
            {
                throw new ArgumentException("Item must have a Path");
            }

            // If the resolver didn't specify this
            if (parent != null)
            {
                item.Parent = parent;
            }

            item.Id = libraryManager.GetNewItemId(item.Path, item.GetType());

            item.IsLocked = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 ||
                item.Parents.Any(i => i.IsLocked);

            // Make sure DateCreated and DateModified have values
            var fileInfo = directoryService.GetFile(item.Path);
            item.DateModified = fileSystem.GetLastWriteTimeUtc(fileInfo);
            SetDateCreated(item, fileSystem, fileInfo);

            EnsureName(item, fileInfo);
        }
示例#8
0
        /// <summary>
        /// Sets the initial item values.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="args">The args.</param>
        /// <param name="fileSystem">The file system.</param>
        public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem)
        {
            // If the resolver didn't specify this
            if (string.IsNullOrEmpty(item.Path))
            {
                item.Path = args.Path;
            }

            // If the resolver didn't specify this
            if (args.Parent != null)
            {
                item.Parent = args.Parent;
            }

            item.Id = item.Path.GetMBId(item.GetType());

            // If the resolver didn't specify this
            if (string.IsNullOrEmpty(item.DisplayMediaType))
            {
                item.DisplayMediaType = item.GetType().Name;
            }

            // Make sure the item has a name
            EnsureName(item, args);

            item.DontFetchMeta = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 ||
                item.Parents.Any(i => i.IsLocked);

            // Make sure DateCreated and DateModified have values
            EntityResolutionHelper.EnsureDates(fileSystem, item, args, true);
        }
        /// <summary>
        /// Fetches the specified item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            
            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, "movie.xml"));

            if (metadataFile != null)
            {
                var path = metadataFile.FullName;
                var boxset = item as BoxSet;

                await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    if (boxset != null)
                    {
                        new BaseItemXmlParser<BoxSet>(Logger).Fetch(boxset, path, cancellationToken);
                    }
                    else
                    {
                        new BaseItemXmlParser<Movie>(Logger).Fetch((Movie)item, path, cancellationToken);
                    }
                }
                finally
                {
                    XmlParsingResourcePool.Release();
                }

                SetLastRefreshed(item, DateTime.UtcNow);
                return true;
            }

            return false;
        }
        public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
        {
            if (item.HasImage(ImageType.Primary))
            {
                SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
                return true;
            }

            var changed = true;

            try
            {
                changed = await DownloadImage((LiveTvProgram)item, cancellationToken).ConfigureAwait(false);
            }
            catch (HttpException ex)
            {
                // Don't fail the provider on a 404
                if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound)
                {
                    throw;
                }
            }

            if (changed)
            {
                SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
            }

            return changed;
        }
示例#11
0
        /// <summary>
        /// Determines whether [is enabled for] [the specified item].
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="updateType">Type of the update.</param>
        /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
        public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
        {
            if (!(item is Folder))
            {
                return false;
            }

            var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
            var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
            
            // If new metadata has been downloaded and save local is on, OR metadata was manually edited, proceed
            if ((_config.Configuration.SaveLocalMeta && wasMetadataDownloaded) || wasMetadataEdited)
            {
                if (!(item is Series) && !(item is BoxSet) && !(item is MusicArtist) && !(item is MusicAlbum) &&
                    !(item is Season))
                {
                    return true;
                }
            }

            // If new metadata has been downloaded or metadata was manually edited, proceed
            if (wasMetadataDownloaded || wasMetadataEdited)
            {
                if (item is AggregateFolder || item is UserRootFolder || item is CollectionFolder)
                {
                    return true;
                }
            }

            return false;
        }
示例#12
0
        public bool CanSync(BaseItem item, TraktUser traktUser)
        {
            if (item.Path == null || item.LocationType == LocationType.Virtual)
            {
                return false;
            }

            if (traktUser.LocationsExcluded != null && traktUser.LocationsExcluded.Any(s => _fileSystem.ContainsSubPath(s, item.Path)))
            {
                return false;
            }

            var movie = item as Movie;

            if (movie != null)
            {
                return !string.IsNullOrEmpty(movie.GetProviderId(MetadataProviders.Imdb)) ||
                    !string.IsNullOrEmpty(movie.GetProviderId(MetadataProviders.Tmdb));
            }

            var episode = item as Episode;

            if (episode != null && episode.Series != null && !episode.IsVirtualUnaired && !episode.IsMissingEpisode)
            {
                var series = episode.Series;

                return !string.IsNullOrEmpty(series.GetProviderId(MetadataProviders.Imdb)) ||
                    !string.IsNullOrEmpty(series.GetProviderId(MetadataProviders.Tvdb));
            }

            return false;
        }
示例#13
0
 internal override void Assign(BaseItem baseItem ) { 
     base.Assign(baseItem);
     folder = (Folder)baseItem;
     folderChildren.Assign(this, FireChildrenChangedEvents);
     folder.QuickListChanged += QuickListChanged;
     folder.UnwatchedCountChanged += AdjustUnwatched;
 }
示例#14
0
        /// <summary>
        /// Saves the specified item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public void Save(BaseItem item, CancellationToken cancellationToken)
        {
            var builder = new StringBuilder();

            builder.Append("<Item>");

            var game = (Game)item;

            if (game.PlayersSupported.HasValue)
            {
                builder.Append("<Players>" + SecurityElement.Escape(game.PlayersSupported.Value.ToString(UsCulture)) + "</Players>");
            }

            if (!string.IsNullOrEmpty(game.GameSystem))
            {
                builder.Append("<GameSystem><![CDATA[" + game.GameSystem + "]]></GameSystem>");
            }
            
            XmlSaverHelpers.AddCommonNodes(item, builder);

            builder.Append("</Item>");

            var xmlFilePath = GetSavePath(item);

            XmlSaverHelpers.Save(builder, xmlFilePath, new[]
                {
                    "Players",
                    "GameSystem"
                });

            // Set last refreshed so that the provider doesn't trigger after the file save
            MovieProviderFromXml.Current.SetLastRefreshed(item, DateTime.UtcNow);
        }
示例#15
0
 public BaseEquipment(BaseItem item)
     : base(item)
 {
     subType = ((BaseEquipment)item).subType;
     Stats = new EquipmentStatCollection();
     Stats.AddStat<LinkableStat>(StatType.ARMOR, item.Stats.GetStat(StatType.ARMOR).BaseValue);
 }
示例#16
0
        /// <summary>
        /// Needses the refresh internal.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="providerInfo">The provider info.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
        protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
        {
            if (string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tvdb)))
            {
                return false;
            }

            if (!ConfigurationManager.Configuration.DownloadSeriesImages.Art &&
                !ConfigurationManager.Configuration.DownloadSeriesImages.Logo &&
                !ConfigurationManager.Configuration.DownloadSeriesImages.Thumb &&
                !ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops &&
                !ConfigurationManager.Configuration.DownloadSeriesImages.Banner)
            {
                return false;
            }

            if (item.HasImage(ImageType.Art) &&
                item.HasImage(ImageType.Logo) &&
                item.HasImage(ImageType.Banner) &&
                item.HasImage(ImageType.Thumb) &&
                item.BackdropImagePaths.Count > 0)
            {
                return false;
            }

            return base.NeedsRefreshInternal(item, providerInfo);
        }
示例#17
0
 public void AssignItem(BaseItem item)
 {
     ItemScript = item;
     spriteImage.sprite = ItemScript.inventoryTile;
     UpdateQuantity(item.Quantity);
     ItemScript.onQuantityChanged += ItemScript_onQuantityChanged;
 }
示例#18
0
        /// <summary>
        /// Determines whether [is enabled for] [the specified item].
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="updateType">Type of the update.</param>
        /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
        public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
        {
            var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
            var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;

            // If new metadata has been downloaded and save local is on
            if (_config.Configuration.SaveLocalMeta && (wasMetadataEdited || wasMetadataDownloaded))
            {
                if (item is MusicArtist)
                {
                    return true;
                }
            }

            // If new metadata has been downloaded or metadata was manually edited, proceed
            if (wasMetadataDownloaded || wasMetadataEdited)
            {
                if (item is Artist)
                {
                    return true;
                }
            }

            return false;
        }
示例#19
0
        /// <summary>
        /// Adds the child.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.InvalidOperationException">Unable to add  + item.Name</exception>
        public async Task AddChild(BaseItem item, CancellationToken cancellationToken)
        {
            item.Parent = this;

            if (item.Id == Guid.Empty)
            {
                item.Id = item.Path.GetMBId(item.GetType());
            }

            if (_children.Any(i => i.Id == item.Id))
            {
                throw new ArgumentException(string.Format("A child with the Id {0} already exists.", item.Id));
            }

            if (item.DateCreated == DateTime.MinValue)
            {
                item.DateCreated = DateTime.UtcNow;
            }
            if (item.DateModified == DateTime.MinValue)
            {
                item.DateModified = DateTime.UtcNow;
            }

            AddChildInternal(item);

            await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);

            await ItemRepository.SaveChildren(Id, _children.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
        }
        /// <summary>
        /// Compares the specified x.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <returns>System.Int32.</returns>
        public int Compare(BaseItem x, BaseItem y)
        {
            if (x.PremiereDate.HasValue && y.PremiereDate.HasValue)
            {
                var val = DateTime.Compare(x.PremiereDate.Value, y.PremiereDate.Value);

                if (val != 0)
                {
                    //return val;
                }
            }

            var episode1 = x as Episode;
            var episode2 = y as Episode;

            if (episode1 == null)
            {
                if (episode2 == null)
                {
                    return 0;
                }

                return 1;
            }

            if (episode2 == null)
            {
                return -1;
            }

            return Compare(episode1, episode2);
        }
示例#21
0
        private IEnumerable<PersonInfo> GetPeopleToValidate(BaseItem item, PeopleMetadataOptions options)
        {
            return item.People.Where(i =>
            {
                if (i.IsType(PersonType.Actor))
                {
                    return options.DownloadActorMetadata;
                }
                if (i.IsType(PersonType.Director))
                {
                    return options.DownloadDirectorMetadata;
                }
                if (i.IsType(PersonType.Composer))
                {
                    return options.DownloadComposerMetadata;
                }
                if (i.IsType(PersonType.Writer))
                {
                    return options.DownloadWriterMetadata;
                }
                if (i.IsType(PersonType.Producer))
                {
                    return options.DownloadProducerMetadata;
                }
                if (i.IsType(PersonType.GuestStar))
                {
                    return options.DownloadGuestStarMetadata;
                }

                return options.DownloadOtherPeopleMetadata;
            });
        }
示例#22
0
        protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
        {
            if (HasAltMeta(item))
                return false;

            return base.NeedsRefreshInternal(item, providerInfo);
        }
示例#23
0
文件: GameItem.cs 项目: RAWeber/Unity
 // Use this for initialization
 void Start()
 {
     Physics.IgnoreCollision(GameControl.player.GetComponent<Collider>(), this.GetComponent<Collider>());
     try
     {
         switch (ItemDatabase.itemDatabase[itemName].Type)
         {
             case BaseItem.ItemType.WEAPON:
                 item = new BaseWeapon((BaseWeapon)ItemDatabase.itemDatabase[itemName]);
                 break;
             case BaseItem.ItemType.EQUIPMENT:
                 item = new BaseEquipment(ItemDatabase.itemDatabase[itemName]);
                 break;
             case BaseItem.ItemType.RELIC:
                 item = new BaseRelic(ItemDatabase.itemDatabase[itemName]);
                 for (int i = 0; i < UnityEngine.Random.Range(1, 3); i++)
                 {
                     int randStat = UnityEngine.Random.Range((int)StatType.STRENGTH, (int)StatType.DEFENSE+1);
                     item.Stats.AddStat<ModifiableStat>((StatType)randStat, UnityEngine.Random.Range(1, 11));
                 }
                 break;
             case BaseItem.ItemType.CONSUMABLE:
                 item = new BaseConsumable(ItemDatabase.itemDatabase[itemName]);
                 break;
         }
     }
     catch (Exception)
     {
         Debug.Log("No item of name "+itemName+" within itemDatabase");
     }
 }
        /// <summary>
        /// Finds the id.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.String}.</returns>
        private async Task<string> FindId(BaseItem item, CancellationToken cancellationToken)
        {
            if (item is Artist)
            {
                // Since MusicArtists are refreshed first, try to find it from one of them
                var id = FindIdFromMusicArtistEntity(item);

                if (!string.IsNullOrEmpty(id))
                {
                    return id;
                }
            }

            try
            {
                // If we don't get anything, go directly to music brainz
                return await FindIdFromMusicBrainz(item, cancellationToken).ConfigureAwait(false);
            }
            catch (HttpException e)
            {
                if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.BadRequest)
                {
                    // They didn't like a character in the name. Handle the exception so that the provider doesn't keep retrying over and over
                    return null;
                }

                throw;
            }
        }
示例#25
0
        private string GetValue(BaseItem item)
        {
            Series series = null;

            var season = item as Season;

            if (season != null)
            {
                series = season.Series;
            }

            var episode = item as Episode;

            if (episode != null)
            {
                series = episode.Series;
            }

            if (series == null)
            {
                series = item as Series;
            }

            return series != null ? series.SortName : null;
        }
        /// <summary>
        /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="force">if set to <c>true</c> [force].</param>
        /// <param name="providerInfo">The provider information.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));

            if (metadataFile != null)
            {
                var path = metadataFile.FullName;

                await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    new BaseItemXmlParser<Folder>(Logger).Fetch((Folder)item, path, cancellationToken);
                }
                finally
                {
                    XmlParsingResourcePool.Release();
                }
            }

            SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
            return true;
        }
        protected override Guid GetFileSystemStamp(BaseItem item)
        {
            var location = GetLocation(item);

            try
            {
                var files = new DirectoryInfo(location)
                    .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
                    .Where(i =>
                    {
                        var ext = i.Extension;

                        return !string.IsNullOrEmpty(ext) &&
                            BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase);
                    })
                    .ToList();

                return GetFileSystemStamp(files);
            }
            catch (DirectoryNotFoundException)
            {
                // User doesn't have the folder. No need to log or blow up

                return Guid.Empty;
            }
        }
        /// <summary>
        /// Fetches metadata and returns true or false indicating if any work that requires persistence was done
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="force">if set to <c>true</c> [force].</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task{System.Boolean}.</returns>
        public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var path = MovieXmlSaver.GetMovieSavePath(item);

            if (File.Exists(path))
            {
                await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);

                try
                {
                    var video = (Video)item;

                    await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false);
                }
                finally
                {
                    XmlParsingResourcePool.Release();
                }
            }

            SetLastRefreshed(item, DateTime.UtcNow, providerInfo);

            return true;
        }
 public static Task DeleteItem(this ILibraryManager manager, BaseItem item)
 {
     return manager.DeleteItem(item, new DeleteOptions
     {
         DeleteFileLocation = true
     });
 }
示例#30
0
        public XmlElement GetItemElement(XmlDocument doc, BaseItem item, string deviceId, Filter filter, StreamInfo streamInfo = null)
        {
            var element = doc.CreateElement(string.Empty, "item", NS_DIDL);
            element.SetAttribute("restricted", "1");
            element.SetAttribute("id", item.Id.ToString("N"));

            if (item.Parent != null)
            {
                element.SetAttribute("parentID", item.Parent.Id.ToString("N"));
            }

            //AddBookmarkInfo(item, user, element);

            AddGeneralProperties(item, element, filter);

            // refID?
            // storeAttribute(itemNode, object, ClassProperties.REF_ID, false);

            var audio = item as Audio;
            if (audio != null)
            {
                AddAudioResource(element, audio, deviceId, filter, streamInfo);
            }

            var video = item as Video;
            if (video != null)
            {
                AddVideoResource(element, video, deviceId, filter, streamInfo);
            }

            AddCover(item, element);

            return element;
        }
示例#31
0
 /// <summary>
 /// Saves the metadata.
 /// </summary>
 public void SaveMetadata(BaseItem item, ItemUpdateType updateType)
 {
     SaveMetadata(item, updateType, _savers);
 }
示例#32
0
        /// <summary>
        /// Gets the image cache tag.
        /// </summary>
        /// <param name="originalImagePath">The original image path.</param>
        /// <param name="dateModified">The date modified of the original image file.</param>
        /// <param name="imageEnhancers">The image enhancers.</param>
        /// <param name="item">The item.</param>
        /// <param name="imageType">Type of the image.</param>
        /// <returns>Guid.</returns>
        /// <exception cref="System.ArgumentNullException">item</exception>
        public Guid GetImageCacheTag(string originalImagePath, DateTime dateModified, IEnumerable <IImageEnhancer> imageEnhancers, BaseItem item, ImageType imageType)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (imageEnhancers == null)
            {
                throw new ArgumentNullException("imageEnhancers");
            }

            if (string.IsNullOrEmpty(originalImagePath))
            {
                throw new ArgumentNullException("originalImagePath");
            }

            // Cache name is created with supported enhancers combined with the last config change so we pick up new config changes
            var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList();

            cacheKeys.Add(originalImagePath + dateModified.Ticks);

            return(string.Join("|", cacheKeys.ToArray()).GetMD5());
        }
示例#33
0
        /// <summary>
        /// Runs an image through the image enhancers, caches the result, and returns the cached path
        /// </summary>
        /// <param name="originalImagePath">The original image path.</param>
        /// <param name="dateModified">The date modified of the original image file.</param>
        /// <param name="item">The item.</param>
        /// <param name="imageType">Type of the image.</param>
        /// <param name="imageIndex">Index of the image.</param>
        /// <param name="supportedEnhancers">The supported enhancers.</param>
        /// <returns>System.String.</returns>
        /// <exception cref="System.ArgumentNullException">originalImagePath</exception>
        public async Task <string> GetEnhancedImage(string originalImagePath, DateTime dateModified, BaseItem item, ImageType imageType, int imageIndex, List <IImageEnhancer> supportedEnhancers)
        {
            if (string.IsNullOrEmpty(originalImagePath))
            {
                throw new ArgumentNullException("originalImagePath");
            }

            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            var cacheGuid = GetImageCacheTag(originalImagePath, dateModified, supportedEnhancers, item, imageType);

            // All enhanced images are saved as png to allow transparency
            var enhancedImagePath = EnhancedImageCache.GetResourcePath(cacheGuid + ".png");

            var semaphore = GetLock(enhancedImagePath);

            await semaphore.WaitAsync().ConfigureAwait(false);

            // Check again in case of contention
            if (File.Exists(enhancedImagePath))
            {
                semaphore.Release();
                return(enhancedImagePath);
            }

            try
            {
                using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
                {
                    // Copy to memory stream to avoid Image locking file
                    using (var memoryStream = new MemoryStream())
                    {
                        await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);

                        using (var originalImage = Image.FromStream(memoryStream, true, false))
                        {
                            //Pass the image through registered enhancers
                            using (var newImage = await ExecuteImageEnhancers(supportedEnhancers, originalImage, item, imageType, imageIndex).ConfigureAwait(false))
                            {
                                var parentDirectory = Path.GetDirectoryName(enhancedImagePath);

                                if (!Directory.Exists(parentDirectory))
                                {
                                    Directory.CreateDirectory(parentDirectory);
                                }

                                //And then save it in the cache
                                using (var outputStream = new FileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))
                                {
                                    newImage.Save(ImageFormat.Png, outputStream, 100);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                semaphore.Release();
            }

            return(enhancedImagePath);
        }
示例#34
0
        /// <summary>
        /// Gets the enhanced image.
        /// </summary>
        /// <param name="originalImagePath">The original image path.</param>
        /// <param name="dateModified">The date modified.</param>
        /// <param name="item">The item.</param>
        /// <param name="imageType">Type of the image.</param>
        /// <param name="imageIndex">Index of the image.</param>
        /// <returns>Task{System.String}.</returns>
        /// <exception cref="System.ArgumentNullException">item</exception>
        public Task <string> GetEnhancedImage(string originalImagePath, DateTime dateModified, BaseItem item, ImageType imageType, int imageIndex)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            var supportedImageEnhancers = ImageEnhancers.Where(i =>
            {
                try
                {
                    return(i.Supports(item, imageType));
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name);

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

            return(GetEnhancedImage(originalImagePath, dateModified, item, imageType, imageIndex, supportedImageEnhancers));
        }
示例#35
0
        /// <summary>
        /// Processes an image by resizing to target dimensions
        /// </summary>
        /// <param name="entity">The entity that owns the image</param>
        /// <param name="imageType">The image type</param>
        /// <param name="imageIndex">The image index (currently only used with backdrops)</param>
        /// <param name="originalImagePath">The original image path.</param>
        /// <param name="cropWhitespace">if set to <c>true</c> [crop whitespace].</param>
        /// <param name="dateModified">The last date modified of the original image file</param>
        /// <param name="toStream">The stream to save the new image to</param>
        /// <param name="width">Use if a fixed width is required. Aspect ratio will be preserved.</param>
        /// <param name="height">Use if a fixed height is required. Aspect ratio will be preserved.</param>
        /// <param name="maxWidth">Use if a max width is required. Aspect ratio will be preserved.</param>
        /// <param name="maxHeight">Use if a max height is required. Aspect ratio will be preserved.</param>
        /// <param name="quality">Quality level, from 0-100. Currently only applies to JPG. The default value should suffice.</param>
        /// <param name="enhancers">The enhancers.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">entity</exception>
        public async Task ProcessImage(BaseItem entity, ImageType imageType, int imageIndex, string originalImagePath, bool cropWhitespace, DateTime dateModified, Stream toStream, int?width, int?height, int?maxWidth, int?maxHeight, int?quality, List <IImageEnhancer> enhancers)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            if (toStream == null)
            {
                throw new ArgumentNullException("toStream");
            }

            if (cropWhitespace)
            {
                originalImagePath = await GetCroppedImage(originalImagePath, dateModified).ConfigureAwait(false);
            }

            // No enhancement - don't cache
            if (enhancers.Count > 0)
            {
                try
                {
                    // Enhance if we have enhancers
                    var ehnancedImagePath = await GetEnhancedImage(originalImagePath, dateModified, entity, imageType, imageIndex, enhancers).ConfigureAwait(false);

                    // If the path changed update dateModified
                    if (!ehnancedImagePath.Equals(originalImagePath, StringComparison.OrdinalIgnoreCase))
                    {
                        dateModified      = File.GetLastWriteTimeUtc(ehnancedImagePath);
                        originalImagePath = ehnancedImagePath;
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error("Error enhancing image", ex);
                }
            }

            var originalImageSize = await GetImageSize(originalImagePath, dateModified).ConfigureAwait(false);

            // Determine the output size based on incoming parameters
            var newSize = DrawingUtils.Resize(originalImageSize, width, height, maxWidth, maxHeight);

            if (!quality.HasValue)
            {
                quality = 90;
            }

            var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality.Value, dateModified);

            try
            {
                using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
                {
                    await fileStream.CopyToAsync(toStream).ConfigureAwait(false);

                    return;
                }
            }
            catch (IOException)
            {
                // Cache file doesn't exist or is currently being written ro
            }

            var semaphore = GetLock(cacheFilePath);

            await semaphore.WaitAsync().ConfigureAwait(false);

            // Check again in case of lock contention
            if (File.Exists(cacheFilePath))
            {
                try
                {
                    using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
                    {
                        await fileStream.CopyToAsync(toStream).ConfigureAwait(false);

                        return;
                    }
                }
                finally
                {
                    semaphore.Release();
                }
            }

            try
            {
                using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
                {
                    // Copy to memory stream to avoid Image locking file
                    using (var memoryStream = new MemoryStream())
                    {
                        await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);

                        using (var originalImage = Image.FromStream(memoryStream, true, false))
                        {
                            var newWidth  = Convert.ToInt32(newSize.Width);
                            var newHeight = Convert.ToInt32(newSize.Height);

                            // Graphics.FromImage will throw an exception if the PixelFormat is Indexed, so we need to handle that here
                            using (var thumbnail = !ImageExtensions.IsPixelFormatSupportedByGraphicsObject(originalImage.PixelFormat) ? new Bitmap(originalImage, newWidth, newHeight) : new Bitmap(newWidth, newHeight, originalImage.PixelFormat))
                            {
                                // Preserve the original resolution
                                thumbnail.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);

                                using (var thumbnailGraph = Graphics.FromImage(thumbnail))
                                {
                                    thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
                                    thumbnailGraph.SmoothingMode      = SmoothingMode.HighQuality;
                                    thumbnailGraph.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                                    thumbnailGraph.PixelOffsetMode    = PixelOffsetMode.HighQuality;
                                    thumbnailGraph.CompositingMode    = CompositingMode.SourceOver;

                                    thumbnailGraph.DrawImage(originalImage, 0, 0, newWidth, newHeight);

                                    var outputFormat = originalImage.RawFormat;

                                    using (var outputMemoryStream = new MemoryStream())
                                    {
                                        // Save to the memory stream
                                        thumbnail.Save(outputFormat, outputMemoryStream, quality.Value);

                                        var bytes = outputMemoryStream.ToArray();

                                        var outputTask = toStream.WriteAsync(bytes, 0, bytes.Length);

                                        // kick off a task to cache the result
                                        var cacheTask = CacheResizedImage(cacheFilePath, bytes);

                                        await Task.WhenAll(outputTask, cacheTask).ConfigureAwait(false);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                semaphore.Release();
            }
        }
示例#36
0
        public 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 = _libraryManagerFactory().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;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    // Logged at lower levels
                }
            }

            //_logger.LogDebug("Returning search results {0}", _json.SerializeToString(resultList));

            return(resultList);
        }
示例#37
0
 /// <summary>
 /// Saves the metadata.
 /// </summary>
 public void SaveMetadata(BaseItem item, ItemUpdateType updateType, IEnumerable <string> savers)
 {
     SaveMetadata(item, updateType, _savers.Where(i => savers.Contains(i.Name, StringComparer.OrdinalIgnoreCase)));
 }
示例#38
0
 public IEnumerable <IImageProvider> GetImageProviders(BaseItem item, ImageRefreshOptions refreshOptions)
 {
     return(GetImageProviders(item, _libraryManagerFactory().GetLibraryOptions(item), GetMetadataOptions(item), refreshOptions, false));
 }
示例#39
0
 public Task RefreshFullItem(BaseItem item, MetadataRefreshOptions options,
                             CancellationToken cancellationToken)
 {
     return(RefreshItem(item, options, cancellationToken));
 }
示例#40
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, currentOptions, includeDisabled, forceEnableInternetMetadata))
                   .OrderBy(i => GetConfiguredOrder(item, i, libraryOptions, globalMetadataOptions))
                   .ThenBy(GetDefaultOrder));
        }
示例#41
0
        private void AddGeneralProperties(BaseItem item, StubType?itemStubType, BaseItem context, XmlElement element, Filter filter)
        {
            AddCommonFields(item, itemStubType, context, element, filter);

            var audio = item as Audio;

            if (audio != null)
            {
                foreach (var artist in audio.Artists)
                {
                    AddValue(element, "upnp", "artist", artist, NS_UPNP);
                }

                if (!string.IsNullOrEmpty(audio.Album))
                {
                    AddValue(element, "upnp", "album", audio.Album, NS_UPNP);
                }

                foreach (var artist in audio.AlbumArtists)
                {
                    AddAlbumArtist(element, artist);
                }
            }

            var album = item as MusicAlbum;

            if (album != null)
            {
                foreach (var artist in album.AlbumArtists)
                {
                    AddAlbumArtist(element, artist);
                    AddValue(element, "upnp", "artist", artist, NS_UPNP);
                }
                foreach (var artist in album.Artists)
                {
                    AddValue(element, "upnp", "artist", artist, NS_UPNP);
                }
            }

            var musicVideo = item as MusicVideo;

            if (musicVideo != null)
            {
                foreach (var artist in musicVideo.Artists)
                {
                    AddValue(element, "upnp", "artist", artist, NS_UPNP);
                    AddAlbumArtist(element, artist);
                }

                if (!string.IsNullOrEmpty(musicVideo.Album))
                {
                    AddValue(element, "upnp", "album", musicVideo.Album, NS_UPNP);
                }
            }

            if (item.IndexNumber.HasValue)
            {
                AddValue(element, "upnp", "originalTrackNumber", item.IndexNumber.Value.ToString(_usCulture), NS_UPNP);

                if (item is Episode)
                {
                    AddValue(element, "upnp", "episodeNumber", item.IndexNumber.Value.ToString(_usCulture), NS_UPNP);
                }
            }
        }
示例#42
0
 public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int?imageIndex, CancellationToken cancellationToken)
 {
     return(new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken));
 }
示例#43
0
        //private void AddBookmarkInfo(BaseItem item, User user, XmlElement element)
        //{
        //    var userdata = _userDataManager.GetUserData(user.Id, item.GetUserDataKey());

        //    if (userdata.PlaybackPositionTicks > 0)
        //    {
        //        var dcmInfo = element.OwnerDocument.CreateElement("sec", "dcmInfo", NS_SEC);
        //        dcmInfo.InnerText = string.Format("BM={0}", Convert.ToInt32(TimeSpan.FromTicks(userdata.PlaybackPositionTicks).TotalSeconds).ToString(_usCulture));
        //        element.AppendChild(dcmInfo);
        //    }
        //}

        /// <summary>
        /// Adds fields used by both items and folders
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="itemStubType">Type of the item stub.</param>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="filter">The filter.</param>
        private void AddCommonFields(BaseItem item, StubType?itemStubType, BaseItem context, XmlElement element, Filter filter)
        {
            // Don't filter on dc:title because not all devices will include it in the filter
            // MediaMonkey for example won't display content without a title
            //if (filter.Contains("dc:title"))
            {
                AddValue(element, "dc", "title", GetDisplayName(item, itemStubType, context), NS_DC);
            }

            element.AppendChild(CreateObjectClass(element.OwnerDocument, item, itemStubType));

            if (filter.Contains("dc:date"))
            {
                if (item.PremiereDate.HasValue)
                {
                    AddValue(element, "dc", "date", item.PremiereDate.Value.ToString("o"), NS_DC);
                }
            }

            if (filter.Contains("upnp:genre"))
            {
                foreach (var genre in item.Genres)
                {
                    AddValue(element, "upnp", "genre", genre, NS_UPNP);
                }
            }

            foreach (var studio in item.Studios)
            {
                AddValue(element, "upnp", "publisher", studio, NS_UPNP);
            }

            if (filter.Contains("dc:description"))
            {
                var desc = item.Overview;

                var hasShortOverview = item as IHasShortOverview;
                if (hasShortOverview != null && !string.IsNullOrEmpty(hasShortOverview.ShortOverview))
                {
                    desc = hasShortOverview.ShortOverview;
                }

                if (!string.IsNullOrWhiteSpace(desc))
                {
                    AddValue(element, "dc", "description", desc, NS_DC);
                }
            }
            if (filter.Contains("upnp:longDescription"))
            {
                if (!string.IsNullOrWhiteSpace(item.Overview))
                {
                    AddValue(element, "upnp", "longDescription", item.Overview, NS_UPNP);
                }
            }

            if (!string.IsNullOrEmpty(item.OfficialRating))
            {
                if (filter.Contains("dc:rating"))
                {
                    AddValue(element, "dc", "rating", item.OfficialRating, NS_DC);
                }
                if (filter.Contains("upnp:rating"))
                {
                    AddValue(element, "upnp", "rating", item.OfficialRating, NS_UPNP);
                }
            }

            AddPeople(item, element);
        }
示例#44
0
        private void AddCover(BaseItem item, StubType?stubType, XmlElement element)
        {
            if (stubType.HasValue && stubType.Value == StubType.People)
            {
                AddEmbeddedImageAsCover("people", element);
                return;
            }

            var imageInfo = GetImageInfo(item);

            if (imageInfo == null)
            {
                return;
            }

            var result = element.OwnerDocument;

            var playbackPercentage = 0;
            var unplayedCount      = 0;

            if (item is Video)
            {
                var userData = _userDataManager.GetUserDataDto(item, _user);

                playbackPercentage = Convert.ToInt32(userData.PlayedPercentage ?? 0);
                if (playbackPercentage >= 100 || userData.Played)
                {
                    playbackPercentage = 100;
                }
            }
            else if (item is Series || item is Season || item is BoxSet)
            {
                var userData = _userDataManager.GetUserDataDto(item, _user);

                if (userData.Played)
                {
                    playbackPercentage = 100;
                }
                else
                {
                    unplayedCount = userData.UnplayedItemCount ?? 0;
                }
            }

            var albumartUrlInfo = GetImageUrl(imageInfo, _profile.MaxAlbumArtWidth, _profile.MaxAlbumArtHeight, playbackPercentage, unplayedCount, "jpg");

            var icon    = result.CreateElement("upnp", "albumArtURI", NS_UPNP);
            var profile = result.CreateAttribute("dlna", "profileID", NS_DLNA);

            profile.InnerText = _profile.AlbumArtPn;
            icon.SetAttributeNode(profile);
            icon.InnerText = albumartUrlInfo.Url;
            element.AppendChild(icon);

            // TOOD: Remove these default values
            var iconUrlInfo = GetImageUrl(imageInfo, _profile.MaxIconWidth ?? 48, _profile.MaxIconHeight ?? 48, playbackPercentage, unplayedCount, "jpg");

            icon           = result.CreateElement("upnp", "icon", NS_UPNP);
            icon.InnerText = iconUrlInfo.Url;
            element.AppendChild(icon);

            if (!_profile.EnableAlbumArtInDidl)
            {
                if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
                {
                    if (!stubType.HasValue)
                    {
                        return;
                    }
                }
            }

            AddImageResElement(item, element, 160, 160, playbackPercentage, unplayedCount, "jpg", "JPEG_TN");

            if (!_profile.EnableSingleAlbumArtLimit)
            {
                AddImageResElement(item, element, 4096, 4096, playbackPercentage, unplayedCount, "jpg", "JPEG_LRG");
                AddImageResElement(item, element, 1024, 768, playbackPercentage, unplayedCount, "jpg", "JPEG_MED");
                AddImageResElement(item, element, 640, 480, playbackPercentage, unplayedCount, "jpg", "JPEG_SM");
                AddImageResElement(item, element, 4096, 4096, playbackPercentage, unplayedCount, "png", "PNG_LRG");
                AddImageResElement(item, element, 160, 160, playbackPercentage, unplayedCount, "png", "PNG_TN");
            }
        }
示例#45
0
 /// <summary>
 /// Gets the save path.
 /// </summary>
 /// <param name="item">The item.</param>
 /// <returns>System.String.</returns>
 public string GetSavePath(BaseItem item)
 {
     return(Path.Combine(item.Path, "folder.xml"));
 }
示例#46
0
        private XmlElement CreateObjectClass(XmlDocument result, BaseItem item, StubType?stubType)
        {
            // More types here
            // http://oss.linn.co.uk/repos/Public/LibUpnpCil/DidlLite/UpnpAv/Test/TestDidlLite.cs

            var objectClass = result.CreateElement("upnp", "class", NS_UPNP);

            if (item.IsFolder || stubType.HasValue)
            {
                string classType = null;

                if (!_profile.RequiresPlainFolders)
                {
                    if (item is MusicAlbum)
                    {
                        classType = "object.container.album.musicAlbum";
                    }
                    else if (item is MusicArtist)
                    {
                        classType = "object.container.person.musicArtist";
                    }
                    else if (item is Series || item is Season || item is BoxSet || item is Video)
                    {
                        classType = "object.container.album.videoAlbum";
                    }
                    else if (item is Playlist)
                    {
                        classType = "object.container.playlistContainer";
                    }
                    else if (item is PhotoAlbum)
                    {
                        classType = "object.container.album.photoAlbum";
                    }
                }

                objectClass.InnerText = classType ?? "object.container.storageFolder";
            }
            else if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
            {
                objectClass.InnerText = "object.item.audioItem.musicTrack";
            }
            else if (string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase))
            {
                objectClass.InnerText = "object.item.imageItem.photo";
            }
            else if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
            {
                if (!_profile.RequiresPlainVideoItems && item is Movie)
                {
                    objectClass.InnerText = "object.item.videoItem.movie";
                }
                else if (!_profile.RequiresPlainVideoItems && item is MusicVideo)
                {
                    objectClass.InnerText = "object.item.videoItem.musicVideoClip";
                }
                else
                {
                    objectClass.InnerText = "object.item.videoItem";
                }
            }
            else if (item is MusicGenre)
            {
                objectClass.InnerText = _profile.RequiresPlainFolders ? "object.container.storageFolder" : "object.container.genre.musicGenre";
            }
            else if (item is Genre || item is GameGenre)
            {
                objectClass.InnerText = _profile.RequiresPlainFolders ? "object.container.storageFolder" : "object.container.genre";
            }
            else
            {
                objectClass.InnerText = "object.item";
            }

            return(objectClass);
        }
 public IEnumerable <ImageType> GetSupportedImages(BaseItem item)
 {
     return(new[] { ImageType.Primary });
 }
示例#48
0
        public XmlElement GetFolderElement(XmlDocument doc, BaseItem folder, StubType?stubType, BaseItem context, int childCount, Filter filter, string requestedId = null)
        {
            var container = doc.CreateElement(string.Empty, "container", NS_DIDL);

            container.SetAttribute("restricted", "0");
            container.SetAttribute("searchable", "1");
            container.SetAttribute("childCount", childCount.ToString(_usCulture));

            var clientId = GetClientId(folder, stubType);

            if (string.Equals(requestedId, "0"))
            {
                container.SetAttribute("id", "0");
                container.SetAttribute("parentID", "-1");
            }
            else
            {
                container.SetAttribute("id", clientId);

                var parent = context ?? folder.DisplayParent;
                if (parent == null)
                {
                    container.SetAttribute("parentID", "0");
                }
                else
                {
                    container.SetAttribute("parentID", GetClientId(parent, null));
                }
            }

            AddCommonFields(folder, stubType, null, container, filter);

            AddCover(folder, stubType, container);

            return(container);
        }
示例#49
0
        private void SaveImageStub(BaseItem item, ImageType imageType, IEnumerable <string> urls)
        {
            var newIndex = item.AllowsMultipleImages(imageType) ? item.GetImages(imageType).Count() : 0;

            SaveImageStub(item, imageType, urls, newIndex);
        }
 public bool Supports(BaseItem item)
 {
     return(item is Series || item is Movie || item is Season);
 }
示例#51
0
 private bool IsEnabled(TypeOptions options, ImageType type, BaseItem item)
 {
     return(options.IsEnabled(type));
 }
示例#52
0
 public InventoryData(BaseItem itemInfo, int amounts)
 {
     this.itemInfo = itemInfo;
     this.amounts  = amounts;
 }
示例#53
0
 private bool HasImage(BaseItem item, ImageType type)
 {
     return(item.HasImage(type));
 }
示例#54
0
        public bool MergeImages(BaseItem item, List <LocalImageInfo> images)
        {
            var changed = false;

            foreach (var type in _singularImages)
            {
                var image = images.FirstOrDefault(i => i.Type == type);

                if (image != null)
                {
                    var currentImage = item.GetImageInfo(type, 0);

                    if (currentImage == null)
                    {
                        item.SetImagePath(type, image.FileInfo);
                        changed = true;
                    }
                    else if (!string.Equals(currentImage.Path, image.FileInfo.FullName, StringComparison.OrdinalIgnoreCase))
                    {
                        item.SetImagePath(type, image.FileInfo);
                        changed = true;
                    }
                    else
                    {
                        var newDateModified = _fileSystem.GetLastWriteTimeUtc(image.FileInfo);

                        // If date changed then we need to reset saved image dimensions
                        if (currentImage.DateModified != newDateModified && (currentImage.Width > 0 || currentImage.Height > 0))
                        {
                            currentImage.Width  = 0;
                            currentImage.Height = 0;
                            changed             = true;
                        }

                        currentImage.DateModified = newDateModified;
                    }
                }
                else
                {
                    var existing = item.GetImageInfo(type, 0);
                    if (existing != null)
                    {
                        if (existing.IsLocalFile && !_fileSystem.FileExists(existing.Path))
                        {
                            item.RemoveImage(existing);
                            changed = true;
                        }
                    }
                }
            }

            if (UpdateMultiImages(item, images, ImageType.Backdrop))
            {
                changed = true;
            }

            var hasScreenshots = item as IHasScreenshots;

            if (hasScreenshots != null)
            {
                if (UpdateMultiImages(item, images, ImageType.Screenshot))
                {
                    changed = true;
                }
            }

            return(changed);
        }
 /// <inheritdoc />
 public IEnumerable <ImageType> GetSupportedImages(BaseItem item)
 {
     yield return(ImageType.Primary);
 }
示例#56
0
        /// <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(BaseItem item, LibraryOptions libraryOptions,
                                               IRemoteImageProvider provider,
                                               ImageRefreshOptions refreshOptions,
                                               TypeOptions savedOptions,
                                               int backdropLimit,
                                               int screenshotLimit,
                                               ICollection <ImageType> downloadedImages,
                                               RefreshResult result,
                                               CancellationToken cancellationToken)
        {
            try
            {
                if (!item.SupportsRemoteImageDownloading)
                {
                    return;
                }

                if (!refreshOptions.ReplaceAllImages &&
                    refreshOptions.ReplaceImages.Length == 0 &&
                    ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit))
                {
                    return;
                }

                _logger.LogDebug("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);
                        }
                    }
                }

                minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
                await DownloadBackdrops(item, libraryOptions, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);

                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.LogError(ex, "Error in {provider}", provider.Name);
            }
        }
示例#57
0
        public TimerInfoDto GetTimerInfoDto(TimerInfo info, ILiveTvService service, LiveTvProgram program, BaseItem channel)
        {
            var dto = new TimerInfoDto
            {
                Id                    = GetInternalTimerId(info.Id),
                Overview              = info.Overview,
                EndDate               = info.EndDate,
                Name                  = info.Name,
                StartDate             = info.StartDate,
                ExternalId            = info.Id,
                ChannelId             = GetInternalChannelId(service.Name, info.ChannelId),
                Status                = info.Status,
                SeriesTimerId         = string.IsNullOrEmpty(info.SeriesTimerId) ? null : GetInternalSeriesTimerId(info.SeriesTimerId).ToString("N"),
                PrePaddingSeconds     = info.PrePaddingSeconds,
                PostPaddingSeconds    = info.PostPaddingSeconds,
                IsPostPaddingRequired = info.IsPostPaddingRequired,
                IsPrePaddingRequired  = info.IsPrePaddingRequired,
                KeepUntil             = info.KeepUntil,
                ExternalChannelId     = info.ChannelId,
                ExternalSeriesTimerId = info.SeriesTimerId,
                ServiceName           = service.Name,
                ExternalProgramId     = info.ProgramId,
                Priority              = info.Priority,
                RunTimeTicks          = (info.EndDate - info.StartDate).Ticks,
                ServerId              = _appHost.SystemId
            };

            if (!string.IsNullOrEmpty(info.ProgramId))
            {
                dto.ProgramId = GetInternalProgramId(info.ProgramId).ToString("N");
            }

            if (program != null)
            {
                dto.ProgramInfo = _dtoService.GetBaseItemDto(program, new DtoOptions());

                if (info.Status != RecordingStatus.Cancelled && info.Status != RecordingStatus.Error)
                {
                    dto.ProgramInfo.TimerId = dto.Id;
                    dto.ProgramInfo.Status  = info.Status.ToString();
                }

                dto.ProgramInfo.SeriesTimerId = dto.SeriesTimerId;

                if (!string.IsNullOrEmpty(info.SeriesTimerId))
                {
                    FillImages(dto.ProgramInfo, info.Name, info.SeriesId);
                }
            }

            if (channel != null)
            {
                dto.ChannelName = channel.Name;

                if (channel.HasImage(ImageType.Primary))
                {
                    dto.ChannelPrimaryImageTag = GetImageTag(channel);
                }
            }

            return(dto);
        }
示例#58
0
        /// <summary>
        /// Refreshes from provider.
        /// </summary>
        private async Task RefreshFromProvider(BaseItem item,
                                               IDynamicImageProvider provider,
                                               ImageRefreshOptions refreshOptions,
                                               TypeOptions savedOptions,
                                               LibraryOptions libraryOptions,
                                               ICollection <ImageType> downloadedImages,
                                               RefreshResult result,
                                               CancellationToken cancellationToken)
        {
            try
            {
                var images = provider.GetSupportedImages(item);

                foreach (var imageType in images)
                {
                    if (!IsEnabled(savedOptions, imageType, item))
                    {
                        continue;
                    }

                    if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType)))
                    {
                        _logger.LogDebug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);

                        var response = await provider.GetImage(item, imageType, cancellationToken).ConfigureAwait(false);

                        if (response.HasImage)
                        {
                            if (!string.IsNullOrEmpty(response.Path))
                            {
                                if (response.Protocol == MediaProtocol.Http)
                                {
                                    _logger.LogDebug("Setting image url into item {0}", item.Id);
                                    item.SetImage(new ItemImageInfo
                                    {
                                        Path = response.Path,
                                        Type = imageType
                                    }, 0);
                                }
                                else
                                {
                                    var mimeType = MimeTypes.GetMimeType(response.Path);

                                    var stream = _fileSystem.GetFileStream(response.Path, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read, true);

                                    await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false);
                                }
                            }
                            else
                            {
                                var mimeType = "image/" + response.Format.ToString().ToLower();

                                await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false);
                            }

                            downloadedImages.Add(imageType);
                            result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                result.ErrorMessage = ex.Message;
                _logger.LogError(ex, "Error in {provider}", provider.Name);
            }
        }
        private void PlayInternal(BaseItem item)
        {
            if (!item.ThemesLoaded)
            {
                item.LoadThemes();
            }

            var coll = new MediaCollection();

            if (item.ThemeVideos != null && item.ThemeVideos.Count > 0)
            {
                for (var i = 0; i < Config.Instance.ThemeBackgroundRepeat; i++)
                {
                    item.ThemeVideos.ForEach(v => coll.AddItem(v.Path));
                }

                IsPlayingVideo = true;
            }

            else if (item.ThemeSongs != null && item.ThemeSongs.Count > 0)
            {
                for (var i = 0; i < Config.Instance.ThemeBackgroundRepeat; i++)
                {
                    item.ThemeSongs.ForEach(a => coll.AddItem(a.Path));
                }

                IsPlayingVideo = false;
            }
            else if (Config.Instance.PlayTrailerAsBackground)
            {
                var movie = item as Movie;
                if (movie != null && movie.TrailerFiles.Any())
                {
                    for (var i = 0; i < Config.Instance.ThemeBackgroundRepeat; i++)
                    {
                        foreach (var trailerFile in movie.TrailerFiles)
                        {
                            coll.AddItem(trailerFile);
                        }
                    }

                    IsPlayingVideo = true;
                }
            }

            if (coll.Any())
            {
                Application.UIDeferredInvokeIfRequired(() =>
                {
                    //stop anything currently playing
                    PlaybackControllerHelper.Stop();

                    var mce              = Application.MediaCenterEnvironment;
                    mce.PropertyChanged += EnvironmentPropertyChange;

                    if (mce.PlayMedia(MediaType.MediaCollection, coll, false))
                    {
                        IsPlaying = true;
                        Application.CurrentInstance.ShowNowPlaying = IsPlayingVideo;
                        CurrentScope = item;
                    }
                    else
                    {
                        mce.PropertyChanged -= EnvironmentPropertyChange;
                    }
                });
            }
        }
 /// <inheritdoc />
 public bool Supports(BaseItem item) => item is Person;