aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities')
-rw-r--r--MediaBrowser.Controller/Entities/AggregateFolder.cs225
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs296
-rw-r--r--MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs31
-rw-r--r--MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs15
-rw-r--r--MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs9
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs272
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs345
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicGenre.cs158
-rw-r--r--MediaBrowser.Controller/Entities/AudioBook.cs71
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs2600
-rw-r--r--MediaBrowser.Controller/Entities/BasePluginFolder.cs54
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs74
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs387
-rw-r--r--MediaBrowser.Controller/Entities/DayOfWeekHelper.cs71
-rw-r--r--MediaBrowser.Controller/Entities/Extensions.cs46
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs1573
-rw-r--r--MediaBrowser.Controller/Entities/Game.cs130
-rw-r--r--MediaBrowser.Controller/Entities/GameGenre.cs141
-rw-r--r--MediaBrowser.Controller/Entities/GameSystem.cs101
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs153
-rw-r--r--MediaBrowser.Controller/Entities/ICollectionFolder.cs23
-rw-r--r--MediaBrowser.Controller/Entities/IHasAspectRatio.cs14
-rw-r--r--MediaBrowser.Controller/Entities/IHasDisplayOrder.cs15
-rw-r--r--MediaBrowser.Controller/Entities/IHasMediaSources.cs17
-rw-r--r--MediaBrowser.Controller/Entities/IHasMetadata.cs317
-rw-r--r--MediaBrowser.Controller/Entities/IHasProgramAttributes.cs20
-rw-r--r--MediaBrowser.Controller/Entities/IHasScreenshots.cs10
-rw-r--r--MediaBrowser.Controller/Entities/IHasSeries.cs20
-rw-r--r--MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs13
-rw-r--r--MediaBrowser.Controller/Entities/IHasStartDate.cs9
-rw-r--r--MediaBrowser.Controller/Entities/IHasTrailers.cs38
-rw-r--r--MediaBrowser.Controller/Entities/IHasUserData.cs27
-rw-r--r--MediaBrowser.Controller/Entities/IHiddenFromDisplay.cs12
-rw-r--r--MediaBrowser.Controller/Entities/IItemByName.cs17
-rw-r--r--MediaBrowser.Controller/Entities/IMetadataContainer.cs19
-rw-r--r--MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs12
-rw-r--r--MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs12
-rw-r--r--MediaBrowser.Controller/Entities/IVirtualFolderCreator.cs15
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs243
-rw-r--r--MediaBrowser.Controller/Entities/InternalPeopleQuery.cs21
-rw-r--r--MediaBrowser.Controller/Entities/ItemImageInfo.cs46
-rw-r--r--MediaBrowser.Controller/Entities/LinkedChild.cs65
-rw-r--r--MediaBrowser.Controller/Entities/Movies/BoxSet.cs216
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs197
-rw-r--r--MediaBrowser.Controller/Entities/MusicVideo.cs74
-rw-r--r--MediaBrowser.Controller/Entities/PeopleHelper.cs119
-rw-r--r--MediaBrowser.Controller/Entities/Person.cs229
-rw-r--r--MediaBrowser.Controller/Entities/Photo.cs110
-rw-r--r--MediaBrowser.Controller/Entities/PhotoAlbum.cs34
-rw-r--r--MediaBrowser.Controller/Entities/Share.cs15
-rw-r--r--MediaBrowser.Controller/Entities/SourceType.cs10
-rw-r--r--MediaBrowser.Controller/Entities/Studio.cs154
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs385
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs272
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs559
-rw-r--r--MediaBrowser.Controller/Entities/TagExtensions.cs35
-rw-r--r--MediaBrowser.Controller/Entities/Trailer.cs121
-rw-r--r--MediaBrowser.Controller/Entities/User.cs351
-rw-r--r--MediaBrowser.Controller/Entities/UserItemData.cs124
-rw-r--r--MediaBrowser.Controller/Entities/UserRootFolder.cs156
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs207
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs1778
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs806
-rw-r--r--MediaBrowser.Controller/Entities/Year.cs160
64 files changed, 0 insertions, 13849 deletions
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
deleted file mode 100644
index 00fac1eabd..0000000000
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Controller.Library;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Specialized folder that can have items added to it's children by external entities.
- /// Used for our RootFolder so plug-ins can add items.
- /// </summary>
- public class AggregateFolder : Folder
- {
- public AggregateFolder()
- {
- PhysicalLocationsList = EmptyStringArray;
- }
-
- [IgnoreDataMember]
- public override bool IsPhysicalRoot
- {
- get { return true; }
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// The _virtual children
- /// </summary>
- private readonly ConcurrentBag<BaseItem> _virtualChildren = new ConcurrentBag<BaseItem>();
-
- /// <summary>
- /// Gets the virtual children.
- /// </summary>
- /// <value>The virtual children.</value>
- public ConcurrentBag<BaseItem> VirtualChildren
- {
- get { return _virtualChildren; }
- }
-
- [IgnoreDataMember]
- public override string[] PhysicalLocations
- {
- get
- {
- return PhysicalLocationsList;
- }
- }
-
- public string[] PhysicalLocationsList { get; set; }
-
- protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
- {
- return CreateResolveArgs(directoryService, true).FileSystemChildren;
- }
-
- private Guid[] _childrenIds = null;
- private readonly object _childIdsLock = new object();
- protected override List<BaseItem> LoadChildren()
- {
- lock (_childIdsLock)
- {
- if (_childrenIds == null || _childrenIds.Length == 0)
- {
- var list = base.LoadChildren();
- _childrenIds = list.Select(i => i.Id).ToArray();
- return list;
- }
-
- return _childrenIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList();
- }
- }
-
- private void ClearCache()
- {
- lock (_childIdsLock)
- {
- _childrenIds = null;
- }
- }
-
- private bool _requiresRefresh;
- public override bool RequiresRefresh()
- {
- var changed = base.RequiresRefresh() || _requiresRefresh;
-
- if (!changed)
- {
- var locations = PhysicalLocations;
-
- var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations;
-
- if (!locations.SequenceEqual(newLocations))
- {
- changed = true;
- }
- }
-
- return changed;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- ClearCache();
-
- var changed = base.BeforeMetadataRefresh() || _requiresRefresh;
- _requiresRefresh = false;
- return changed;
- }
-
- private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations)
- {
- ClearCache();
-
- var path = ContainingFolderPath;
-
- var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
- {
- FileInfo = FileSystem.GetDirectoryInfo(path),
- Path = path,
- Parent = GetParent() as Folder
- };
-
- // Gather child folder and files
- if (args.IsDirectory)
- {
- var isPhysicalRoot = args.IsPhysicalRoot;
-
- // When resolving the root, we need it's grandchildren (children of user views)
- var flattenFolderDepth = isPhysicalRoot ? 2 : 0;
-
- var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, FileSystem, Logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
-
- // Need to remove subpaths that may have been resolved from shortcuts
- // Example: if \\server\movies exists, then strip out \\server\movies\action
- if (isPhysicalRoot)
- {
- files = LibraryManager.NormalizeRootPathList(files).ToArray();
- }
-
- args.FileSystemChildren = files;
- }
-
- _requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
- if (setPhysicalLocations)
- {
- PhysicalLocationsList = args.PhysicalLocations;
- }
-
- return args;
- }
-
- protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
- {
- return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren);
- }
-
- protected override async Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
- {
- ClearCache();
-
- await base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService)
- .ConfigureAwait(false);
-
- ClearCache();
- }
-
- /// <summary>
- /// Adds the virtual child.
- /// </summary>
- /// <param name="child">The child.</param>
- /// <exception cref="System.ArgumentNullException"></exception>
- public void AddVirtualChild(BaseItem child)
- {
- if (child == null)
- {
- throw new ArgumentNullException();
- }
-
- _virtualChildren.Add(child);
- }
-
- /// <summary>
- /// Finds the virtual child.
- /// </summary>
- /// <param name="id">The id.</param>
- /// <returns>BaseItem.</returns>
- /// <exception cref="System.ArgumentNullException">id</exception>
- public BaseItem FindVirtualChild(Guid id)
- {
- if (id == Guid.Empty)
- {
- throw new ArgumentNullException("id");
- }
-
- foreach (var child in _virtualChildren)
- {
- if (child.Id == id)
- {
- return child;
- }
- }
- return null;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
deleted file mode 100644
index 16fd75d2e9..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ /dev/null
@@ -1,296 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.MediaInfo;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Threading;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- /// <summary>
- /// Class Audio
- /// </summary>
- public class Audio : BaseItem,
- IHasAlbumArtist,
- IHasArtist,
- IHasMusicGenres,
- IHasLookupInfo<SongInfo>,
- IHasMediaSources
- {
- /// <summary>
- /// Gets or sets the artist.
- /// </summary>
- /// <value>The artist.</value>
- [IgnoreDataMember]
- public string[] Artists { get; set; }
-
- [IgnoreDataMember]
- public string[] AlbumArtists { get; set; }
-
- [IgnoreDataMember]
- public override bool EnableRefreshOnDateModifiedChange
- {
- get { return true; }
- }
-
- public Audio()
- {
- Artists = EmptyStringArray;
- AlbumArtists = EmptyStringArray;
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return false; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- protected override bool SupportsOwnedItems
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override Folder LatestItemsIndexContainer
- {
- get
- {
- return AlbumEntity;
- }
- }
-
- public override bool CanDownload()
- {
- var locationType = LocationType;
- return locationType != LocationType.Remote &&
- locationType != LocationType.Virtual;
- }
-
- [IgnoreDataMember]
- public string[] AllArtists
- {
- get
- {
- var list = new string[AlbumArtists.Length + Artists.Length];
-
- var index = 0;
- foreach (var artist in AlbumArtists)
- {
- list[index] = artist;
- index++;
- }
- foreach (var artist in Artists)
- {
- list[index] = artist;
- index++;
- }
-
- return list;
-
- }
- }
-
- [IgnoreDataMember]
- public MusicAlbum AlbumEntity
- {
- get { return FindParent<MusicAlbum>(); }
- }
-
- /// <summary>
- /// Gets the type of the media.
- /// </summary>
- /// <value>The type of the media.</value>
- [IgnoreDataMember]
- public override string MediaType
- {
- get
- {
- return Model.Entities.MediaType.Audio;
- }
- }
-
- /// <summary>
- /// Creates the name of the sort.
- /// </summary>
- /// <returns>System.String.</returns>
- protected override string CreateSortName()
- {
- return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("0000 - ") : "")
- + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
- }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- var songKey = IndexNumber.HasValue ? IndexNumber.Value.ToString("0000") : string.Empty;
-
-
- if (ParentIndexNumber.HasValue)
- {
- songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey;
- }
- songKey += Name;
-
- if (!string.IsNullOrWhiteSpace(Album))
- {
- songKey = Album + "-" + songKey;
- }
-
- var albumArtist = AlbumArtists.Length == 0 ? null : AlbumArtists[0];
- if (!string.IsNullOrWhiteSpace(albumArtist))
- {
- songKey = albumArtist + "-" + songKey;
- }
-
- list.Insert(0, songKey);
-
- return list;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- if (SourceType == SourceType.Library)
- {
- return UnratedItem.Music;
- }
- return base.GetBlockUnratedType();
- }
-
- public List<MediaStream> GetMediaStreams()
- {
- return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
- {
- ItemId = Id
- });
- }
-
- public List<MediaStream> GetMediaStreams(MediaStreamType type)
- {
- return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
- {
- ItemId = Id,
- Type = type
- });
- }
-
- public SongInfo GetLookupInfo()
- {
- var info = GetItemLookupInfo<SongInfo>();
-
- info.AlbumArtists = AlbumArtists;
- info.Album = Album;
- info.Artists = Artists;
-
- return info;
- }
-
- public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
- {
- if (SourceType == SourceType.Channel)
- {
- var sources = ChannelManager.GetStaticMediaSources(this, CancellationToken.None)
- .ToList();
-
- if (sources.Count > 0)
- {
- return sources;
- }
-
- var list = new List<MediaSourceInfo>
- {
- GetVersionInfo(this, enablePathSubstitution)
- };
-
- foreach (var mediaSource in list)
- {
- if (string.IsNullOrWhiteSpace(mediaSource.Path))
- {
- mediaSource.Type = MediaSourceType.Placeholder;
- }
- }
-
- return list;
- }
-
- var result = new List<MediaSourceInfo>
- {
- GetVersionInfo(this, enablePathSubstitution)
- };
-
- return result;
- }
-
- private static MediaSourceInfo GetVersionInfo(Audio i, bool enablePathSubstituion)
- {
- var locationType = i.LocationType;
-
- var info = new MediaSourceInfo
- {
- Id = i.Id.ToString("N"),
- Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File,
- MediaStreams = MediaSourceManager.GetMediaStreams(i.Id),
- Name = i.Name,
- Path = enablePathSubstituion ? GetMappedPath(i, i.Path, locationType) : i.Path,
- RunTimeTicks = i.RunTimeTicks,
- Container = i.Container,
- Size = i.Size
- };
-
- if (info.Protocol == MediaProtocol.File)
- {
- info.ETag = i.DateModified.Ticks.ToString(CultureInfo.InvariantCulture).GetMD5().ToString("N");
- }
-
- if (string.IsNullOrEmpty(info.Container))
- {
- if (!string.IsNullOrWhiteSpace(i.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual)
- {
- info.Container = System.IO.Path.GetExtension(i.Path).TrimStart('.');
- }
- }
-
- info.Bitrate = i.TotalBitrate;
- info.InferTotalBitrate();
-
- return info;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs
deleted file mode 100644
index 1b717b900a..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- public class AudioPodcast : Audio, IHasLookupInfo<SongInfo>
- {
- [IgnoreDataMember]
- public override bool SupportsPositionTicksResume
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return true;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs b/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
deleted file mode 100644
index b2dedada47..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- public interface IHasAlbumArtist
- {
- string[] AlbumArtists { get; set; }
- }
-
- public interface IHasArtist
- {
- string[] AllArtists { get; }
-
- string[] Artists { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs b/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs
deleted file mode 100644
index fdf939e359..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/IHasMusicGenres.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Generic;
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- public interface IHasMusicGenres
- {
- List<string> Genres { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
deleted file mode 100644
index acda9ae02b..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ /dev/null
@@ -1,272 +0,0 @@
-using System;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
-using System.Collections.Generic;
-using System.Linq;
-using MediaBrowser.Model.Serialization;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Library;
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- /// <summary>
- /// Class MusicAlbum
- /// </summary>
- public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
- {
- public string[] AlbumArtists { get; set; }
- public string[] Artists { get; set; }
-
- public MusicAlbum()
- {
- Artists = EmptyStringArray;
- AlbumArtists = EmptyStringArray;
- }
-
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public MusicArtist MusicArtist
- {
- get { return GetMusicArtist(new DtoOptions(true)); }
- }
-
- public MusicArtist GetMusicArtist(DtoOptions options)
- {
- var parents = GetParents();
- foreach (var parent in parents)
- {
- var artist = parent as MusicArtist;
- if (artist != null)
- {
- return artist;
- }
- }
-
- var name = AlbumArtist;
- if (!string.IsNullOrWhiteSpace(name))
- {
- return LibraryManager.GetArtist(name, options);
- }
- return null;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsCumulativeRunTimeTicks
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public string[] AllArtists
- {
- get
- {
- var list = new string[AlbumArtists.Length + Artists.Length];
-
- var index = 0;
- foreach (var artist in AlbumArtists)
- {
- list[index] = artist;
- index++;
- }
- foreach (var artist in Artists)
- {
- list[index] = artist;
- index++;
- }
-
- return list;
- }
- }
-
- [IgnoreDataMember]
- public string AlbumArtist
- {
- get { return AlbumArtists.Length == 0 ? null : AlbumArtists[0]; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return false; }
- }
-
- /// <summary>
- /// Gets the tracks.
- /// </summary>
- /// <value>The tracks.</value>
- [IgnoreDataMember]
- public IEnumerable<BaseItem> Tracks
- {
- get
- {
- return GetRecursiveChildren(i => i is Audio);
- }
- }
-
- protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
- {
- return Tracks;
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- var albumArtist = AlbumArtist;
- if (!string.IsNullOrWhiteSpace(albumArtist))
- {
- list.Insert(0, albumArtist + "-" + Name);
- }
-
- var id = this.GetProviderId(MetadataProviders.MusicBrainzAlbum);
-
- if (!string.IsNullOrWhiteSpace(id))
- {
- list.Insert(0, "MusicAlbum-Musicbrainz-" + id);
- }
-
- id = this.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup);
-
- if (!string.IsNullOrWhiteSpace(id))
- {
- list.Insert(0, "MusicAlbum-MusicBrainzReleaseGroup-" + id);
- }
-
- return list;
- }
-
- protected override bool GetBlockUnratedValue(UserPolicy config)
- {
- return config.BlockUnratedItems.Contains(UnratedItem.Music);
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Music;
- }
-
- public AlbumInfo GetLookupInfo()
- {
- var id = GetItemLookupInfo<AlbumInfo>();
-
- id.AlbumArtists = AlbumArtists;
-
- var artist = GetMusicArtist(new DtoOptions(false));
-
- if (artist != null)
- {
- id.ArtistProviderIds = artist.ProviderIds;
- }
-
- id.SongInfos = GetRecursiveChildren(i => i is Audio)
- .Cast<Audio>()
- .Select(i => i.GetLookupInfo())
- .ToList();
-
- var album = id.SongInfos
- .Select(i => i.Album)
- .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
-
- if (!string.IsNullOrWhiteSpace(album))
- {
- id.Name = album;
- }
-
- return id;
- }
-
- public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
- {
- var items = GetRecursiveChildren();
-
- var totalItems = items.Count;
- var numComplete = 0;
-
- var childUpdateType = ItemUpdateType.None;
-
- // Refresh songs
- foreach (var item in items)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- var updateType = await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- childUpdateType = childUpdateType | updateType;
-
- numComplete++;
- double percent = numComplete;
- percent /= totalItems;
- progress.Report(percent * 95);
- }
-
- var parentRefreshOptions = refreshOptions;
- if (childUpdateType > ItemUpdateType.None)
- {
- parentRefreshOptions = new MetadataRefreshOptions(refreshOptions);
- parentRefreshOptions.MetadataRefreshMode = MetadataRefreshMode.FullRefresh;
- }
-
- // Refresh current item
- await RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
-
- if (!refreshOptions.IsAutomated)
- {
- await RefreshArtists(refreshOptions, cancellationToken).ConfigureAwait(false);
- }
- }
-
- private async Task RefreshArtists(MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
- {
- var all = AllArtists;
- foreach (var i in all)
- {
- // This should not be necessary but we're seeing some cases of it
- if (string.IsNullOrWhiteSpace(i))
- {
- continue;
- }
-
- var artist = LibraryManager.GetArtist(i);
-
- if (!artist.IsAccessedByName)
- {
- continue;
- }
-
- await artist.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
deleted file mode 100644
index 19fe68e25f..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ /dev/null
@@ -1,345 +0,0 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using MediaBrowser.Model.Serialization;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- /// <summary>
- /// Class MusicArtist
- /// </summary>
- public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
- {
- [IgnoreDataMember]
- public bool IsAccessedByName
- {
- get { return ParentId == Guid.Empty; }
- }
-
- [IgnoreDataMember]
- public override bool IsFolder
- {
- get
- {
- return !IsAccessedByName;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsCumulativeRunTimeTicks
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool IsDisplayedAsFolder
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- public override bool CanDelete()
- {
- return !IsAccessedByName;
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- if (query.IncludeItemTypes.Length == 0)
- {
- query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
- query.ArtistIds = new[] { Id.ToString("N") };
- }
-
- return LibraryManager.GetItemList(query);
- }
-
- [IgnoreDataMember]
- public override IEnumerable<BaseItem> Children
- {
- get
- {
- if (IsAccessedByName)
- {
- return new List<BaseItem>();
- }
-
- return base.Children;
- }
- }
-
- public override int GetChildCount(User user)
- {
- if (IsAccessedByName)
- {
- return 0;
- }
- return base.GetChildCount(user);
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- if (IsAccessedByName)
- {
- return true;
- }
-
- return base.IsSaveLocalMetadataEnabled();
- }
-
- private readonly Task _cachedTask = Task.FromResult(true);
- protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
- {
- if (IsAccessedByName)
- {
- // Should never get in here anyway
- return _cachedTask;
- }
-
- return base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService);
- }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.InsertRange(0, GetUserDataKeys(this));
- return list;
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Gets the user data key.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <returns>System.String.</returns>
- private static List<string> GetUserDataKeys(MusicArtist item)
- {
- var list = new List<string>();
- var id = item.GetProviderId(MetadataProviders.MusicBrainzArtist);
-
- if (!string.IsNullOrEmpty(id))
- {
- list.Add("Artist-Musicbrainz-" + id);
- }
-
- list.Add("Artist-" + (item.Name ?? string.Empty).RemoveDiacritics());
- return list;
- }
- public override string CreatePresentationUniqueKey()
- {
- return "Artist-" + (Name ?? string.Empty).RemoveDiacritics();
- }
- protected override bool GetBlockUnratedValue(UserPolicy config)
- {
- return config.BlockUnratedItems.Contains(UnratedItem.Music);
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Music;
- }
-
- public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
- {
- var items = GetRecursiveChildren();
-
- var totalItems = items.Count;
- var numComplete = 0;
-
- var childUpdateType = ItemUpdateType.None;
-
- // Refresh songs
- foreach (var item in items)
- {
- if (!(item is Audio))
- {
- continue;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- var updateType = await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- childUpdateType = childUpdateType | updateType;
-
- numComplete++;
- double percent = numComplete;
- percent /= totalItems;
- progress.Report(percent * 100);
- }
-
- var parentRefreshOptions = refreshOptions;
- if (childUpdateType > ItemUpdateType.None)
- {
- parentRefreshOptions = new MetadataRefreshOptions(refreshOptions);
- parentRefreshOptions.MetadataRefreshMode = MetadataRefreshMode.FullRefresh;
- }
-
- // Refresh current item
- await RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
-
- // Refresh all non-songs
- foreach (var item in items)
- {
- if (item is Audio)
- {
- continue;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- var updateType = await item.RefreshMetadata(parentRefreshOptions, cancellationToken).ConfigureAwait(false);
-
- numComplete++;
- double percent = numComplete;
- percent /= totalItems;
- progress.Report(percent * 100);
- }
- }
-
- public ArtistInfo GetLookupInfo()
- {
- var info = GetItemLookupInfo<ArtistInfo>();
-
- info.SongInfos = GetRecursiveChildren(i => i is Audio)
- .Cast<Audio>()
- .Select(i => i.GetLookupInfo())
- .ToList();
-
- return info;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validName = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.ArtistsPath, validName);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- if (IsAccessedByName)
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (IsAccessedByName)
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
deleted file mode 100644
index 02e6520488..0000000000
--- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities.Audio
-{
- /// <summary>
- /// Class MusicGenre
- /// </summary>
- public class MusicGenre : BaseItem, IItemByName
- {
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
- return list;
- }
- public override string CreatePresentationUniqueKey()
- {
- return GetUserDataKeys()[0];
- }
-
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAncestors
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool IsDisplayedAsFolder
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- query.GenreIds = new[] { Id.ToString("N") };
- query.IncludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
-
- return LibraryManager.GetItemList(query);
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validName = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.MusicGenrePath, validName);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs
deleted file mode 100644
index 374bb21f74..0000000000
--- a/MediaBrowser.Controller/Entities/AudioBook.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class AudioBook : Audio.Audio, IHasSeries, IHasLookupInfo<SongInfo>
- {
- [IgnoreDataMember]
- public override bool SupportsPositionTicksResume
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public string SeriesPresentationUniqueKey { get; set; }
- [IgnoreDataMember]
- public string SeriesName { get; set; }
- [IgnoreDataMember]
- public Guid? SeriesId { get; set; }
-
- public string FindSeriesSortName()
- {
- return SeriesName;
- }
- public string FindSeriesName()
- {
- return SeriesName;
- }
- public string FindSeriesPresentationUniqueKey()
- {
- return SeriesPresentationUniqueKey;
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return null;
- }
-
- public Guid? FindSeriesId()
- {
- return SeriesId;
- }
-
- public override bool CanDownload()
- {
- var locationType = LocationType;
- return locationType != LocationType.Remote &&
- locationType != LocationType.Virtual;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Book;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
deleted file mode 100644
index 98899253e1..0000000000
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ /dev/null
@@ -1,2600 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Channels;
-using MediaBrowser.Controller.Collections;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Drawing;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Library;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Users;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Controller.MediaEncoding;
-using MediaBrowser.Controller.Sorting;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.Globalization;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.LiveTv;
-using MediaBrowser.Model.Providers;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class BaseItem
- /// </summary>
- public abstract class BaseItem : IHasMetadata, IHasLookupInfo<ItemLookupInfo>
- {
- protected static Guid[] EmptyGuidArray = new Guid[] { };
- protected static MetadataFields[] EmptyMetadataFieldsArray = new MetadataFields[] { };
- protected static string[] EmptyStringArray = new string[] { };
- protected static MediaUrl[] EmptyMediaUrlArray = new MediaUrl[] { };
- protected static ItemImageInfo[] EmptyItemImageInfoArray = new ItemImageInfo[] { };
- public static readonly LinkedChild[] EmptyLinkedChildArray = new LinkedChild[] { };
-
- protected BaseItem()
- {
- ThemeSongIds = EmptyGuidArray;
- ThemeVideoIds = EmptyGuidArray;
- Tags = EmptyStringArray;
- Genres = new List<string>();
- Studios = EmptyStringArray;
- ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- LockedFields = EmptyMetadataFieldsArray;
- ImageInfos = EmptyItemImageInfoArray;
- ProductionLocations = EmptyStringArray;
- }
-
- public static readonly char[] SlugReplaceChars = { '?', '/', '&' };
- public static char SlugChar = '-';
-
- /// <summary>
- /// The supported image extensions
- /// </summary>
- public static readonly string[] SupportedImageExtensions = { ".png", ".jpg", ".jpeg", ".tbn", ".gif" };
-
- public static readonly List<string> SupportedImageExtensionsList = SupportedImageExtensions.ToList();
-
- /// <summary>
- /// The trailer folder name
- /// </summary>
- public static string TrailerFolderName = "trailers";
- public static string ThemeSongsFolderName = "theme-music";
- public static string ThemeSongFilename = "theme";
- public static string ThemeVideosFolderName = "backdrops";
-
- [IgnoreDataMember]
- public Guid[] ThemeSongIds { get; set; }
- [IgnoreDataMember]
- public Guid[] ThemeVideoIds { get; set; }
-
- [IgnoreDataMember]
- public string PreferredMetadataCountryCode { get; set; }
- [IgnoreDataMember]
- public string PreferredMetadataLanguage { get; set; }
-
- public long? Size { get; set; }
- public string Container { get; set; }
-
- [IgnoreDataMember]
- public string Tagline { get; set; }
-
- [IgnoreDataMember]
- public virtual ItemImageInfo[] ImageInfos { get; set; }
-
- [IgnoreDataMember]
- public bool IsVirtualItem { get; set; }
-
- /// <summary>
- /// Gets or sets the album.
- /// </summary>
- /// <value>The album.</value>
- [IgnoreDataMember]
- public string Album { get; set; }
-
- /// <summary>
- /// Gets or sets the channel identifier.
- /// </summary>
- /// <value>The channel identifier.</value>
- [IgnoreDataMember]
- public string ChannelId { get; set; }
-
- [IgnoreDataMember]
- public virtual bool SupportsAddingToPlaylist
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool AlwaysScanInternalMetadataPath
- {
- get { return false; }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is in mixed folder.
- /// </summary>
- /// <value><c>true</c> if this instance is in mixed folder; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public bool IsInMixedFolder { get; set; }
-
- [IgnoreDataMember]
- public virtual bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsPositionTicksResume
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsRemoteImageDownloading
- {
- get
- {
- return true;
- }
- }
-
- private string _name;
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [IgnoreDataMember]
- public virtual string Name
- {
- get
- {
- return _name;
- }
- set
- {
- _name = value;
-
- // lazy load this again
- _sortName = null;
- }
- }
-
- [IgnoreDataMember]
- public bool IsUnaired
- {
- get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; }
- }
-
- [IgnoreDataMember]
- public int? TotalBitrate { get; set; }
- [IgnoreDataMember]
- public ExtraType? ExtraType { get; set; }
-
- [IgnoreDataMember]
- public bool IsThemeMedia
- {
- get
- {
- return ExtraType.HasValue && (ExtraType.Value == Model.Entities.ExtraType.ThemeSong || ExtraType.Value == Model.Entities.ExtraType.ThemeVideo);
- }
- }
-
- [IgnoreDataMember]
- public string OriginalTitle { get; set; }
-
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- [IgnoreDataMember]
- public Guid Id { get; set; }
-
- [IgnoreDataMember]
- public Guid OwnerId { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance is hd.
- /// </summary>
- /// <value><c>true</c> if this instance is hd; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public bool? IsHD { get; set; }
-
- /// <summary>
- /// Gets or sets the audio.
- /// </summary>
- /// <value>The audio.</value>
- [IgnoreDataMember]
- public ProgramAudio? Audio { get; set; }
-
- /// <summary>
- /// Return the id that should be used to key display prefs for this item.
- /// Default is based on the type for everything except actual generic folders.
- /// </summary>
- /// <value>The display prefs id.</value>
- [IgnoreDataMember]
- public virtual Guid DisplayPreferencesId
- {
- get
- {
- var thisType = GetType();
- return thisType == typeof(Folder) ? Id : thisType.FullName.GetMD5();
- }
- }
-
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- [IgnoreDataMember]
- public virtual string Path { get; set; }
-
- [IgnoreDataMember]
- public virtual SourceType SourceType
- {
- get
- {
- if (!string.IsNullOrWhiteSpace(ChannelId))
- {
- return SourceType.Channel;
- }
-
- return SourceType.Library;
- }
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- [IgnoreDataMember]
- public virtual string ContainingFolderPath
- {
- get
- {
- if (IsFolder)
- {
- return Path;
- }
-
- return FileSystem.GetDirectoryName(Path);
- }
- }
-
- /// <summary>
- /// Gets or sets the name of the service.
- /// </summary>
- /// <value>The name of the service.</value>
- [IgnoreDataMember]
- public string ServiceName { get; set; }
-
- /// <summary>
- /// If this content came from an external service, the id of the content on that service
- /// </summary>
- [IgnoreDataMember]
- public string ExternalId { get; set; }
-
- [IgnoreDataMember]
- public string ExternalSeriesId { get; set; }
-
- /// <summary>
- /// Gets or sets the etag.
- /// </summary>
- /// <value>The etag.</value>
- [IgnoreDataMember]
- public string ExternalEtag { get; set; }
-
- [IgnoreDataMember]
- public virtual bool IsHidden
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool IsOwnedItem
- {
- get
- {
- if (OwnerId != Guid.Empty)
- {
- return true;
- }
-
- // legacy
-
- // Local trailer, special feature, theme video, etc.
- // An item that belongs to another item but is not part of the Parent-Child tree
- // This is a hack for now relying on ExtraType. Eventually we may need to persist this
- if (ParentId == Guid.Empty && !IsFolder && LocationType == LocationType.FileSystem)
- {
- return true;
- }
-
- return false;
- }
- }
-
- public BaseItem GetOwner()
- {
- var ownerId = OwnerId;
- return ownerId == Guid.Empty ? null : LibraryManager.GetItemById(ownerId);
- }
-
- /// <summary>
- /// Gets or sets the type of the location.
- /// </summary>
- /// <value>The type of the location.</value>
- [IgnoreDataMember]
- public virtual LocationType LocationType
- {
- get
- {
- //if (IsOffline)
- //{
- // return LocationType.Offline;
- //}
-
- if (string.IsNullOrWhiteSpace(Path))
- {
- if (SourceType == SourceType.Channel)
- {
- return LocationType.Remote;
- }
-
- return LocationType.Virtual;
- }
-
- return FileSystem.IsPathFile(Path) ? LocationType.FileSystem : LocationType.Remote;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsLocalMetadata
- {
- get
- {
- if (SourceType == SourceType.Channel)
- {
- return false;
- }
-
- var locationType = LocationType;
-
- return locationType != LocationType.Remote && locationType != LocationType.Virtual;
- }
- }
-
- [IgnoreDataMember]
- public virtual string FileNameWithoutExtension
- {
- get
- {
- if (LocationType == LocationType.FileSystem)
- {
- return System.IO.Path.GetFileNameWithoutExtension(Path);
- }
-
- return null;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool EnableAlphaNumericSorting
- {
- get
- {
- return true;
- }
- }
-
- private List<Tuple<StringBuilder, bool>> GetSortChunks(string s1)
- {
- var list = new List<Tuple<StringBuilder, bool>>();
-
- int thisMarker = 0, thisNumericChunk = 0;
-
- while (thisMarker < s1.Length)
- {
- if (thisMarker >= s1.Length)
- {
- break;
- }
- char thisCh = s1[thisMarker];
-
- StringBuilder thisChunk = new StringBuilder();
-
- while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0])))
- {
- thisChunk.Append(thisCh);
- thisMarker++;
-
- if (thisMarker < s1.Length)
- {
- thisCh = s1[thisMarker];
- }
- }
-
- var isNumeric = thisChunk.Length > 0 && char.IsDigit(thisChunk[0]);
- list.Add(new Tuple<StringBuilder, bool>(thisChunk, isNumeric));
- }
-
- return list;
- }
-
- /// <summary>
- /// This is just a helper for convenience
- /// </summary>
- /// <value>The primary image path.</value>
- [IgnoreDataMember]
- public string PrimaryImagePath
- {
- get { return this.GetImagePath(ImageType.Primary); }
- }
-
- public virtual bool IsInternetMetadataEnabled()
- {
- return LibraryManager.GetLibraryOptions(this).EnableInternetProviders;
- }
-
- public virtual bool CanDelete()
- {
- if (SourceType == SourceType.Channel)
- {
- return false;
- }
-
- var locationType = LocationType;
- return locationType != LocationType.Remote &&
- locationType != LocationType.Virtual;
- }
-
- public virtual bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
- {
- if (user.Policy.EnableContentDeletion)
- {
- return true;
- }
-
- var allowed = user.Policy.EnableContentDeletionFromFolders;
- var collectionFolders = LibraryManager.GetCollectionFolders(this, allCollectionFolders);
-
- foreach (var folder in collectionFolders)
- {
- if (allowed.Contains(folder.Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
- {
- return true;
- }
- }
-
- return false;
- }
-
- public bool CanDelete(User user, List<Folder> allCollectionFolders)
- {
- return CanDelete() && IsAuthorizedToDelete(user, allCollectionFolders);
- }
-
- public bool CanDelete(User user)
- {
- var allCollectionFolders = LibraryManager.GetUserRootFolder().Children.OfType<Folder>().ToList();
- return CanDelete(user, allCollectionFolders);
- }
-
- public virtual bool CanDownload()
- {
- return false;
- }
-
- public virtual bool IsAuthorizedToDownload(User user)
- {
- return user.Policy.EnableContentDownloading;
- }
-
- public bool CanDownload(User user)
- {
- return CanDownload() && IsAuthorizedToDownload(user);
- }
-
- /// <summary>
- /// Gets or sets the date created.
- /// </summary>
- /// <value>The date created.</value>
- [IgnoreDataMember]
- public DateTime DateCreated { get; set; }
-
- /// <summary>
- /// Gets or sets the date modified.
- /// </summary>
- /// <value>The date modified.</value>
- [IgnoreDataMember]
- public DateTime DateModified { get; set; }
-
- [IgnoreDataMember]
- public DateTime DateLastSaved { get; set; }
-
- [IgnoreDataMember]
- public DateTime DateLastRefreshed { get; set; }
-
- [IgnoreDataMember]
- public virtual bool EnableRefreshOnDateModifiedChange
- {
- get { return false; }
- }
-
- /// <summary>
- /// The logger
- /// </summary>
- public static ILogger Logger { get; set; }
- public static ILibraryManager LibraryManager { get; set; }
- public static IServerConfigurationManager ConfigurationManager { get; set; }
- public static IProviderManager ProviderManager { get; set; }
- public static ILocalizationManager LocalizationManager { get; set; }
- public static IItemRepository ItemRepository { get; set; }
- public static IFileSystem FileSystem { get; set; }
- public static IUserDataManager UserDataManager { get; set; }
- public static ILiveTvManager LiveTvManager { get; set; }
- public static IChannelManager ChannelManager { get; set; }
- public static ICollectionManager CollectionManager { get; set; }
- public static IImageProcessor ImageProcessor { get; set; }
- public static IMediaSourceManager MediaSourceManager { get; set; }
- public static IMediaEncoder MediaEncoder { get; set; }
-
- /// <summary>
- /// Returns a <see cref="System.String" /> that represents this instance.
- /// </summary>
- /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
- public override string ToString()
- {
- return Name;
- }
-
- [IgnoreDataMember]
- public bool IsLocked { get; set; }
-
- /// <summary>
- /// Gets or sets the locked fields.
- /// </summary>
- /// <value>The locked fields.</value>
- [IgnoreDataMember]
- public MetadataFields[] LockedFields { get; set; }
-
- /// <summary>
- /// Gets the type of the media.
- /// </summary>
- /// <value>The type of the media.</value>
- [IgnoreDataMember]
- public virtual string MediaType
- {
- get
- {
- return null;
- }
- }
-
- [IgnoreDataMember]
- public virtual string[] PhysicalLocations
- {
- get
- {
- var locationType = LocationType;
-
- if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
- {
- return new string[] { };
- }
-
- return new[] { Path };
- }
- }
-
- private string _forcedSortName;
- /// <summary>
- /// Gets or sets the name of the forced sort.
- /// </summary>
- /// <value>The name of the forced sort.</value>
- [IgnoreDataMember]
- public string ForcedSortName
- {
- get { return _forcedSortName; }
- set { _forcedSortName = value; _sortName = null; }
- }
-
- private string _sortName;
- /// <summary>
- /// Gets the name of the sort.
- /// </summary>
- /// <value>The name of the sort.</value>
- [IgnoreDataMember]
- public string SortName
- {
- get
- {
- if (_sortName == null)
- {
- if (!string.IsNullOrWhiteSpace(ForcedSortName))
- {
- // Need the ToLower because that's what CreateSortName does
- _sortName = ModifySortChunks(ForcedSortName).ToLower();
- }
- else
- {
- _sortName = CreateSortName();
- }
- }
- return _sortName;
- }
- set
- {
- _sortName = value;
- }
- }
-
- public string GetInternalMetadataPath()
- {
- var basePath = ConfigurationManager.ApplicationPaths.InternalMetadataPath;
-
- return GetInternalMetadataPath(basePath);
- }
-
- protected virtual string GetInternalMetadataPath(string basePath)
- {
- if (SourceType == SourceType.Channel)
- {
- return System.IO.Path.Combine(basePath, "channels", ChannelId, Id.ToString("N"));
- }
-
- var idString = Id.ToString("N");
-
- basePath = System.IO.Path.Combine(basePath, "library");
-
- return System.IO.Path.Combine(basePath, idString.Substring(0, 2), idString);
- }
-
- /// <summary>
- /// Creates the name of the sort.
- /// </summary>
- /// <returns>System.String.</returns>
- protected virtual string CreateSortName()
- {
- if (Name == null) return null; //some items may not have name filled in properly
-
- if (!EnableAlphaNumericSorting)
- {
- return Name.TrimStart();
- }
-
- var sortable = Name.Trim().ToLower();
-
- foreach (var removeChar in ConfigurationManager.Configuration.SortRemoveCharacters)
- {
- sortable = sortable.Replace(removeChar, string.Empty);
- }
-
- foreach (var replaceChar in ConfigurationManager.Configuration.SortReplaceCharacters)
- {
- sortable = sortable.Replace(replaceChar, " ");
- }
-
- foreach (var search in ConfigurationManager.Configuration.SortRemoveWords)
- {
- // Remove from beginning if a space follows
- if (sortable.StartsWith(search + " "))
- {
- sortable = sortable.Remove(0, search.Length + 1);
- }
- // Remove from middle if surrounded by spaces
- sortable = sortable.Replace(" " + search + " ", " ");
-
- // Remove from end if followed by a space
- if (sortable.EndsWith(" " + search))
- {
- sortable = sortable.Remove(sortable.Length - (search.Length + 1));
- }
- }
-
- return ModifySortChunks(sortable);
- }
-
- private string ModifySortChunks(string name)
- {
- var chunks = GetSortChunks(name);
-
- var builder = new StringBuilder();
-
- foreach (var chunk in chunks)
- {
- var chunkBuilder = chunk.Item1;
-
- // This chunk is numeric
- if (chunk.Item2)
- {
- while (chunkBuilder.Length < 10)
- {
- chunkBuilder.Insert(0, '0');
- }
- }
-
- builder.Append(chunkBuilder);
- }
- //Logger.Debug("ModifySortChunks Start: {0} End: {1}", name, builder.ToString());
- return builder.ToString().RemoveDiacritics();
- }
-
- [IgnoreDataMember]
- public Guid ParentId { get; set; }
-
- /// <summary>
- /// Gets or sets the parent.
- /// </summary>
- /// <value>The parent.</value>
- [IgnoreDataMember]
- public Folder Parent
- {
- get { return GetParent() as Folder; }
- set
- {
-
- }
- }
-
- public void SetParent(Folder parent)
- {
- ParentId = parent == null ? Guid.Empty : parent.Id;
- }
-
- public BaseItem GetParent()
- {
- var parentId = ParentId;
- if (parentId != Guid.Empty)
- {
- return LibraryManager.GetItemById(parentId);
- }
-
- return null;
- }
-
- public IEnumerable<BaseItem> GetParents()
- {
- var parent = GetParent();
-
- while (parent != null)
- {
- yield return parent;
-
- parent = parent.GetParent();
- }
- }
-
- /// <summary>
- /// Finds a parent of a given type
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns>``0.</returns>
- public T FindParent<T>()
- where T : Folder
- {
- foreach (var parent in GetParents())
- {
- var item = parent as T;
- if (item != null)
- {
- return item;
- }
- }
- return null;
- }
-
- [IgnoreDataMember]
- public virtual Guid? DisplayParentId
- {
- get
- {
- var parentId = ParentId;
-
- if (parentId == Guid.Empty)
- {
- return null;
- }
- return parentId;
- }
- }
-
- [IgnoreDataMember]
- public BaseItem DisplayParent
- {
- get
- {
- var id = DisplayParentId;
- if (!id.HasValue || id.Value == Guid.Empty)
- {
- return null;
- }
- return LibraryManager.GetItemById(id.Value);
- }
- }
-
- /// <summary>
- /// When the item first debuted. For movies this could be premiere date, episodes would be first aired
- /// </summary>
- /// <value>The premiere date.</value>
- [IgnoreDataMember]
- public DateTime? PremiereDate { get; set; }
-
- /// <summary>
- /// Gets or sets the end date.
- /// </summary>
- /// <value>The end date.</value>
- [IgnoreDataMember]
- public DateTime? EndDate { get; set; }
-
- /// <summary>
- /// Gets or sets the official rating.
- /// </summary>
- /// <value>The official rating.</value>
- [IgnoreDataMember]
- public string OfficialRating { get; set; }
-
- [IgnoreDataMember]
- public int InheritedParentalRatingValue { get; set; }
-
- /// <summary>
- /// Gets or sets the critic rating.
- /// </summary>
- /// <value>The critic rating.</value>
- [IgnoreDataMember]
- public float? CriticRating { get; set; }
-
- /// <summary>
- /// Gets or sets the custom rating.
- /// </summary>
- /// <value>The custom rating.</value>
- [IgnoreDataMember]
- public string CustomRating { get; set; }
-
- /// <summary>
- /// Gets or sets the overview.
- /// </summary>
- /// <value>The overview.</value>
- [IgnoreDataMember]
- public string Overview { get; set; }
-
- /// <summary>
- /// Gets or sets the studios.
- /// </summary>
- /// <value>The studios.</value>
- [IgnoreDataMember]
- public string[] Studios { get; set; }
-
- /// <summary>
- /// Gets or sets the genres.
- /// </summary>
- /// <value>The genres.</value>
- [IgnoreDataMember]
- public List<string> Genres { get; set; }
-
- /// <summary>
- /// Gets or sets the tags.
- /// </summary>
- /// <value>The tags.</value>
- [IgnoreDataMember]
- public string[] Tags { get; set; }
-
- [IgnoreDataMember]
- public string[] ProductionLocations { get; set; }
-
- /// <summary>
- /// Gets or sets the home page URL.
- /// </summary>
- /// <value>The home page URL.</value>
- [IgnoreDataMember]
- public string HomePageUrl { get; set; }
-
- /// <summary>
- /// Gets or sets the community rating.
- /// </summary>
- /// <value>The community rating.</value>
- [IgnoreDataMember]
- public float? CommunityRating { get; set; }
-
- /// <summary>
- /// Gets or sets the run time ticks.
- /// </summary>
- /// <value>The run time ticks.</value>
- [IgnoreDataMember]
- public long? RunTimeTicks { get; set; }
-
- /// <summary>
- /// Gets or sets the production year.
- /// </summary>
- /// <value>The production year.</value>
- [IgnoreDataMember]
- public int? ProductionYear { get; set; }
-
- /// <summary>
- /// If the item is part of a series, this is it's number in the series.
- /// This could be episode number, album track number, etc.
- /// </summary>
- /// <value>The index number.</value>
- [IgnoreDataMember]
- public int? IndexNumber { get; set; }
-
- /// <summary>
- /// For an episode this could be the season number, or for a song this could be the disc number.
- /// </summary>
- /// <value>The parent index number.</value>
- [IgnoreDataMember]
- public int? ParentIndexNumber { get; set; }
-
- [IgnoreDataMember]
- public string OfficialRatingForComparison
- {
- get
- {
- var officialRating = OfficialRating;
- if (!string.IsNullOrWhiteSpace(officialRating))
- {
- return officialRating;
- }
-
- var parent = DisplayParent;
- if (parent != null)
- {
- return parent.OfficialRatingForComparison;
- }
-
- return null;
- }
- }
-
- [IgnoreDataMember]
- public string CustomRatingForComparison
- {
- get
- {
- var customRating = CustomRating;
- if (!string.IsNullOrWhiteSpace(customRating))
- {
- return customRating;
- }
-
- var parent = DisplayParent;
- if (parent != null)
- {
- return parent.CustomRatingForComparison;
- }
-
- return null;
- }
- }
-
- /// <summary>
- /// Gets the play access.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns>PlayAccess.</returns>
- public PlayAccess GetPlayAccess(User user)
- {
- if (!user.Policy.EnableMediaPlayback)
- {
- return PlayAccess.None;
- }
-
- //if (!user.IsParentalScheduleAllowed())
- //{
- // return PlayAccess.None;
- //}
-
- return PlayAccess.Full;
- }
-
- /// <summary>
- /// Loads the theme songs.
- /// </summary>
- /// <returns>List{Audio.Audio}.</returns>
- private static Audio.Audio[] LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
- {
- var files = fileSystemChildren.Where(i => i.IsDirectory)
- .Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => FileSystem.GetFiles(i.FullName))
- .ToList();
-
- // Support plex/xbmc convention
- files.AddRange(fileSystemChildren
- .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
- );
-
- return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
- .OfType<Audio.Audio>()
- .Select(audio =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(audio.Id) as Audio.Audio;
-
- if (dbItem != null)
- {
- audio = dbItem;
- }
- else
- {
- // item is new
- audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
- }
-
- return audio;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToArray();
- }
-
- /// <summary>
- /// Loads the video backdrops.
- /// </summary>
- /// <returns>List{Video}.</returns>
- private static Video[] LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
- {
- var files = fileSystemChildren.Where(i => i.IsDirectory)
- .Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => FileSystem.GetFiles(i.FullName));
-
- return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
- .OfType<Video>()
- .Select(item =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(item.Id) as Video;
-
- if (dbItem != null)
- {
- item = dbItem;
- }
- else
- {
- // item is new
- item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
- }
-
- return item;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToArray();
- }
-
- public Task RefreshMetadata(CancellationToken cancellationToken)
- {
- return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)), cancellationToken);
- }
-
- protected virtual void TriggerOnRefreshStart()
- {
-
- }
-
- protected virtual void TriggerOnRefreshComplete()
- {
-
- }
-
- /// <summary>
- /// Overrides the base implementation to refresh metadata for local trailers
- /// </summary>
- /// <param name="options">The options.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>true if a provider reports we changed</returns>
- public async Task<ItemUpdateType> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken)
- {
- TriggerOnRefreshStart();
-
- var locationType = LocationType;
-
- var requiresSave = false;
-
- if (SupportsOwnedItems)
- {
- try
- {
- var files = locationType != LocationType.Remote && locationType != LocationType.Virtual ?
- GetFileSystemChildren(options.DirectoryService).ToList() :
- new List<FileSystemMetadata>();
-
- var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false);
-
- if (ownedItemsChanged)
- {
- requiresSave = true;
- }
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error refreshing owned items for {0}", ex, Path ?? Name);
- }
- }
-
- try
- {
- var refreshOptions = requiresSave
- ? new MetadataRefreshOptions(options)
- {
- ForceSave = true
- }
- : options;
-
- return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
- }
- finally
- {
- TriggerOnRefreshComplete();
- }
- }
-
- [IgnoreDataMember]
- protected virtual bool SupportsOwnedItems
- {
- get { return IsFolder || GetParent() != null; }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsPeople
- {
- get { return false; }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsThemeMedia
- {
- get { return false; }
- }
-
- /// <summary>
- /// Refreshes owned items such as trailers, theme videos, special features, etc.
- /// Returns true or false indicating if changes were found.
- /// </summary>
- /// <param name="options"></param>
- /// <param name="fileSystemChildren"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var themeSongsChanged = false;
-
- var themeVideosChanged = false;
-
- var localTrailersChanged = false;
-
- if (LocationType == LocationType.FileSystem && GetParent() != null)
- {
- if (SupportsThemeMedia)
- {
- if (!IsInMixedFolder)
- {
- themeSongsChanged = await RefreshThemeSongs(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
-
- themeVideosChanged = await RefreshThemeVideos(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
- }
- }
-
- var hasTrailers = this as IHasTrailers;
- if (hasTrailers != null)
- {
- localTrailersChanged = await RefreshLocalTrailers(hasTrailers, options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
- }
- }
-
- return themeSongsChanged || themeVideosChanged || localTrailersChanged;
- }
-
- protected virtual FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
- {
- var path = ContainingFolderPath;
-
- return directoryService.GetFileSystemEntries(path);
- }
-
- private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var newItems = LibraryManager.FindTrailers(this, fileSystemChildren, options.DirectoryService).ToList();
-
- var newItemIds = newItems.Select(i => i.Id).ToArray();
-
- var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
- var ownerId = item.Id;
-
- var tasks = newItems.Select(i =>
- {
- var subOptions = new MetadataRefreshOptions(options);
-
- if (!i.ExtraType.HasValue ||
- i.ExtraType.Value != Model.Entities.ExtraType.Trailer ||
- i.OwnerId != ownerId ||
- i.ParentId != Guid.Empty)
- {
- i.ExtraType = Model.Entities.ExtraType.Trailer;
- i.OwnerId = ownerId;
- i.ParentId = Guid.Empty;
- subOptions.ForceSave = true;
- }
-
- return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
- });
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
- item.LocalTrailerIds = newItemIds;
-
- return itemsChanged;
- }
-
- private async Task<bool> RefreshThemeVideos(BaseItem item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService);
-
- var newThemeVideoIds = newThemeVideos.Select(i => i.Id).ToArray(newThemeVideos.Length);
-
- var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds);
-
- var ownerId = item.Id;
-
- var tasks = newThemeVideos.Select(i =>
- {
- var subOptions = new MetadataRefreshOptions(options);
-
- if (!i.ExtraType.HasValue ||
- i.ExtraType.Value != Model.Entities.ExtraType.ThemeVideo ||
- i.OwnerId != ownerId ||
- i.ParentId != Guid.Empty)
- {
- i.ExtraType = Model.Entities.ExtraType.ThemeVideo;
- i.OwnerId = ownerId;
- i.ParentId = Guid.Empty;
- subOptions.ForceSave = true;
- }
-
- return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
- });
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
- item.ThemeVideoIds = newThemeVideoIds;
-
- return themeVideosChanged;
- }
-
- /// <summary>
- /// Refreshes the theme songs.
- /// </summary>
- private async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService);
- var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToArray(newThemeSongs.Length);
-
- var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds);
-
- var ownerId = item.Id;
-
- var tasks = newThemeSongs.Select(i =>
- {
- var subOptions = new MetadataRefreshOptions(options);
-
- if (!i.ExtraType.HasValue ||
- i.ExtraType.Value != Model.Entities.ExtraType.ThemeSong ||
- i.OwnerId != ownerId ||
- i.ParentId != Guid.Empty)
- {
- i.ExtraType = Model.Entities.ExtraType.ThemeSong;
- i.OwnerId = ownerId;
- i.ParentId = Guid.Empty;
- subOptions.ForceSave = true;
- }
-
- return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
- });
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
- item.ThemeSongIds = newThemeSongIds;
-
- return themeSongsChanged;
- }
-
- /// <summary>
- /// Gets or sets the provider ids.
- /// </summary>
- /// <value>The provider ids.</value>
- [IgnoreDataMember]
- public Dictionary<string, string> ProviderIds { get; set; }
-
- [IgnoreDataMember]
- public virtual Folder LatestItemsIndexContainer
- {
- get { return null; }
- }
-
- public virtual double? GetDefaultPrimaryImageAspectRatio()
- {
- return null;
- }
-
- public virtual string CreatePresentationUniqueKey()
- {
- return Id.ToString("N");
- }
-
- [IgnoreDataMember]
- public string PresentationUniqueKey { get; set; }
-
- public string GetPresentationUniqueKey()
- {
- return PresentationUniqueKey ?? CreatePresentationUniqueKey();
- }
-
- public virtual bool RequiresRefresh()
- {
- return false;
- }
-
- public virtual List<string> GetUserDataKeys()
- {
- var list = new List<string>();
-
- if (SourceType == SourceType.Channel)
- {
- if (!string.IsNullOrWhiteSpace(ExternalId))
- {
- list.Add(ExternalId);
- }
- }
-
- list.Add(Id.ToString());
- return list;
- }
-
- internal virtual ItemUpdateType UpdateFromResolvedItem(BaseItem newItem)
- {
- var updateType = ItemUpdateType.None;
-
- if (IsInMixedFolder != newItem.IsInMixedFolder)
- {
- IsInMixedFolder = newItem.IsInMixedFolder;
- updateType |= ItemUpdateType.MetadataImport;
- }
-
- return updateType;
- }
-
- public void AfterMetadataRefresh()
- {
- _sortName = null;
- }
-
- /// <summary>
- /// Gets the preferred metadata language.
- /// </summary>
- /// <returns>System.String.</returns>
- public string GetPreferredMetadataLanguage()
- {
- string lang = PreferredMetadataLanguage;
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = GetParents()
- .Select(i => i.PreferredMetadataLanguage)
- .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
- }
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = LibraryManager.GetCollectionFolders(this)
- .Select(i => i.PreferredMetadataLanguage)
- .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
- }
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = LibraryManager.GetLibraryOptions(this).PreferredMetadataLanguage;
- }
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = ConfigurationManager.Configuration.PreferredMetadataLanguage;
- }
-
- return lang;
- }
-
- /// <summary>
- /// Gets the preferred metadata language.
- /// </summary>
- /// <returns>System.String.</returns>
- public string GetPreferredMetadataCountryCode()
- {
- string lang = PreferredMetadataCountryCode;
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = GetParents()
- .Select(i => i.PreferredMetadataCountryCode)
- .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
- }
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = LibraryManager.GetCollectionFolders(this)
- .Select(i => i.PreferredMetadataCountryCode)
- .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
- }
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = LibraryManager.GetLibraryOptions(this).MetadataCountryCode;
- }
-
- if (string.IsNullOrWhiteSpace(lang))
- {
- lang = ConfigurationManager.Configuration.MetadataCountryCode;
- }
-
- return lang;
- }
-
- public virtual bool IsSaveLocalMetadataEnabled()
- {
- if (SourceType == SourceType.Channel)
- {
- return false;
- }
-
- var libraryOptions = LibraryManager.GetLibraryOptions(this);
-
- return libraryOptions.SaveLocalMetadata;
- }
-
- /// <summary>
- /// Determines if a given user has access to this item
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns><c>true</c> if [is parental allowed] [the specified user]; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentNullException">user</exception>
- public bool IsParentalAllowed(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException("user");
- }
-
- if (!IsVisibleViaTags(user))
- {
- return false;
- }
-
- var maxAllowedRating = user.Policy.MaxParentalRating;
-
- if (maxAllowedRating == null)
- {
- return true;
- }
-
- var rating = CustomRatingForComparison;
-
- if (string.IsNullOrWhiteSpace(rating))
- {
- rating = OfficialRatingForComparison;
- }
-
- if (string.IsNullOrWhiteSpace(rating))
- {
- return !GetBlockUnratedValue(user.Policy);
- }
-
- var value = LocalizationManager.GetRatingLevel(rating);
-
- // Could not determine the integer value
- if (!value.HasValue)
- {
- var isAllowed = !GetBlockUnratedValue(user.Policy);
-
- if (!isAllowed)
- {
- Logger.Debug("{0} has an unrecognized parental rating of {1}.", Name, rating);
- }
-
- return isAllowed;
- }
-
- return value.Value <= maxAllowedRating.Value;
- }
-
- public int? GetParentalRatingValue()
- {
- var rating = CustomRating;
-
- if (string.IsNullOrWhiteSpace(rating))
- {
- rating = OfficialRating;
- }
-
- if (string.IsNullOrWhiteSpace(rating))
- {
- return null;
- }
-
- return LocalizationManager.GetRatingLevel(rating);
- }
-
- public int? GetInheritedParentalRatingValue()
- {
- var rating = CustomRatingForComparison;
-
- if (string.IsNullOrWhiteSpace(rating))
- {
- rating = OfficialRatingForComparison;
- }
-
- if (string.IsNullOrWhiteSpace(rating))
- {
- return null;
- }
-
- return LocalizationManager.GetRatingLevel(rating);
- }
-
- public List<string> GetInheritedTags()
- {
- var list = new List<string>();
- list.AddRange(Tags);
-
- foreach (var parent in GetParents())
- {
- list.AddRange(parent.Tags);
- }
-
- return list.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
- }
-
- private bool IsVisibleViaTags(User user)
- {
- var policy = user.Policy;
- if (policy.BlockedTags.Any(i => Tags.Contains(i, StringComparer.OrdinalIgnoreCase)))
- {
- return false;
- }
-
- return true;
- }
-
- protected virtual bool IsAllowTagFilterEnforced()
- {
- return true;
- }
-
- public virtual UnratedItem GetBlockUnratedType()
- {
- if (SourceType == SourceType.Channel)
- {
- return UnratedItem.ChannelContent;
- }
-
- return UnratedItem.Other;
- }
-
- /// <summary>
- /// Gets the block unrated value.
- /// </summary>
- /// <param name="config">The configuration.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- protected virtual bool GetBlockUnratedValue(UserPolicy config)
- {
- // Don't block plain folders that are unrated. Let the media underneath get blocked
- // Special folders like series and albums will override this method.
- if (IsFolder)
- {
- return false;
- }
- if (this is IItemByName)
- {
- return false;
- }
-
- return config.BlockUnratedItems.Contains(GetBlockUnratedType());
- }
-
- /// <summary>
- /// Determines if this folder should be visible to a given user.
- /// Default is just parental allowed. Can be overridden for more functionality.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns><c>true</c> if the specified user is visible; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentNullException">user</exception>
- public virtual bool IsVisible(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException("user");
- }
-
- return IsParentalAllowed(user);
- }
-
- public virtual bool IsVisibleStandalone(User user)
- {
- if (SourceType == SourceType.Channel)
- {
- return IsVisibleStandaloneInternal(user, false) && Channel.IsChannelVisible(this, user);
- }
-
- return IsVisibleStandaloneInternal(user, true);
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsInheritedParentImages
- {
- get { return false; }
- }
-
- protected bool IsVisibleStandaloneInternal(User user, bool checkFolders)
- {
- if (!IsVisible(user))
- {
- return false;
- }
-
- if (GetParents().Any(i => !i.IsVisible(user)))
- {
- return false;
- }
-
- if (checkFolders)
- {
- var topParent = GetParents().LastOrDefault() ?? this;
-
- if (string.IsNullOrWhiteSpace(topParent.Path))
- {
- return true;
- }
-
- var itemCollectionFolders = LibraryManager.GetCollectionFolders(this).Select(i => i.Id).ToList();
-
- if (itemCollectionFolders.Count > 0)
- {
- var userCollectionFolders = user.RootFolder.GetChildren(user, true).Select(i => i.Id).ToList();
- if (!itemCollectionFolders.Any(userCollectionFolders.Contains))
- {
- return false;
- }
- }
- }
-
- return true;
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is folder.
- /// </summary>
- /// <value><c>true</c> if this instance is folder; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public virtual bool IsFolder
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool IsDisplayedAsFolder
- {
- get
- {
- return false;
- }
- }
-
- public virtual string GetClientTypeName()
- {
- if (IsFolder && SourceType == SourceType.Channel && !(this is Channel))
- {
- return "ChannelFolderItem";
- }
-
- return GetType().Name;
- }
-
- /// <summary>
- /// Gets the linked child.
- /// </summary>
- /// <param name="info">The info.</param>
- /// <returns>BaseItem.</returns>
- protected BaseItem GetLinkedChild(LinkedChild info)
- {
- // First get using the cached Id
- if (info.ItemId.HasValue)
- {
- if (info.ItemId.Value == Guid.Empty)
- {
- return null;
- }
-
- var itemById = LibraryManager.GetItemById(info.ItemId.Value);
-
- if (itemById != null)
- {
- return itemById;
- }
- }
-
- var item = FindLinkedChild(info);
-
- // If still null, log
- if (item == null)
- {
- // Don't keep searching over and over
- info.ItemId = Guid.Empty;
- }
- else
- {
- // Cache the id for next time
- info.ItemId = item.Id;
- }
-
- return item;
- }
-
- private BaseItem FindLinkedChild(LinkedChild info)
- {
- if (!string.IsNullOrWhiteSpace(info.Path))
- {
- var itemByPath = LibraryManager.FindByPath(info.Path, null);
-
- if (itemByPath == null)
- {
- //Logger.Warn("Unable to find linked item at path {0}", info.Path);
- }
-
- return itemByPath;
- }
-
- return null;
- }
-
- [IgnoreDataMember]
- public virtual bool EnableRememberingTrackSelections
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Adds a studio to the item
- /// </summary>
- /// <param name="name">The name.</param>
- /// <exception cref="System.ArgumentNullException"></exception>
- public void AddStudio(string name)
- {
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentNullException("name");
- }
-
- var current = Studios;
-
- if (!current.Contains(name, StringComparer.OrdinalIgnoreCase))
- {
- if (current.Length == 0)
- {
- Studios = new[] { name };
- }
- else
- {
- var list = current.ToArray(current.Length + 1);
- list[list.Length - 1] = name;
- Studios = list;
- }
- }
- }
-
- public void SetStudios(IEnumerable<string> names)
- {
- Studios = names.Distinct().ToArray();
- }
-
- /// <summary>
- /// Adds a genre to the item
- /// </summary>
- /// <param name="name">The name.</param>
- /// <exception cref="System.ArgumentNullException"></exception>
- public void AddGenre(string name)
- {
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentNullException("name");
- }
-
- if (!Genres.Contains(name, StringComparer.OrdinalIgnoreCase))
- {
- Genres.Add(name);
- }
- }
-
- /// <summary>
- /// Marks the played.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <param name="datePlayed">The date played.</param>
- /// <param name="resetPosition">if set to <c>true</c> [reset position].</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public virtual void MarkPlayed(User user,
- DateTime? datePlayed,
- bool resetPosition)
- {
- if (user == null)
- {
- throw new ArgumentNullException();
- }
-
- var data = UserDataManager.GetUserData(user, this);
-
- if (datePlayed.HasValue)
- {
- // Increment
- data.PlayCount++;
- }
-
- // Ensure it's at least one
- data.PlayCount = Math.Max(data.PlayCount, 1);
-
- if (resetPosition)
- {
- data.PlaybackPositionTicks = 0;
- }
-
- data.LastPlayedDate = datePlayed ?? data.LastPlayedDate ?? DateTime.UtcNow;
- data.Played = true;
-
- UserDataManager.SaveUserData(user.Id, this, data, UserDataSaveReason.TogglePlayed, CancellationToken.None);
- }
-
- /// <summary>
- /// Marks the unplayed.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public virtual void MarkUnplayed(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException();
- }
-
- var data = UserDataManager.GetUserData(user, this);
-
- //I think it is okay to do this here.
- // if this is only called when a user is manually forcing something to un-played
- // then it probably is what we want to do...
- data.PlayCount = 0;
- data.PlaybackPositionTicks = 0;
- data.LastPlayedDate = null;
- data.Played = false;
-
- UserDataManager.SaveUserData(user.Id, this, data, UserDataSaveReason.TogglePlayed, CancellationToken.None);
- }
-
- /// <summary>
- /// Do whatever refreshing is necessary when the filesystem pertaining to this item has changed.
- /// </summary>
- /// <returns>Task.</returns>
- public virtual void ChangedExternally()
- {
- ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(FileSystem)
- {
- ValidateChildren = true,
-
- }, RefreshPriority.High);
- }
-
- /// <summary>
- /// Gets an image
- /// </summary>
- /// <param name="type">The type.</param>
- /// <param name="imageIndex">Index of the image.</param>
- /// <returns><c>true</c> if the specified type has image; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentException">Backdrops should be accessed using Item.Backdrops</exception>
- public bool HasImage(ImageType type, int imageIndex)
- {
- return GetImageInfo(type, imageIndex) != null;
- }
-
- public void SetImage(ItemImageInfo image, int index)
- {
- if (image.Type == ImageType.Chapter)
- {
- throw new ArgumentException("Cannot set chapter images using SetImagePath");
- }
-
- var existingImage = GetImageInfo(image.Type, index);
-
- if (existingImage != null)
- {
- existingImage.Path = image.Path;
- existingImage.DateModified = image.DateModified;
- existingImage.Width = image.Width;
- existingImage.Height = image.Height;
- }
-
- else
- {
- var currentCount = ImageInfos.Length;
- var newList = ImageInfos.ToArray(currentCount + 1);
- newList[currentCount] = image;
- ImageInfos = newList;
- }
- }
-
- public void SetImagePath(ImageType type, int index, FileSystemMetadata file)
- {
- if (type == ImageType.Chapter)
- {
- throw new ArgumentException("Cannot set chapter images using SetImagePath");
- }
-
- var image = GetImageInfo(type, index);
-
- if (image == null)
- {
- var currentCount = ImageInfos.Length;
- var newList = ImageInfos.ToArray(currentCount + 1);
- newList[currentCount] = GetImageInfo(file, type);
- ImageInfos = newList;
- }
- else
- {
- var imageInfo = GetImageInfo(file, type);
-
- image.Path = file.FullName;
- image.DateModified = imageInfo.DateModified;
-
- // reset these values
- image.Width = 0;
- image.Height = 0;
- }
- }
-
- /// <summary>
- /// Deletes the image.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <param name="index">The index.</param>
- /// <returns>Task.</returns>
- public void DeleteImage(ImageType type, int index)
- {
- var info = GetImageInfo(type, index);
-
- if (info == null)
- {
- // Nothing to do
- return;
- }
-
- // Remove it from the item
- RemoveImage(info);
-
- if (info.IsLocalFile)
- {
- FileSystem.DeleteFile(info.Path);
- }
-
- UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
- }
-
- public void RemoveImage(ItemImageInfo image)
- {
- RemoveImages(new List<ItemImageInfo> { image });
- }
-
- public void RemoveImages(List<ItemImageInfo> deletedImages)
- {
- ImageInfos = ImageInfos.Except(deletedImages).ToArray();
- }
-
- public virtual void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
- {
- LibraryManager.UpdateItem(this, updateReason, cancellationToken);
- }
-
- /// <summary>
- /// Validates that images within the item are still on the file system
- /// </summary>
- public bool ValidateImages(IDirectoryService directoryService)
- {
- var allFiles = ImageInfos
- .Where(i => i.IsLocalFile)
- .Select(i => FileSystem.GetDirectoryName(i.Path))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .SelectMany(i => directoryService.GetFilePaths(i))
- .ToList();
-
- var deletedImages = ImageInfos
- .Where(image => image.IsLocalFile && !allFiles.Contains(image.Path, StringComparer.OrdinalIgnoreCase))
- .ToList();
-
- if (deletedImages.Count > 0)
- {
- ImageInfos = ImageInfos.Except(deletedImages).ToArray();
- }
-
- return deletedImages.Count > 0;
- }
-
- /// <summary>
- /// Gets the image path.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="imageIndex">Index of the image.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.InvalidOperationException">
- /// </exception>
- /// <exception cref="System.ArgumentNullException">item</exception>
- public string GetImagePath(ImageType imageType, int imageIndex)
- {
- var info = GetImageInfo(imageType, imageIndex);
-
- return info == null ? null : info.Path;
- }
-
- /// <summary>
- /// Gets the image information.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="imageIndex">Index of the image.</param>
- /// <returns>ItemImageInfo.</returns>
- public ItemImageInfo GetImageInfo(ImageType imageType, int imageIndex)
- {
- if (imageType == ImageType.Chapter)
- {
- var chapter = ItemRepository.GetChapter(Id, imageIndex);
-
- if (chapter == null)
- {
- return null;
- }
-
- var path = chapter.ImagePath;
-
- if (string.IsNullOrWhiteSpace(path))
- {
- return null;
- }
-
- return new ItemImageInfo
- {
- Path = path,
- DateModified = chapter.ImageDateModified,
- Type = imageType
- };
- }
-
- return GetImages(imageType)
- .ElementAtOrDefault(imageIndex);
- }
-
- public IEnumerable<ItemImageInfo> GetImages(ImageType imageType)
- {
- if (imageType == ImageType.Chapter)
- {
- throw new ArgumentException("No image info for chapter images");
- }
-
- return ImageInfos.Where(i => i.Type == imageType);
- }
-
- /// <summary>
- /// Adds the images.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="images">The images.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- /// <exception cref="System.ArgumentException">Cannot call AddImages with chapter images</exception>
- public bool AddImages(ImageType imageType, List<FileSystemMetadata> images)
- {
- if (imageType == ImageType.Chapter)
- {
- throw new ArgumentException("Cannot call AddImages with chapter images");
- }
-
- var existingImages = GetImages(imageType)
- .ToList();
-
- var newImageList = new List<FileSystemMetadata>();
- var imageAdded = false;
- var imageUpdated = false;
-
- foreach (var newImage in images)
- {
- if (newImage == null)
- {
- throw new ArgumentException("null image found in list");
- }
-
- var existing = existingImages
- .FirstOrDefault(i => string.Equals(i.Path, newImage.FullName, StringComparison.OrdinalIgnoreCase));
-
- if (existing == null)
- {
- newImageList.Add(newImage);
- imageAdded = true;
- }
- else
- {
- if (existing.IsLocalFile)
- {
- var newDateModified = FileSystem.GetLastWriteTimeUtc(newImage);
-
- // If date changed then we need to reset saved image dimensions
- if (existing.DateModified != newDateModified && (existing.Width > 0 || existing.Height > 0))
- {
- existing.Width = 0;
- existing.Height = 0;
- imageUpdated = true;
- }
-
- existing.DateModified = newDateModified;
- }
- }
- }
-
- if (imageAdded || images.Count != existingImages.Count)
- {
- var newImagePaths = images.Select(i => i.FullName).ToList();
-
- var deleted = existingImages
- .Where(i => i.IsLocalFile && !newImagePaths.Contains(i.Path, StringComparer.OrdinalIgnoreCase) && !FileSystem.FileExists(i.Path))
- .ToList();
-
- if (deleted.Count > 0)
- {
- ImageInfos = ImageInfos.Except(deleted).ToArray();
- }
- }
-
- if (newImageList.Count > 0)
- {
- var currentCount = ImageInfos.Length;
- var newList = ImageInfos.ToArray(currentCount + newImageList.Count);
-
- foreach (var image in newImageList)
- {
- newList[currentCount] = GetImageInfo(image, imageType);
- currentCount++;
- }
-
- ImageInfos = newList;
- }
-
- return imageUpdated || newImageList.Count > 0;
- }
-
- private ItemImageInfo GetImageInfo(FileSystemMetadata file, ImageType type)
- {
- return new ItemImageInfo
- {
- Path = file.FullName,
- Type = type,
- DateModified = FileSystem.GetLastWriteTimeUtc(file)
- };
- }
-
- /// <summary>
- /// Gets the file system path to delete when the item is to be deleted
- /// </summary>
- /// <returns></returns>
- public virtual IEnumerable<FileSystemMetadata> GetDeletePaths()
- {
- return new[] {
- new FileSystemMetadata
- {
- FullName = Path,
- IsDirectory = IsFolder
- }
- }.Concat(GetLocalMetadataFilesToDelete());
- }
-
- protected List<FileSystemMetadata> GetLocalMetadataFilesToDelete()
- {
- if (IsFolder || !IsInMixedFolder)
- {
- return new List<FileSystemMetadata>();
- }
-
- var filename = System.IO.Path.GetFileNameWithoutExtension(Path);
- var extensions = new List<string> { ".nfo", ".xml", ".srt", ".vtt", ".sub", ".idx", ".txt", ".edl" };
- extensions.AddRange(SupportedImageExtensions);
-
- return FileSystem.GetFiles(FileSystem.GetDirectoryName(Path), extensions.ToArray(extensions.Count), false, false)
- .Where(i => System.IO.Path.GetFileNameWithoutExtension(i.FullName).StartsWith(filename, StringComparison.OrdinalIgnoreCase))
- .ToList();
- }
-
- public bool AllowsMultipleImages(ImageType type)
- {
- return type == ImageType.Backdrop || type == ImageType.Screenshot || type == ImageType.Chapter;
- }
-
- public void SwapImages(ImageType type, int index1, int index2)
- {
- if (!AllowsMultipleImages(type))
- {
- throw new ArgumentException("The change index operation is only applicable to backdrops and screenshots");
- }
-
- var info1 = GetImageInfo(type, index1);
- var info2 = GetImageInfo(type, index2);
-
- if (info1 == null || info2 == null)
- {
- // Nothing to do
- return;
- }
-
- if (!info1.IsLocalFile || !info2.IsLocalFile)
- {
- // TODO: Not supported yet
- return;
- }
-
- var path1 = info1.Path;
- var path2 = info2.Path;
-
- FileSystem.SwapFiles(path1, path2);
-
- // Refresh these values
- info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path);
- info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path);
-
- info1.Width = 0;
- info1.Height = 0;
- info2.Width = 0;
- info2.Height = 0;
-
- UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
- }
-
- public virtual bool IsPlayed(User user)
- {
- var userdata = UserDataManager.GetUserData(user, this);
-
- return userdata != null && userdata.Played;
- }
-
- public bool IsFavoriteOrLiked(User user)
- {
- var userdata = UserDataManager.GetUserData(user, this);
-
- return userdata != null && (userdata.IsFavorite || (userdata.Likes ?? false));
- }
-
- public virtual bool IsUnplayed(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException("user");
- }
-
- var userdata = UserDataManager.GetUserData(user, this);
-
- return userdata == null || !userdata.Played;
- }
-
- ItemLookupInfo IHasLookupInfo<ItemLookupInfo>.GetLookupInfo()
- {
- return GetItemLookupInfo<ItemLookupInfo>();
- }
-
- protected T GetItemLookupInfo<T>()
- where T : ItemLookupInfo, new()
- {
- return new T
- {
- MetadataCountryCode = GetPreferredMetadataCountryCode(),
- MetadataLanguage = GetPreferredMetadataLanguage(),
- Name = GetNameForMetadataLookup(),
- ProviderIds = ProviderIds,
- IndexNumber = IndexNumber,
- ParentIndexNumber = ParentIndexNumber,
- Year = ProductionYear,
- PremiereDate = PremiereDate
- };
- }
-
- protected virtual string GetNameForMetadataLookup()
- {
- return Name;
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public virtual bool BeforeMetadataRefresh()
- {
- _sortName = null;
-
- var hasChanges = false;
-
- if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path))
- {
- Name = FileSystem.GetFileNameWithoutExtension(Path);
- hasChanges = true;
- }
-
- return hasChanges;
- }
-
- protected static string GetMappedPath(BaseItem item, string path, LocationType locationType)
- {
- if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
- {
- return LibraryManager.GetPathAfterNetworkSubstitution(path, item);
- }
-
- return path;
- }
-
- public virtual void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields)
- {
- if (RunTimeTicks.HasValue)
- {
- double pct = RunTimeTicks.Value;
-
- if (pct > 0)
- {
- pct = userData.PlaybackPositionTicks / pct;
-
- if (pct > 0)
- {
- dto.PlayedPercentage = 100 * pct;
- }
- }
- }
- }
-
- protected Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
- {
- var newOptions = new MetadataRefreshOptions(options);
- newOptions.SearchResult = null;
-
- var item = this;
-
- if (copyTitleMetadata)
- {
- // Take some data from the main item, for querying purposes
- if (!item.Genres.SequenceEqual(ownedItem.Genres, StringComparer.Ordinal))
- {
- newOptions.ForceSave = true;
- ownedItem.Genres = item.Genres.ToList();
- }
- if (!item.Studios.SequenceEqual(ownedItem.Studios, StringComparer.Ordinal))
- {
- newOptions.ForceSave = true;
- ownedItem.Studios = item.Studios;
- }
- if (!item.ProductionLocations.SequenceEqual(ownedItem.ProductionLocations, StringComparer.Ordinal))
- {
- newOptions.ForceSave = true;
- ownedItem.ProductionLocations = item.ProductionLocations;
- }
- if (item.CommunityRating != ownedItem.CommunityRating)
- {
- ownedItem.CommunityRating = item.CommunityRating;
- newOptions.ForceSave = true;
- }
- if (item.CriticRating != ownedItem.CriticRating)
- {
- ownedItem.CriticRating = item.CriticRating;
- newOptions.ForceSave = true;
- }
- if (!string.Equals(item.Overview, ownedItem.Overview, StringComparison.Ordinal))
- {
- ownedItem.Overview = item.Overview;
- newOptions.ForceSave = true;
- }
- if (!string.Equals(item.OfficialRating, ownedItem.OfficialRating, StringComparison.Ordinal))
- {
- ownedItem.OfficialRating = item.OfficialRating;
- newOptions.ForceSave = true;
- }
- if (!string.Equals(item.CustomRating, ownedItem.CustomRating, StringComparison.Ordinal))
- {
- ownedItem.CustomRating = item.CustomRating;
- newOptions.ForceSave = true;
- }
- }
-
- return ownedItem.RefreshMetadata(newOptions, cancellationToken);
- }
-
- protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
- {
- var newOptions = new MetadataRefreshOptions(options);
- newOptions.SearchResult = null;
-
- var id = LibraryManager.GetNewItemId(path, typeof(Video));
-
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var video = LibraryManager.GetItemById(id) as Video;
-
- if (video == null)
- {
- video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
-
- newOptions.ForceSave = true;
- }
-
- //var parentId = Id;
- //if (!video.IsOwnedItem || video.ParentId != parentId)
- //{
- // video.IsOwnedItem = true;
- // video.ParentId = parentId;
- // newOptions.ForceSave = true;
- //}
-
- if (video == null)
- {
- return Task.FromResult(true);
- }
-
- return RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken);
- }
-
- public string GetEtag(User user)
- {
- var list = GetEtagValues(user);
-
- return string.Join("|", list.ToArray(list.Count)).GetMD5().ToString("N");
- }
-
- protected virtual List<string> GetEtagValues(User user)
- {
- return new List<string>
- {
- DateLastSaved.Ticks.ToString(CultureInfo.InvariantCulture)
- };
- }
-
- public virtual IEnumerable<Guid> GetAncestorIds()
- {
- return GetParents().Select(i => i.Id).Concat(LibraryManager.GetCollectionFolders(this).Select(i => i.Id));
- }
-
- public BaseItem GetTopParent()
- {
- if (IsTopParent)
- {
- return this;
- }
-
- foreach (var parent in GetParents())
- {
- if (parent.IsTopParent)
- {
- return parent;
- }
- }
- return null;
- }
-
- [IgnoreDataMember]
- public virtual bool IsTopParent
- {
- get
- {
- if (this is BasePluginFolder || this is Channel)
- {
- return true;
- }
-
- var view = this as UserView;
- if (view != null)
- {
- if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- if (string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- }
-
- if (GetParent() is AggregateFolder)
- {
- return true;
- }
-
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsAncestors
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool StopRefreshIfLocalMetadataFound
- {
- get
- {
- return true;
- }
- }
-
- public virtual IEnumerable<Guid> GetIdsForAncestorQuery()
- {
- return new[] { Id };
- }
-
- public virtual Task Delete(DeleteOptions options)
- {
- return LibraryManager.DeleteItem(this, options);
- }
-
- public virtual List<ExternalUrl> GetRelatedUrls()
- {
- return new List<ExternalUrl>();
- }
-
- public virtual double? GetRefreshProgress()
- {
- return null;
- }
-
- public virtual ItemUpdateType OnMetadataChanged()
- {
- var updateType = ItemUpdateType.None;
-
- var item = this;
-
- var inheritedParentalRatingValue = item.GetInheritedParentalRatingValue() ?? 0;
- if (inheritedParentalRatingValue != item.InheritedParentalRatingValue)
- {
- item.InheritedParentalRatingValue = inheritedParentalRatingValue;
- updateType |= ItemUpdateType.MetadataImport;
- }
-
- return updateType;
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs
deleted file mode 100644
index c06f1cef4c..0000000000
--- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Plugins derive from and export this class to create a folder that will appear in the root along
- /// with all the other actual physical folders in the system.
- /// </summary>
- public abstract class BasePluginFolder : Folder, ICollectionFolder
- {
- [IgnoreDataMember]
- public virtual string CollectionType
- {
- get { return null; }
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- //public override double? GetDefaultPrimaryImageAspectRatio()
- //{
- // double value = 16;
- // value /= 9;
-
- // return value;
- //}
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
deleted file mode 100644
index 45e3915ce2..0000000000
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.Linq;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class Book : BaseItem, IHasLookupInfo<BookInfo>, IHasSeries
- {
- [IgnoreDataMember]
- public override string MediaType
- {
- get
- {
- return Model.Entities.MediaType.Book;
- }
- }
-
- [IgnoreDataMember]
- public string SeriesPresentationUniqueKey { get; set; }
- [IgnoreDataMember]
- public string SeriesName { get; set; }
- [IgnoreDataMember]
- public Guid? SeriesId { get; set; }
-
- public string FindSeriesSortName()
- {
- return SeriesName;
- }
- public string FindSeriesName()
- {
- return SeriesName;
- }
- public string FindSeriesPresentationUniqueKey()
- {
- return SeriesPresentationUniqueKey;
- }
-
- public Guid? FindSeriesId()
- {
- return SeriesId;
- }
-
- public override bool CanDownload()
- {
- var locationType = LocationType;
- return locationType != LocationType.Remote &&
- locationType != LocationType.Virtual;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Book;
- }
-
- public BookInfo GetLookupInfo()
- {
- var info = GetItemLookupInfo<BookInfo>();
-
- if (string.IsNullOrEmpty(SeriesName))
- {
- info.SeriesName = GetParents().Select(i => i.Name).FirstOrDefault();
- }
- else
- {
- info.SeriesName = SeriesName;
- }
-
- return info;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
deleted file mode 100644
index 03fca60c89..0000000000
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ /dev/null
@@ -1,387 +0,0 @@
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Specialized Folder class that points to a subset of the physical folders in the system.
- /// It is created from the user-specific folders within the system root
- /// </summary>
- public class CollectionFolder : Folder, ICollectionFolder
- {
- public static IXmlSerializer XmlSerializer { get; set; }
-
- public CollectionFolder()
- {
- PhysicalLocationsList = EmptyStringArray;
- PhysicalFolderIds = EmptyGuidArray;
- }
-
- //public override double? GetDefaultPrimaryImageAspectRatio()
- //{
- // double value = 16;
- // value /= 9;
-
- // return value;
- //}
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public string CollectionType { get; set; }
-
- private static readonly Dictionary<string, LibraryOptions> LibraryOptions = new Dictionary<string, LibraryOptions>();
- public LibraryOptions GetLibraryOptions()
- {
- return GetLibraryOptions(Path);
- }
-
- private static LibraryOptions LoadLibraryOptions(string path)
- {
- try
- {
- var result = XmlSerializer.DeserializeFromFile(typeof(LibraryOptions), GetLibraryOptionsPath(path)) as LibraryOptions;
-
- if (result == null)
- {
- return new LibraryOptions();
- }
-
- return result;
- }
- catch (FileNotFoundException)
- {
- return new LibraryOptions();
- }
- catch (IOException)
- {
- return new LibraryOptions();
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error loading library options", ex);
-
- return new LibraryOptions();
- }
- }
-
- private static string GetLibraryOptionsPath(string path)
- {
- return System.IO.Path.Combine(path, "options.xml");
- }
-
- public void UpdateLibraryOptions(LibraryOptions options)
- {
- SaveLibraryOptions(Path, options);
- }
-
- public static LibraryOptions GetLibraryOptions(string path)
- {
- lock (LibraryOptions)
- {
- LibraryOptions options;
- if (!LibraryOptions.TryGetValue(path, out options))
- {
- options = LoadLibraryOptions(path);
- LibraryOptions[path] = options;
- }
-
- return options;
- }
- }
-
- public static void SaveLibraryOptions(string path, LibraryOptions options)
- {
- lock (LibraryOptions)
- {
- LibraryOptions[path] = options;
-
- XmlSerializer.SerializeToFile(options, GetLibraryOptionsPath(path));
- }
- }
-
- /// <summary>
- /// Allow different display preferences for each collection folder
- /// </summary>
- /// <value>The display prefs id.</value>
- [IgnoreDataMember]
- public override Guid DisplayPreferencesId
- {
- get
- {
- return Id;
- }
- }
-
- [IgnoreDataMember]
- public override string[] PhysicalLocations
- {
- get
- {
- return PhysicalLocationsList;
- }
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- public string[] PhysicalLocationsList { get; set; }
- public Guid[] PhysicalFolderIds { get; set; }
-
- protected override FileSystemMetadata[] GetFileSystemChildren(IDirectoryService directoryService)
- {
- return CreateResolveArgs(directoryService, true).FileSystemChildren;
- }
-
- private bool _requiresRefresh;
- public override bool RequiresRefresh()
- {
- var changed = base.RequiresRefresh() || _requiresRefresh;
-
- if (!changed)
- {
- var locations = PhysicalLocations;
-
- var newLocations = CreateResolveArgs(new DirectoryService(Logger, FileSystem), false).PhysicalLocations;
-
- if (!locations.SequenceEqual(newLocations))
- {
- changed = true;
- }
- }
-
- if (!changed)
- {
- var folderIds = PhysicalFolderIds;
-
- var newFolderIds = GetPhysicalFolders(false).Select(i => i.Id).ToList();
-
- if (!folderIds.SequenceEqual(newFolderIds))
- {
- changed = true;
- }
- }
-
- return changed;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- var changed = base.BeforeMetadataRefresh() || _requiresRefresh;
- _requiresRefresh = false;
- return changed;
- }
-
- public override double? GetRefreshProgress()
- {
- var folders = GetPhysicalFolders(true).ToList();
- double totalProgresses = 0;
- var foldersWithProgress = 0;
-
- foreach (var folder in folders)
- {
- var progress = ProviderManager.GetRefreshProgress(folder.Id);
- if (progress.HasValue)
- {
- totalProgresses += progress.Value;
- foldersWithProgress++;
- }
- }
-
- if (foldersWithProgress == 0)
- {
- return null;
- }
-
- return (totalProgresses / foldersWithProgress);
- }
-
- protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
- {
- return RefreshLinkedChildrenInternal(true);
- }
-
- private bool RefreshLinkedChildrenInternal(bool setFolders)
- {
- var physicalFolders = GetPhysicalFolders(false)
- .ToList();
-
- var linkedChildren = physicalFolders
- .SelectMany(c => c.LinkedChildren)
- .ToList();
-
- var changed = !linkedChildren.SequenceEqual(LinkedChildren, new LinkedChildComparer(FileSystem));
-
- LinkedChildren = linkedChildren.ToArray(linkedChildren.Count);
-
- var folderIds = PhysicalFolderIds;
- var newFolderIds = physicalFolders.Select(i => i.Id).ToArray();
-
- if (!folderIds.SequenceEqual(newFolderIds))
- {
- changed = true;
- if (setFolders)
- {
- PhysicalFolderIds = newFolderIds;
- }
- }
-
- return changed;
- }
-
- private ItemResolveArgs CreateResolveArgs(IDirectoryService directoryService, bool setPhysicalLocations)
- {
- var path = ContainingFolderPath;
-
- var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
- {
- FileInfo = FileSystem.GetDirectoryInfo(path),
- Path = path,
- Parent = GetParent() as Folder,
- CollectionType = CollectionType
- };
-
- // Gather child folder and files
- if (args.IsDirectory)
- {
- var isPhysicalRoot = args.IsPhysicalRoot;
-
- // When resolving the root, we need it's grandchildren (children of user views)
- var flattenFolderDepth = isPhysicalRoot ? 2 : 0;
-
- var files = FileData.GetFilteredFileSystemEntries(directoryService, args.Path, FileSystem, Logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf);
-
- // Need to remove subpaths that may have been resolved from shortcuts
- // Example: if \\server\movies exists, then strip out \\server\movies\action
- if (isPhysicalRoot)
- {
- files = LibraryManager.NormalizeRootPathList(files).ToArray();
- }
-
- args.FileSystemChildren = files;
- }
-
- _requiresRefresh = _requiresRefresh || !args.PhysicalLocations.SequenceEqual(PhysicalLocations);
- if (setPhysicalLocations)
- {
- PhysicalLocationsList = args.PhysicalLocations;
- }
-
- return args;
- }
-
- /// <summary>
- /// Compare our current children (presumably just read from the repo) with the current state of the file system and adjust for any changes
- /// ***Currently does not contain logic to maintain items that are unavailable in the file system***
- /// </summary>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="recursive">if set to <c>true</c> [recursive].</param>
- /// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
- /// <param name="refreshOptions">The refresh options.</param>
- /// <param name="directoryService">The directory service.</param>
- /// <returns>Task.</returns>
- protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
- {
- return Task.FromResult(true);
- }
-
- /// <summary>
- /// Our children are actually just references to the ones in the physical root...
- /// </summary>
- /// <value>The actual children.</value>
- [IgnoreDataMember]
- public override IEnumerable<BaseItem> Children
- {
- get { return GetActualChildren(); }
- }
-
- public IEnumerable<BaseItem> GetActualChildren()
- {
- return GetPhysicalFolders(true).SelectMany(c => c.Children);
- }
-
- public IEnumerable<Folder> GetPhysicalFolders()
- {
- return GetPhysicalFolders(true);
- }
-
- private IEnumerable<Folder> GetPhysicalFolders(bool enableCache)
- {
- if (enableCache)
- {
- return PhysicalFolderIds.Select(i => LibraryManager.GetItemById(i)).OfType<Folder>();
- }
-
- var rootChildren = LibraryManager.RootFolder.Children
- .OfType<Folder>()
- .ToList();
-
- return PhysicalLocations.Where(i => !FileSystem.AreEqual(i, Path)).SelectMany(i => GetPhysicalParents(i, rootChildren)).DistinctBy(i => i.Id);
- }
-
- private IEnumerable<Folder> GetPhysicalParents(string path, List<Folder> rootChildren)
- {
- var result = rootChildren
- .Where(i => FileSystem.AreEqual(i.Path, path))
- .ToList();
-
- if (result.Count == 0)
- {
- var folder = LibraryManager.FindByPath(path, true) as Folder;
-
- if (folder != null)
- {
- result.Add(folder);
- }
- }
-
- return result;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/DayOfWeekHelper.cs b/MediaBrowser.Controller/Entities/DayOfWeekHelper.cs
deleted file mode 100644
index 80ba206cc6..0000000000
--- a/MediaBrowser.Controller/Entities/DayOfWeekHelper.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using MediaBrowser.Model.Configuration;
-using System;
-using System.Collections.Generic;
-
-namespace MediaBrowser.Controller.Entities
-{
- public static class DayOfWeekHelper
- {
- public static List<DayOfWeek> GetDaysOfWeek(DynamicDayOfWeek day)
- {
- return GetDaysOfWeek(new List<DynamicDayOfWeek> { day });
- }
-
- public static List<DayOfWeek> GetDaysOfWeek(List<DynamicDayOfWeek> days)
- {
- var list = new List<DayOfWeek>();
-
- if (days.Contains(DynamicDayOfWeek.Sunday) ||
- days.Contains(DynamicDayOfWeek.Weekend) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Sunday);
- }
-
- if (days.Contains(DynamicDayOfWeek.Saturday) ||
- days.Contains(DynamicDayOfWeek.Weekend) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Saturday);
- }
-
- if (days.Contains(DynamicDayOfWeek.Monday) ||
- days.Contains(DynamicDayOfWeek.Weekday) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Monday);
- }
-
- if (days.Contains(DynamicDayOfWeek.Monday) ||
- days.Contains(DynamicDayOfWeek.Weekday) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Tuesday
- );
- }
-
- if (days.Contains(DynamicDayOfWeek.Wednesday) ||
- days.Contains(DynamicDayOfWeek.Weekday) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Wednesday);
- }
-
- if (days.Contains(DynamicDayOfWeek.Thursday) ||
- days.Contains(DynamicDayOfWeek.Weekday) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Thursday);
- }
-
- if (days.Contains(DynamicDayOfWeek.Friday) ||
- days.Contains(DynamicDayOfWeek.Weekday) ||
- days.Contains(DynamicDayOfWeek.Everyday))
- {
- list.Add(DayOfWeek.Friday);
- }
-
- return list;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Extensions.cs b/MediaBrowser.Controller/Entities/Extensions.cs
deleted file mode 100644
index 36855a86c1..0000000000
--- a/MediaBrowser.Controller/Entities/Extensions.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using MediaBrowser.Model.Entities;
-using System;
-using System.Linq;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Extensions
- /// </summary>
- public static class Extensions
- {
- /// <summary>
- /// Adds the trailer URL.
- /// </summary>
- public static void AddTrailerUrl(this IHasTrailers item, string url)
- {
- if (string.IsNullOrWhiteSpace(url))
- {
- throw new ArgumentNullException("url");
- }
-
- var current = item.RemoteTrailers.FirstOrDefault(i => string.Equals(i.Url, url, StringComparison.OrdinalIgnoreCase));
-
- if (current == null)
- {
- var mediaUrl = new MediaUrl
- {
- Url = url
- };
-
- if (item.RemoteTrailers.Length == 0)
- {
- item.RemoteTrailers = new[] { mediaUrl };
- }
- else
- {
- var list = item.RemoteTrailers.ToArray(item.RemoteTrailers.Length + 1);
- list[list.Length - 1] = mediaUrl;
-
- item.RemoteTrailers = list;
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
deleted file mode 100644
index 08b6a123d9..0000000000
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ /dev/null
@@ -1,1573 +0,0 @@
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Querying;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-using MediaBrowser.Controller.Channels;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Folder
- /// </summary>
- public class Folder : BaseItem
- {
- public static IUserManager UserManager { get; set; }
- public static IUserViewManager UserViewManager { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance is root.
- /// </summary>
- /// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value>
- public bool IsRoot { get; set; }
-
- public LinkedChild[] LinkedChildren { get; set; }
-
- [IgnoreDataMember]
- public DateTime? DateLastMediaAdded { get; set; }
-
- public Folder()
- {
- LinkedChildren = EmptyLinkedChildArray;
- }
-
- [IgnoreDataMember]
- public override bool SupportsThemeMedia
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public virtual bool IsPreSorted
- {
- get { return false; }
- }
-
- [IgnoreDataMember]
- public virtual bool IsPhysicalRoot
- {
- get { return false; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is folder.
- /// </summary>
- /// <value><c>true</c> if this instance is folder; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsFolder
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool IsDisplayedAsFolder
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsCumulativeRunTimeTicks
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsDateLastMediaAdded
- {
- get
- {
- return false;
- }
- }
-
- public override bool CanDelete()
- {
- if (IsRoot)
- {
- return false;
- }
-
- return base.CanDelete();
- }
-
- public override bool RequiresRefresh()
- {
- var baseResult = base.RequiresRefresh();
-
- if (SupportsCumulativeRunTimeTicks && !RunTimeTicks.HasValue)
- {
- baseResult = true;
- }
-
- return baseResult;
- }
-
- [IgnoreDataMember]
- public override string FileNameWithoutExtension
- {
- get
- {
- if (LocationType == LocationType.FileSystem)
- {
- return System.IO.Path.GetFileName(Path);
- }
-
- return null;
- }
- }
-
- protected override bool IsAllowTagFilterEnforced()
- {
- if (this is ICollectionFolder)
- {
- return false;
- }
- if (this is UserView)
- {
- return false;
- }
- return true;
- }
-
- [IgnoreDataMember]
- protected virtual bool SupportsShortcutChildren
- {
- get { return false; }
- }
-
- /// <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 void AddChild(BaseItem item, CancellationToken cancellationToken)
- {
- item.SetParent(this);
-
- if (item.Id == Guid.Empty)
- {
- item.Id = LibraryManager.GetNewItemId(item.Path, 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;
- }
-
- LibraryManager.CreateItem(item, cancellationToken);
- }
-
- /// <summary>
- /// Removes the child.
- /// </summary>
- /// <param name="item">The item.</param>
- public void RemoveChild(BaseItem item)
- {
- item.SetParent(null);
- }
-
- /// <summary>
- /// Gets the actual children.
- /// </summary>
- /// <value>The actual children.</value>
- [IgnoreDataMember]
- public virtual IEnumerable<BaseItem> Children
- {
- get
- {
- return LoadChildren();
- }
- }
-
- /// <summary>
- /// thread-safe access to all recursive children of this folder - without regard to user
- /// </summary>
- /// <value>The recursive children.</value>
- [IgnoreDataMember]
- public IEnumerable<BaseItem> RecursiveChildren
- {
- get { return GetRecursiveChildren(); }
- }
-
- public override bool IsVisible(User user)
- {
- if (this is ICollectionFolder && !(this is BasePluginFolder))
- {
- if (user.Policy.BlockedMediaFolders != null)
- {
- if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) ||
-
- // Backwards compatibility
- user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
- }
- else
- {
- if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
- }
- }
-
- return base.IsVisible(user);
- }
-
- /// <summary>
- /// Loads our children. Validation will occur externally.
- /// We want this sychronous.
- /// </summary>
- protected virtual List<BaseItem> LoadChildren()
- {
- //Logger.Debug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
- //just load our children from the repo - the library will be validated and maintained in other processes
- return GetCachedChildren();
- }
-
- public override double? GetRefreshProgress()
- {
- return ProviderManager.GetRefreshProgress(Id);
- }
-
- public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken)
- {
- return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem)));
- }
-
- /// <summary>
- /// Validates that the children of the folder still exist
- /// </summary>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="metadataRefreshOptions">The metadata refresh options.</param>
- /// <param name="recursive">if set to <c>true</c> [recursive].</param>
- /// <returns>Task.</returns>
- public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken, MetadataRefreshOptions metadataRefreshOptions, bool recursive = true)
- {
- return ValidateChildrenInternal(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService);
- }
-
- private Dictionary<Guid, BaseItem> GetActualChildrenDictionary()
- {
- var dictionary = new Dictionary<Guid, BaseItem>();
-
- var childrenList = Children.ToList();
-
- foreach (var child in childrenList)
- {
- var id = child.Id;
- if (dictionary.ContainsKey(id))
- {
- Logger.Error("Found folder containing items with duplicate id. Path: {0}, Child Name: {1}",
- Path ?? Name,
- child.Path ?? child.Name);
- }
- else
- {
- dictionary[id] = child;
- }
- }
-
- return dictionary;
- }
-
- protected override void TriggerOnRefreshStart()
- {
- }
-
- protected override void TriggerOnRefreshComplete()
- {
- }
-
- /// <summary>
- /// Validates the children internal.
- /// </summary>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="recursive">if set to <c>true</c> [recursive].</param>
- /// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
- /// <param name="refreshOptions">The refresh options.</param>
- /// <param name="directoryService">The directory service.</param>
- /// <returns>Task.</returns>
- protected virtual async Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
- {
- if (recursive)
- {
- ProviderManager.OnRefreshStart(this);
- }
-
- try
- {
- await ValidateChildrenInternal2(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService).ConfigureAwait(false);
- }
- finally
- {
- if (recursive)
- {
- ProviderManager.OnRefreshComplete(this);
- }
- }
- }
-
- private async Task ValidateChildrenInternal2(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
- {
- var locationType = LocationType;
-
- cancellationToken.ThrowIfCancellationRequested();
-
- var validChildren = new List<BaseItem>();
- var validChildrenNeedGeneration = false;
-
- var allLibraryPaths = LibraryManager
- .GetVirtualFolders()
- .SelectMany(i => i.Locations)
- .ToList();
-
- if (locationType != LocationType.Remote && locationType != LocationType.Virtual)
- {
- IEnumerable<BaseItem> nonCachedChildren;
-
- try
- {
- nonCachedChildren = GetNonCachedChildren(directoryService);
- }
- catch (IOException ex)
- {
- nonCachedChildren = new BaseItem[] { };
-
- Logger.ErrorException("Error getting file system entries for {0}", ex, Path);
- }
-
- if (nonCachedChildren == null) return; //nothing to validate
-
- progress.Report(5);
-
- if (recursive)
- {
- ProviderManager.OnRefreshProgress(this, 5);
- }
-
- //build a dictionary of the current children we have now by Id so we can compare quickly and easily
- var currentChildren = GetActualChildrenDictionary();
-
- //create a list for our validated children
- var newItems = new List<BaseItem>();
-
- cancellationToken.ThrowIfCancellationRequested();
-
- foreach (var child in nonCachedChildren)
- {
- BaseItem currentChild;
-
- if (currentChildren.TryGetValue(child.Id, out currentChild))
- {
- validChildren.Add(currentChild);
-
- if (currentChild.UpdateFromResolvedItem(child) > ItemUpdateType.None)
- {
- currentChild.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken);
- }
-
- continue;
- }
-
- // Brand new item - needs to be added
- child.SetParent(this);
- newItems.Add(child);
- validChildren.Add(child);
- }
-
- // If any items were added or removed....
- if (newItems.Count > 0 || currentChildren.Count != validChildren.Count)
- {
- // That's all the new and changed ones - now see if there are any that are missing
- var itemsRemoved = currentChildren.Values.Except(validChildren).ToList();
- var actualRemovals = new List<BaseItem>();
-
- foreach (var item in itemsRemoved)
- {
- var itemLocationType = item.LocationType;
- if (itemLocationType == LocationType.Virtual ||
- itemLocationType == LocationType.Remote)
- {
- }
-
- else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path, allLibraryPaths))
- {
- }
- else
- {
- actualRemovals.Add(item);
- }
- }
-
- if (actualRemovals.Count > 0)
- {
- foreach (var item in actualRemovals)
- {
- Logger.Debug("Removed item: " + item.Path);
-
- item.SetParent(null);
- await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false);
- LibraryManager.ReportItemRemoved(item, this);
- }
- }
-
- LibraryManager.CreateItems(newItems, this, cancellationToken);
- }
- }
- else
- {
- validChildrenNeedGeneration = true;
- }
-
- progress.Report(10);
-
- if (recursive)
- {
- ProviderManager.OnRefreshProgress(this, 10);
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- if (recursive)
- {
- using (var innerProgress = new ActionableProgress<double>())
- {
- var folder = this;
- innerProgress.RegisterAction(p =>
- {
- double newPct = .80 * p + 10;
- progress.Report(newPct);
- ProviderManager.OnRefreshProgress(folder, newPct);
- });
-
- if (validChildrenNeedGeneration)
- {
- validChildren = Children.ToList();
- validChildrenNeedGeneration = false;
- }
-
- await ValidateSubFolders(validChildren.OfType<Folder>().ToList(), directoryService, innerProgress, cancellationToken).ConfigureAwait(false);
- }
- }
-
- if (refreshChildMetadata)
- {
- progress.Report(90);
-
- if (recursive)
- {
- ProviderManager.OnRefreshProgress(this, 90);
- }
-
- var container = this as IMetadataContainer;
-
- using (var innerProgress = new ActionableProgress<double>())
- {
- var folder = this;
- innerProgress.RegisterAction(p =>
- {
- double newPct = .10 * p + 90;
- progress.Report(newPct);
- if (recursive)
- {
- ProviderManager.OnRefreshProgress(folder, newPct);
- }
- });
-
- if (container != null)
- {
- await container.RefreshAllMetadata(refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false);
- }
- else
- {
- if (validChildrenNeedGeneration)
- {
- validChildren = Children.ToList();
- }
-
- await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken);
- }
- }
- }
- }
-
- private async Task RefreshMetadataRecursive(List<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
- {
- var numComplete = 0;
- var count = children.Count;
- double currentPercent = 0;
-
- foreach (var child in children)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- using (var innerProgress = new ActionableProgress<double>())
- {
- // Avoid implicitly captured closure
- var currentInnerPercent = currentPercent;
-
- innerProgress.RegisterAction(p =>
- {
- double innerPercent = currentInnerPercent;
- innerPercent += p / (count);
- progress.Report(innerPercent);
- });
-
- await RefreshChildMetadata(child, refreshOptions, recursive && child.IsFolder, innerProgress, cancellationToken)
- .ConfigureAwait(false);
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= count;
- percent *= 100;
- currentPercent = percent;
-
- progress.Report(percent);
- }
- }
-
- private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
- {
- var container = child as IMetadataContainer;
-
- if (container != null)
- {
- await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false);
- }
- else
- {
- if (refreshOptions.RefreshItem(child))
- {
- await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- }
-
- if (recursive)
- {
- var folder = child as Folder;
-
- if (folder != null)
- {
- await folder.RefreshMetadataRecursive(folder.Children.ToList(), refreshOptions, true, progress, cancellationToken);
- }
- }
- }
- }
-
- /// <summary>
- /// Refreshes the children.
- /// </summary>
- /// <param name="children">The children.</param>
- /// <param name="directoryService">The directory service.</param>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
- {
- var numComplete = 0;
- var count = children.Count;
- double currentPercent = 0;
-
- foreach (var child in children)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- using (var innerProgress = new ActionableProgress<double>())
- {
- // Avoid implicitly captured closure
- var currentInnerPercent = currentPercent;
-
- innerProgress.RegisterAction(p =>
- {
- double innerPercent = currentInnerPercent;
- innerPercent += p / (count);
- progress.Report(innerPercent);
- });
-
- await child.ValidateChildrenInternal(innerProgress, cancellationToken, true, false, null, directoryService)
- .ConfigureAwait(false);
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= count;
- percent *= 100;
- currentPercent = percent;
-
- progress.Report(percent);
- }
- }
-
- public static bool IsPathOffline(string path, List<string> allLibraryPaths)
- {
- //if (FileSystem.FileExists(path))
- //{
- // return false;
- //}
-
- var originalPath = path;
-
- // Depending on whether the path is local or unc, it may return either null or '\' at the top
- while (!string.IsNullOrWhiteSpace(path) && path.Length > 1)
- {
- if (FileSystem.DirectoryExists(path))
- {
- return false;
- }
-
- if (allLibraryPaths.Contains(path, StringComparer.OrdinalIgnoreCase))
- {
- return true;
- }
-
- path = FileSystem.GetDirectoryName(path);
- }
-
- return allLibraryPaths.Any(i => ContainsPath(i, originalPath));
- }
-
- private static bool ContainsPath(string parent, string path)
- {
- return FileSystem.AreEqual(parent, path) || FileSystem.ContainsSubPath(parent, path);
- }
-
- /// <summary>
- /// Get the children of this folder from the actual file system
- /// </summary>
- /// <returns>IEnumerable{BaseItem}.</returns>
- protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
- {
- var collectionType = LibraryManager.GetContentType(this);
- var libraryOptions = LibraryManager.GetLibraryOptions(this);
-
- return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, libraryOptions, collectionType);
- }
-
- /// <summary>
- /// Get our children from the repo - stubbed for now
- /// </summary>
- /// <returns>IEnumerable{BaseItem}.</returns>
- protected List<BaseItem> GetCachedChildren()
- {
- return ItemRepository.GetItemList(new InternalItemsQuery
- {
- Parent = this,
- GroupByPresentationUniqueKey = false,
- DtoOptions = new DtoOptions(true)
- });
- }
-
- public virtual int GetChildCount(User user)
- {
- if (LinkedChildren.Length > 0)
- {
- if (!(this is ICollectionFolder))
- {
- return GetChildren(user, true).Count;
- }
- }
-
- var result = GetItems(new InternalItemsQuery(user)
- {
- Recursive = false,
- Limit = 0,
- Parent = this,
- DtoOptions = new DtoOptions(false)
- {
- EnableImages = false
- }
-
- });
-
- return result.TotalRecordCount;
- }
-
- public virtual int GetRecursiveChildCount(User user)
- {
- return GetItems(new InternalItemsQuery(user)
- {
- Recursive = true,
- IsFolder = false,
- IsVirtualItem = false,
- EnableTotalRecordCount = true,
- Limit = 0,
- DtoOptions = new DtoOptions(false)
- {
- EnableImages = false
- }
-
- }).TotalRecordCount;
- }
-
- public QueryResult<BaseItem> QueryRecursive(InternalItemsQuery query)
- {
- var user = query.User;
-
- if (!query.ForceDirect && RequiresPostFiltering(query))
- {
- IEnumerable<BaseItem> items;
- Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
-
- if (query.User == null)
- {
- items = GetRecursiveChildren(filter);
- }
- else
- {
- items = GetRecursiveChildren(user, query);
- }
-
- return PostFilterAndSort(items, query, true, true);
- }
-
- if (!(this is UserRootFolder) && !(this is AggregateFolder))
- {
- if (!query.ParentId.HasValue)
- {
- query.Parent = this;
- }
- }
-
- if (RequiresPostFiltering2(query))
- {
- return QueryWithPostFiltering2(query);
- }
-
- return LibraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> QueryWithPostFiltering2(InternalItemsQuery query)
- {
- var startIndex = query.StartIndex;
- var limit = query.Limit;
-
- query.StartIndex = null;
- query.Limit = null;
-
- var itemsList = LibraryManager.GetItemList(query);
- var user = query.User;
-
- if (user != null)
- {
- // needed for boxsets
- itemsList = itemsList.Where(i => i.IsVisibleStandalone(query.User)).ToList();
- }
-
- BaseItem[] returnItems;
- int totalCount = 0;
-
- if (query.EnableTotalRecordCount)
- {
- var itemsArray = itemsList.ToArray();
- totalCount = itemsArray.Length;
- returnItems = itemsArray;
- }
- else
- {
- returnItems = itemsList.ToArray();
- }
-
- if (limit.HasValue)
- {
- returnItems = returnItems.Skip(startIndex ?? 0).Take(limit.Value).ToArray();
- }
- else if (startIndex.HasValue)
- {
- returnItems = returnItems.Skip(startIndex.Value).ToArray();
- }
-
- return new QueryResult<BaseItem>
- {
- TotalRecordCount = totalCount,
- Items = returnItems.ToArray()
- };
- }
-
- private bool RequiresPostFiltering2(InternalItemsQuery query)
- {
- if (query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], typeof(BoxSet).Name, StringComparison.OrdinalIgnoreCase))
- {
- Logger.Debug("Query requires post-filtering due to BoxSet query");
- return true;
- }
-
- return false;
- }
-
- private bool RequiresPostFiltering(InternalItemsQuery query)
- {
- if (LinkedChildren.Length > 0)
- {
- if (!(this is ICollectionFolder))
- {
- Logger.Debug("Query requires post-filtering due to LinkedChildren. Type: " + GetType().Name);
- return true;
- }
- }
-
- if (query.IsInBoxSet.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsInBoxSet");
- return true;
- }
-
- // Filter by Video3DFormat
- if (query.Is3D.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to Is3D");
- return true;
- }
-
- if (query.HasOfficialRating.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasOfficialRating");
- return true;
- }
-
- if (query.IsPlaceHolder.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to IsPlaceHolder");
- return true;
- }
-
- if (query.HasSpecialFeature.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasSpecialFeature");
- return true;
- }
-
- if (query.HasSubtitles.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasSubtitles");
- return true;
- }
-
- if (query.HasTrailer.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to HasTrailer");
- return true;
- }
-
- // Filter by VideoType
- if (query.VideoTypes.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to VideoTypes");
- return true;
- }
-
- // Apply person filter
- if (query.ItemIdsFromPersonFilters != null)
- {
- Logger.Debug("Query requires post-filtering due to ItemIdsFromPersonFilters");
- return true;
- }
-
- if (UserViewBuilder.CollapseBoxSetItems(query, this, query.User, ConfigurationManager))
- {
- Logger.Debug("Query requires post-filtering due to CollapseBoxSetItems");
- return true;
- }
-
- if (!string.IsNullOrWhiteSpace(query.AdjacentTo))
- {
- Logger.Debug("Query requires post-filtering due to AdjacentTo");
- return true;
- }
-
- if (query.SeriesStatuses.Length > 0)
- {
- Logger.Debug("Query requires post-filtering due to SeriesStatuses");
- return true;
- }
-
- if (query.AiredDuringSeason.HasValue)
- {
- Logger.Debug("Query requires post-filtering due to AiredDuringSeason");
- return true;
- }
-
- if (query.IsPlayed.HasValue)
- {
- if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes.Contains(typeof(Series).Name))
- {
- Logger.Debug("Query requires post-filtering due to IsPlayed");
- return true;
- }
- }
-
- return false;
- }
-
- public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
- {
- if (query.ItemIds.Length > 0)
- {
- var result = LibraryManager.GetItemsResult(query);
-
- if (query.OrderBy.Length == 0)
- {
- var ids = query.ItemIds.ToList();
-
- // Try to preserve order
- result.Items = result.Items.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray();
- }
- return result;
- }
-
- return GetItemsInternal(query);
- }
-
- public BaseItem[] GetItemList(InternalItemsQuery query)
- {
- query.EnableTotalRecordCount = false;
-
- if (query.ItemIds.Length > 0)
- {
- var result = LibraryManager.GetItemList(query);
-
- if (query.OrderBy.Length == 0)
- {
- var ids = query.ItemIds.ToList();
-
- // Try to preserve order
- return result.OrderBy(i => ids.IndexOf(i.Id.ToString("N"))).ToArray();
- }
- return result.ToArray(result.Count);
- }
-
- return GetItemsInternal(query).Items;
- }
-
- protected virtual QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
- {
- if (SourceType == SourceType.Channel)
- {
- try
- {
- // Don't blow up here because it could cause parent screens with other content to fail
- return ChannelManager.GetChannelItemsInternal(new ChannelItemQuery
- {
- ChannelId = ChannelId,
- FolderId = Id.ToString("N"),
- Limit = query.Limit,
- StartIndex = query.StartIndex,
- UserId = query.User.Id.ToString("N"),
- OrderBy = query.OrderBy
-
- }, new SimpleProgress<double>(), CancellationToken.None).Result;
- }
- catch
- {
- // Already logged at lower levels
- return new QueryResult<BaseItem>();
- }
- }
-
- if (query.Recursive)
- {
- return QueryRecursive(query);
- }
-
- var user = query.User;
-
- Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
-
- IEnumerable<BaseItem> items;
-
- if (query.User == null)
- {
- items = query.Recursive
- ? GetRecursiveChildren(filter)
- : Children.Where(filter);
- }
- else
- {
- items = query.Recursive
- ? GetRecursiveChildren(user, query)
- : GetChildren(user, true).Where(filter);
- }
-
- return PostFilterAndSort(items, query, true, true);
- }
-
- protected QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, InternalItemsQuery query, bool collapseBoxSetItems, bool enableSorting)
- {
- return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager, collapseBoxSetItems, enableSorting);
- }
-
- public virtual List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
- {
- if (user == null)
- {
- throw new ArgumentNullException();
- }
-
- //the true root should return our users root folder children
- if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, includeLinkedChildren);
-
- var result = new Dictionary<Guid, BaseItem>();
-
- AddChildren(user, includeLinkedChildren, result, false, null);
-
- return result.Values.ToList();
- }
-
- protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
- {
- return Children;
- }
-
- /// <summary>
- /// Adds the children to list.
- /// </summary>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool recursive, InternalItemsQuery query)
- {
- foreach (var child in GetEligibleChildrenForRecursiveChildren(user))
- {
- if (child.IsVisible(user))
- {
- if (query == null || UserViewBuilder.FilterItem(child, query))
- {
- result[child.Id] = child;
- }
-
- if (recursive && child.IsFolder)
- {
- var folder = (Folder)child;
-
- folder.AddChildren(user, includeLinkedChildren, result, true, query);
- }
- }
- }
-
- if (includeLinkedChildren)
- {
- foreach (var child in GetLinkedChildren(user))
- {
- if (child.IsVisible(user))
- {
- if (query == null || UserViewBuilder.FilterItem(child, query))
- {
- result[child.Id] = child;
- }
- }
- }
- }
- }
-
- /// <summary>
- /// Gets allowed recursive children of an item
- /// </summary>
- /// <param name="user">The user.</param>
- /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param>
- /// <returns>IEnumerable{BaseItem}.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
- {
- return GetRecursiveChildren(user, null);
- }
-
- public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
- {
- if (user == null)
- {
- throw new ArgumentNullException("user");
- }
-
- var result = new Dictionary<Guid, BaseItem>();
-
- AddChildren(user, true, result, true, query);
-
- return result.Values;
- }
-
- /// <summary>
- /// Gets the recursive children.
- /// </summary>
- /// <returns>IList{BaseItem}.</returns>
- public IList<BaseItem> GetRecursiveChildren()
- {
- return GetRecursiveChildren(true);
- }
-
- public IList<BaseItem> GetRecursiveChildren(bool includeLinkedChildren)
- {
- return GetRecursiveChildren(i => true, includeLinkedChildren);
- }
-
- public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
- {
- return GetRecursiveChildren(filter, true);
- }
-
- public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter, bool includeLinkedChildren)
- {
- var result = new Dictionary<Guid, BaseItem>();
-
- AddChildrenToList(result, includeLinkedChildren, true, filter);
-
- return result.Values.ToList();
- }
-
- /// <summary>
- /// Adds the children to list.
- /// </summary>
- private void AddChildrenToList(Dictionary<Guid, BaseItem> result, bool includeLinkedChildren, bool recursive, Func<BaseItem, bool> filter)
- {
- foreach (var child in Children)
- {
- if (filter == null || filter(child))
- {
- result[child.Id] = child;
- }
-
- if (recursive && child.IsFolder)
- {
- var folder = (Folder)child;
-
- // We can only support includeLinkedChildren for the first folder, or we might end up stuck in a loop of linked items
- folder.AddChildrenToList(result, false, true, filter);
- }
- }
-
- if (includeLinkedChildren)
- {
- foreach (var child in GetLinkedChildren())
- {
- if (filter == null || filter(child))
- {
- result[child.Id] = child;
- }
- }
- }
- }
-
-
- /// <summary>
- /// Gets the linked children.
- /// </summary>
- /// <returns>IEnumerable{BaseItem}.</returns>
- public List<BaseItem> GetLinkedChildren()
- {
- var linkedChildren = LinkedChildren;
- var list = new List<BaseItem>(linkedChildren.Length);
-
- foreach (var i in linkedChildren)
- {
- var child = GetLinkedChild(i);
-
- if (child != null)
- {
- list.Add(child);
- }
- }
- return list;
- }
-
- protected virtual bool FilterLinkedChildrenPerUser
- {
- get
- {
- return false;
- }
- }
-
- public List<BaseItem> GetLinkedChildren(User user)
- {
- if (!FilterLinkedChildrenPerUser || user == null)
- {
- return GetLinkedChildren();
- }
-
- var linkedChildren = LinkedChildren;
- var list = new List<BaseItem>(linkedChildren.Length);
-
- if (linkedChildren.Length == 0)
- {
- return list;
- }
-
- var allUserRootChildren = user.RootFolder.Children.OfType<Folder>().ToList();
-
- var collectionFolderIds = allUserRootChildren
- .OfType<CollectionFolder>()
- .Where(i => i.IsVisible(user))
- .Select(i => i.Id)
- .ToList();
-
- foreach (var i in linkedChildren)
- {
- var child = GetLinkedChild(i);
-
- if (child == null)
- {
- continue;
- }
-
- var childOwner = child.IsOwnedItem ? (child.GetOwner() ?? child) : child;
-
- if (childOwner != null && !(child is IItemByName))
- {
- var childLocationType = childOwner.LocationType;
- if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual)
- {
- if (!childOwner.IsVisibleStandalone(user))
- {
- continue;
- }
- }
- else if (childLocationType == LocationType.FileSystem)
- {
- var itemCollectionFolderIds =
- LibraryManager.GetCollectionFolders(childOwner, allUserRootChildren).Select(f => f.Id);
-
- if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains))
- {
- continue;
- }
- }
- }
-
- list.Add(child);
- }
-
- return list;
- }
-
- /// <summary>
- /// Gets the linked children.
- /// </summary>
- /// <returns>IEnumerable{BaseItem}.</returns>
- public IEnumerable<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
- {
- return LinkedChildren
- .Select(i => new Tuple<LinkedChild, BaseItem>(i, GetLinkedChild(i)))
- .Where(i => i.Item2 != null);
- }
-
- [IgnoreDataMember]
- protected override bool SupportsOwnedItems
- {
- get
- {
- return base.SupportsOwnedItems || SupportsShortcutChildren;
- }
- }
-
- protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var changesFound = false;
-
- if (LocationType == LocationType.FileSystem)
- {
- if (RefreshLinkedChildren(fileSystemChildren))
- {
- changesFound = true;
- }
- }
-
- var baseHasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
-
- return baseHasChanges || changesFound;
- }
-
- /// <summary>
- /// Refreshes the linked children.
- /// </summary>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- protected virtual bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
- {
- if (SupportsShortcutChildren)
- {
- var newShortcutLinks = fileSystemChildren
- .Where(i => !i.IsDirectory && FileSystem.IsShortcut(i.FullName))
- .Select(i =>
- {
- try
- {
- Logger.Debug("Found shortcut at {0}", i.FullName);
-
- var resolvedPath = FileSystem.ResolveShortcut(i.FullName);
-
- if (!string.IsNullOrEmpty(resolvedPath))
- {
- return new LinkedChild
- {
- Path = resolvedPath,
- Type = LinkedChildType.Shortcut
- };
- }
-
- Logger.Error("Error resolving shortcut {0}", i.FullName);
-
- return null;
- }
- catch (IOException ex)
- {
- Logger.ErrorException("Error resolving shortcut {0}", ex, i.FullName);
- return null;
- }
- })
- .Where(i => i != null)
- .ToList();
-
- var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList();
-
- if (!newShortcutLinks.SequenceEqual(currentShortcutLinks, new LinkedChildComparer(FileSystem)))
- {
- Logger.Info("Shortcut links have changed for {0}", Path);
-
- newShortcutLinks.AddRange(LinkedChildren.Where(i => i.Type == LinkedChildType.Manual));
- LinkedChildren = newShortcutLinks.ToArray(newShortcutLinks.Count);
- return true;
- }
- }
-
- foreach (var child in LinkedChildren)
- {
- // Reset the cached value
- child.ItemId = null;
- }
-
- return false;
- }
-
- /// <summary>
- /// Marks the played.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <param name="datePlayed">The date played.</param>
- /// <param name="resetPosition">if set to <c>true</c> [reset position].</param>
- /// <returns>Task.</returns>
- public override void MarkPlayed(User user,
- DateTime? datePlayed,
- bool resetPosition)
- {
- var query = new InternalItemsQuery
- {
- User = user,
- Recursive = true,
- IsFolder = false,
- EnableTotalRecordCount = false
- };
-
- if (!user.Configuration.DisplayMissingEpisodes)
- {
- query.IsVirtualItem = false;
- }
-
- var itemsResult = GetItemList(query);
-
- // Sweep through recursively and update status
- foreach (var item in itemsResult)
- {
- if (item.IsVirtualItem)
- {
- // The querying doesn't support virtual unaired
- var episode = item as Episode;
- if (episode != null && episode.IsUnaired)
- {
- continue;
- }
- }
-
- item.MarkPlayed(user, datePlayed, resetPosition);
- }
- }
-
- /// <summary>
- /// Marks the unplayed.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns>Task.</returns>
- public override void MarkUnplayed(User user)
- {
- var itemsResult = GetItemList(new InternalItemsQuery
- {
- User = user,
- Recursive = true,
- IsFolder = false,
- EnableTotalRecordCount = false
-
- });
-
- // Sweep through recursively and update status
- foreach (var item in itemsResult)
- {
- item.MarkUnplayed(user);
- }
- }
-
- public override bool IsPlayed(User user)
- {
- var itemsResult = GetItemList(new InternalItemsQuery(user)
- {
- Recursive = true,
- IsFolder = false,
- IsVirtualItem = false,
- EnableTotalRecordCount = false
-
- });
-
- return itemsResult
- .All(i => i.IsPlayed(user));
- }
-
- public override bool IsUnplayed(User user)
- {
- return !IsPlayed(user);
- }
-
- [IgnoreDataMember]
- public virtual bool SupportsUserDataFromChildren
- {
- get
- {
- // These are just far too slow.
- if (this is ICollectionFolder)
- {
- return false;
- }
- if (this is UserView)
- {
- return false;
- }
- if (this is UserRootFolder)
- {
- return false;
- }
- if (this is Channel)
- {
- return false;
- }
- if (SourceType != SourceType.Library)
- {
- return false;
- }
- var iItemByName = this as IItemByName;
- if (iItemByName != null)
- {
- var hasDualAccess = this as IHasDualAccess;
- if (hasDualAccess == null || hasDualAccess.IsAccessedByName)
- {
- return false;
- }
- }
-
- return true;
- }
- }
-
- public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields)
- {
- if (!SupportsUserDataFromChildren)
- {
- return;
- }
-
- if (itemDto != null)
- {
- if (fields.Contains(ItemFields.RecursiveItemCount))
- {
- itemDto.RecursiveItemCount = GetRecursiveChildCount(user);
- }
- }
-
- if (SupportsPlayedStatus)
- {
- var unplayedQueryResult = GetItems(new InternalItemsQuery(user)
- {
- Recursive = true,
- IsFolder = false,
- IsVirtualItem = false,
- EnableTotalRecordCount = true,
- Limit = 0,
- IsPlayed = false,
- DtoOptions = new DtoOptions(false)
- {
- EnableImages = false
- }
-
- });
-
- double unplayedCount = unplayedQueryResult.TotalRecordCount;
-
- dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
-
- if (itemDto != null && itemDto.RecursiveItemCount.HasValue)
- {
- if (itemDto.RecursiveItemCount.Value > 0)
- {
- var unplayedPercentage = (unplayedCount / itemDto.RecursiveItemCount.Value) * 100;
- dto.PlayedPercentage = 100 - unplayedPercentage;
- dto.Played = dto.PlayedPercentage.Value >= 100;
- }
- }
- else
- {
- dto.Played = (dto.UnplayedItemCount ?? 0) == 0;
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
deleted file mode 100644
index bead0ef955..0000000000
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class Game : BaseItem, IHasTrailers, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
- {
- public Game()
- {
- MultiPartGameFiles = EmptyStringArray;
- RemoteTrailers = EmptyMediaUrlArray;
- LocalTrailerIds = EmptyGuidArray;
- RemoteTrailerIds = EmptyGuidArray;
- }
-
- public Guid[] LocalTrailerIds { get; set; }
- public Guid[] RemoteTrailerIds { get; set; }
-
- public override bool CanDownload()
- {
- var locationType = LocationType;
- return locationType != LocationType.Remote &&
- locationType != LocationType.Virtual;
- }
-
- [IgnoreDataMember]
- public override bool SupportsThemeMedia
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return false; }
- }
-
- /// <summary>
- /// Gets or sets the remote trailers.
- /// </summary>
- /// <value>The remote trailers.</value>
- public MediaUrl[] RemoteTrailers { get; set; }
-
- /// <summary>
- /// Gets the type of the media.
- /// </summary>
- /// <value>The type of the media.</value>
- [IgnoreDataMember]
- public override string MediaType
- {
- get { return Model.Entities.MediaType.Game; }
- }
-
- /// <summary>
- /// Gets or sets the players supported.
- /// </summary>
- /// <value>The players supported.</value>
- public int? PlayersSupported { get; set; }
-
- /// <summary>
- /// Gets a value indicating whether this instance is place holder.
- /// </summary>
- /// <value><c>true</c> if this instance is place holder; otherwise, <c>false</c>.</value>
- public bool IsPlaceHolder { get; set; }
-
- /// <summary>
- /// Gets or sets the game system.
- /// </summary>
- /// <value>The game system.</value>
- public string GameSystem { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance is multi part.
- /// </summary>
- /// <value><c>true</c> if this instance is multi part; otherwise, <c>false</c>.</value>
- public bool IsMultiPart { get; set; }
-
- /// <summary>
- /// Holds the paths to the game files in the event this is a multipart game
- /// </summary>
- public string[] MultiPartGameFiles { get; set; }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
- var id = this.GetProviderId(MetadataProviders.Gamesdb);
-
- if (!string.IsNullOrEmpty(id))
- {
- list.Insert(0, "Game-Gamesdb-" + id);
- }
- return list;
- }
-
- public override IEnumerable<FileSystemMetadata> GetDeletePaths()
- {
- if (!IsInMixedFolder)
- {
- return new[] {
- new FileSystemMetadata
- {
- FullName = FileSystem.GetDirectoryName(Path),
- IsDirectory = true
- }
- };
- }
-
- return base.GetDeletePaths();
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Game;
- }
-
- public GameInfo GetLookupInfo()
- {
- var id = GetItemLookupInfo<GameInfo>();
-
- id.GameSystem = GameSystem;
-
- return id;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs
deleted file mode 100644
index 6dc85f3e53..0000000000
--- a/MediaBrowser.Controller/Entities/GameGenre.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class GameGenre : BaseItem, IItemByName
- {
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
- return list;
- }
-
- public override string CreatePresentationUniqueKey()
- {
- return GetUserDataKeys()[0];
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAncestors
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- query.GenreIds = new[] { Id.ToString("N") };
- query.IncludeItemTypes = new[] { typeof(Game).Name };
-
- return LibraryManager.GetItemList(query);
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validName = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GameGenrePath, validName);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs
deleted file mode 100644
index c940b59531..0000000000
--- a/MediaBrowser.Controller/Entities/GameSystem.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Users;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class GameSystem
- /// </summary>
- public class GameSystem : Folder, IHasLookupInfo<GameSystemInfo>
- {
- /// <summary>
- /// Return the id that should be used to key display prefs for this item.
- /// Default is based on the type for everything except actual generic folders.
- /// </summary>
- /// <value>The display prefs id.</value>
- [IgnoreDataMember]
- public override Guid DisplayPreferencesId
- {
- get
- {
- return Id;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 16;
- value /= 9;
-
- return value;
- }
-
- /// <summary>
- /// Gets or sets the game system.
- /// </summary>
- /// <value>The game system.</value>
- public string GameSystemName { get; set; }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- if (!string.IsNullOrEmpty(GameSystemName))
- {
- list.Insert(0, "GameSystem-" + GameSystemName);
- }
- return list;
- }
-
- protected override bool GetBlockUnratedValue(UserPolicy config)
- {
- // Don't block. Determine by game
- return false;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Game;
- }
-
- public GameSystemInfo GetLookupInfo()
- {
- var id = GetItemLookupInfo<GameSystemInfo>();
-
- id.Path = Path;
-
- return id;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
deleted file mode 100644
index 569a0dfb8b..0000000000
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Controller.Entities.Audio;
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Genre
- /// </summary>
- public class Genre : BaseItem, IItemByName
- {
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
- return list;
- }
- public override string CreatePresentationUniqueKey()
- {
- return GetUserDataKeys()[0];
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- [IgnoreDataMember]
- public override bool IsDisplayedAsFolder
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAncestors
- {
- get
- {
- return false;
- }
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- query.GenreIds = new[] { Id.ToString("N") };
- query.ExcludeItemTypes = new[] { typeof(Game).Name, typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
-
- return LibraryManager.GetItemList(query);
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validName = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.GenrePath, validName);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/ICollectionFolder.cs b/MediaBrowser.Controller/Entities/ICollectionFolder.cs
deleted file mode 100644
index b70ad322d9..0000000000
--- a/MediaBrowser.Controller/Entities/ICollectionFolder.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// This is just a marker interface to denote top level folders
- /// </summary>
- public interface ICollectionFolder
- {
- string CollectionType { get; }
- string Path { get; }
- string Name { get; }
- Guid Id { get; }
- string[] PhysicalLocations { get; }
- }
-
- public interface ISupportsUserSpecificView
- {
- bool EnableUserSpecificView { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasAspectRatio.cs b/MediaBrowser.Controller/Entities/IHasAspectRatio.cs
deleted file mode 100644
index 5aecf4eac1..0000000000
--- a/MediaBrowser.Controller/Entities/IHasAspectRatio.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IHasAspectRatio
- /// </summary>
- public interface IHasAspectRatio
- {
- /// <summary>
- /// Gets or sets the aspect ratio.
- /// </summary>
- /// <value>The aspect ratio.</value>
- string AspectRatio { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasDisplayOrder.cs b/MediaBrowser.Controller/Entities/IHasDisplayOrder.cs
deleted file mode 100644
index 5e1ae21798..0000000000
--- a/MediaBrowser.Controller/Entities/IHasDisplayOrder.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IHasDisplayOrder
- /// </summary>
- public interface IHasDisplayOrder
- {
- /// <summary>
- /// Gets or sets the display order.
- /// </summary>
- /// <value>The display order.</value>
- string DisplayOrder { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasMediaSources.cs b/MediaBrowser.Controller/Entities/IHasMediaSources.cs
deleted file mode 100644
index 54786134f3..0000000000
--- a/MediaBrowser.Controller/Entities/IHasMediaSources.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using MediaBrowser.Model.Dto;
-using System.Collections.Generic;
-using MediaBrowser.Model.Entities;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasMediaSources : IHasMetadata
- {
- /// <summary>
- /// Gets the media sources.
- /// </summary>
- /// <param name="enablePathSubstitution">if set to <c>true</c> [enable path substitution].</param>
- /// <returns>Task{IEnumerable{MediaSourceInfo}}.</returns>
- List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
- List<MediaStream> GetMediaStreams();
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs
deleted file mode 100644
index b7d31b4d6a..0000000000
--- a/MediaBrowser.Controller/Entities/IHasMetadata.cs
+++ /dev/null
@@ -1,317 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.IO;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IHasMetadata
- /// </summary>
- public interface IHasMetadata : IHasProviderIds, IHasUserData
- {
- /// <summary>
- /// Gets the preferred metadata country code.
- /// </summary>
- /// <returns>System.String.</returns>
- string GetPreferredMetadataCountryCode();
-
- /// <summary>
- /// Gets the date modified.
- /// </summary>
- /// <value>The date modified.</value>
- DateTime DateModified { get; set; }
-
- /// <summary>
- /// Gets or sets the date last saved.
- /// </summary>
- /// <value>The date last saved.</value>
- DateTime DateLastSaved { get; set; }
-
- SourceType SourceType { get; }
-
- /// <summary>
- /// Gets or sets the date last refreshed.
- /// </summary>
- /// <value>The date last refreshed.</value>
- DateTime DateLastRefreshed { get; set; }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- bool BeforeMetadataRefresh();
-
- /// <summary>
- /// Afters the metadata refresh.
- /// </summary>
- void AfterMetadataRefresh();
-
- /// <summary>
- /// Gets a value indicating whether [supports people].
- /// </summary>
- /// <value><c>true</c> if [supports people]; otherwise, <c>false</c>.</value>
- bool SupportsPeople { get; }
-
- bool RequiresRefresh();
-
- bool EnableRefreshOnDateModifiedChange { get; }
-
- string PresentationUniqueKey { get; set; }
-
- string GetPresentationUniqueKey();
- string CreatePresentationUniqueKey();
- bool StopRefreshIfLocalMetadataFound { get; }
-
- int? GetInheritedParentalRatingValue();
- int InheritedParentalRatingValue { get; set; }
- List<string> GetInheritedTags();
- long? RunTimeTicks { get; set; }
-
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- string Name { get; set; }
-
- /// <summary>
- /// Gets the path.
- /// </summary>
- /// <value>The path.</value>
- string Path { get; set; }
-
- /// <summary>
- /// Gets the file name without extension.
- /// </summary>
- /// <value>The file name without extension.</value>
- string FileNameWithoutExtension { get; }
-
- /// <summary>
- /// Gets the type of the location.
- /// </summary>
- /// <value>The type of the location.</value>
- LocationType LocationType { get; }
-
- /// <summary>
- /// Gets the locked fields.
- /// </summary>
- /// <value>The locked fields.</value>
- MetadataFields[] LockedFields { get; }
-
- /// <summary>
- /// Gets the images.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <returns>IEnumerable{ItemImageInfo}.</returns>
- IEnumerable<ItemImageInfo> GetImages(ImageType imageType);
-
- /// <summary>
- /// Gets the image path.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="imageIndex">Index of the image.</param>
- /// <returns>System.String.</returns>
- string GetImagePath(ImageType imageType, int imageIndex);
-
- /// <summary>
- /// Gets the image information.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="imageIndex">Index of the image.</param>
- /// <returns>ItemImageInfo.</returns>
- ItemImageInfo GetImageInfo(ImageType imageType, int imageIndex);
-
- /// <summary>
- /// Sets the image.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <param name="index">The index.</param>
- /// <param name="file">The file.</param>
- void SetImagePath(ImageType type, int index, FileSystemMetadata file);
-
- /// <summary>
- /// Determines whether the specified type has image.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <param name="imageIndex">Index of the image.</param>
- /// <returns><c>true</c> if the specified type has image; otherwise, <c>false</c>.</returns>
- bool HasImage(ImageType type, int imageIndex);
-
- /// <summary>
- /// Allowses the multiple images.
- /// </summary>
- /// <param name="type">The type.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- bool AllowsMultipleImages(ImageType type);
-
- /// <summary>
- /// Swaps the images.
- /// </summary>
- void SwapImages(ImageType type, int index1, int index2);
-
- /// <summary>
- /// Gets or sets the primary image path.
- /// </summary>
- /// <value>The primary image path.</value>
- string PrimaryImagePath { get; }
-
- /// <summary>
- /// Gets the preferred metadata language.
- /// </summary>
- /// <returns>System.String.</returns>
- string GetPreferredMetadataLanguage();
-
- /// <summary>
- /// Validates the images and returns true or false indicating if any were removed.
- /// </summary>
- bool ValidateImages(IDirectoryService directoryService);
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- bool IsOwnedItem { get; }
-
- /// <summary>
- /// Gets the containing folder path.
- /// </summary>
- /// <value>The containing folder path.</value>
- string ContainingFolderPath { get; }
-
- /// <summary>
- /// Adds the images.
- /// </summary>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="images">The images.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- bool AddImages(ImageType imageType, List<FileSystemMetadata> images);
-
- /// <summary>
- /// Determines whether [is save local metadata enabled].
- /// </summary>
- /// <returns><c>true</c> if [is save local metadata enabled]; otherwise, <c>false</c>.</returns>
- bool IsSaveLocalMetadataEnabled();
-
- /// <summary>
- /// Gets a value indicating whether [supports local metadata].
- /// </summary>
- /// <value><c>true</c> if [supports local metadata]; otherwise, <c>false</c>.</value>
- bool SupportsLocalMetadata { get; }
-
- bool IsInMixedFolder { get; }
-
- /// <summary>
- /// Gets a value indicating whether this instance is locked.
- /// </summary>
- /// <value><c>true</c> if this instance is locked; otherwise, <c>false</c>.</value>
- bool IsLocked { get; }
-
- /// <summary>
- /// Gets a value indicating whether [supports remote image downloading].
- /// </summary>
- /// <value><c>true</c> if [supports remote image downloading]; otherwise, <c>false</c>.</value>
- bool SupportsRemoteImageDownloading { get; }
-
- /// <summary>
- /// Gets the internal metadata path.
- /// </summary>
- /// <returns>System.String.</returns>
- string GetInternalMetadataPath();
-
- /// <summary>
- /// Gets a value indicating whether [always scan internal metadata path].
- /// </summary>
- /// <value><c>true</c> if [always scan internal metadata path]; otherwise, <c>false</c>.</value>
- bool AlwaysScanInternalMetadataPath { get; }
-
- /// <summary>
- /// Determines whether [is internet metadata enabled].
- /// </summary>
- /// <returns><c>true</c> if [is internet metadata enabled]; otherwise, <c>false</c>.</returns>
- bool IsInternetMetadataEnabled();
-
- /// <summary>
- /// Removes the image.
- /// </summary>
- /// <param name="image">The image.</param>
- void RemoveImage(ItemImageInfo image);
-
- void RemoveImages(List<ItemImageInfo> images);
-
- /// <summary>
- /// Updates to repository.
- /// </summary>
- void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken);
-
- /// <summary>
- /// Sets the image.
- /// </summary>
- /// <param name="image">The image.</param>
- /// <param name="index">The index.</param>
- void SetImage(ItemImageInfo image, int index);
-
- double? GetDefaultPrimaryImageAspectRatio();
-
- int? ProductionYear { get; set; }
-
- string[] Tags { get; set; }
-
- ItemUpdateType OnMetadataChanged();
- }
-
- public static class HasMetadataExtensions
- {
- /// <summary>
- /// Gets the image path.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="imageType">Type of the image.</param>
- /// <returns>System.String.</returns>
- public static string GetImagePath(this IHasMetadata item, ImageType imageType)
- {
- return item.GetImagePath(imageType, 0);
- }
-
- public static bool HasImage(this IHasMetadata item, ImageType imageType)
- {
- return item.HasImage(imageType, 0);
- }
-
- /// <summary>
- /// Sets the image path.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="file">The file.</param>
- public static void SetImagePath(this IHasMetadata item, ImageType imageType, FileSystemMetadata file)
- {
- item.SetImagePath(imageType, 0, file);
- }
-
- /// <summary>
- /// Sets the image path.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="imageType">Type of the image.</param>
- /// <param name="file">The file.</param>
- public static void SetImagePath(this IHasMetadata item, ImageType imageType, string file)
- {
- if (file.StartsWith("http", System.StringComparison.OrdinalIgnoreCase))
- {
- item.SetImage(new ItemImageInfo
- {
- Path = file,
- Type = imageType
- }, 0);
- }
- else
- {
- item.SetImagePath(imageType, BaseItem.FileSystem.GetFileInfo(file));
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
deleted file mode 100644
index 90786d44d7..0000000000
--- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using MediaBrowser.Model.LiveTv;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasProgramAttributes
- {
- bool IsMovie { get; set; }
- bool IsSports { get; set; }
- bool IsNews { get; set; }
- bool IsKids { get; set; }
- bool IsRepeat { get; set; }
- bool? IsHD { get; set; }
- bool IsSeries { get; set; }
- bool IsLive { get; set; }
- bool IsPremiere { get; set; }
- ProgramAudio? Audio { get; set; }
- string EpisodeTitle { get; set; }
- string ServiceName { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasScreenshots.cs b/MediaBrowser.Controller/Entities/IHasScreenshots.cs
deleted file mode 100644
index 2fd402bc2b..0000000000
--- a/MediaBrowser.Controller/Entities/IHasScreenshots.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IHasScreenshots
- /// </summary>
- public interface IHasScreenshots
- {
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasSeries.cs b/MediaBrowser.Controller/Entities/IHasSeries.cs
deleted file mode 100644
index 20efdc2b8b..0000000000
--- a/MediaBrowser.Controller/Entities/IHasSeries.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-
-using System;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasSeries
- {
- /// <summary>
- /// Gets the name of the series.
- /// </summary>
- /// <value>The name of the series.</value>
- string SeriesName { get; set; }
- string FindSeriesName();
- string FindSeriesSortName();
- Guid? SeriesId { get; set; }
- Guid? FindSeriesId();
- string SeriesPresentationUniqueKey { get; set; }
- string FindSeriesPresentationUniqueKey();
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs b/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs
deleted file mode 100644
index f4905b7dcf..0000000000
--- a/MediaBrowser.Controller/Entities/IHasSpecialFeatures.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasSpecialFeatures
- {
- /// <summary>
- /// Gets or sets the special feature ids.
- /// </summary>
- /// <value>The special feature ids.</value>
- Guid[] SpecialFeatureIds { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasStartDate.cs b/MediaBrowser.Controller/Entities/IHasStartDate.cs
deleted file mode 100644
index a6714fb964..0000000000
--- a/MediaBrowser.Controller/Entities/IHasStartDate.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasStartDate
- {
- DateTime StartDate { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasTrailers.cs b/MediaBrowser.Controller/Entities/IHasTrailers.cs
deleted file mode 100644
index 07dde37894..0000000000
--- a/MediaBrowser.Controller/Entities/IHasTrailers.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasTrailers : IHasMetadata
- {
- /// <summary>
- /// Gets or sets the remote trailers.
- /// </summary>
- /// <value>The remote trailers.</value>
- MediaUrl[] RemoteTrailers { get; set; }
-
- /// <summary>
- /// Gets or sets the local trailer ids.
- /// </summary>
- /// <value>The local trailer ids.</value>
- Guid[] LocalTrailerIds { get; set; }
- Guid[] RemoteTrailerIds { get; set; }
- }
-
- public static class HasTrailerExtensions
- {
- /// <summary>
- /// Gets the trailer ids.
- /// </summary>
- /// <returns>List&lt;Guid&gt;.</returns>
- public static List<Guid> GetTrailerIds(this IHasTrailers item)
- {
- var list = item.LocalTrailerIds.ToList();
- list.AddRange(item.RemoteTrailerIds);
- return list;
- }
-
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs
deleted file mode 100644
index ab4f624e21..0000000000
--- a/MediaBrowser.Controller/Entities/IHasUserData.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IHasUserData
- /// </summary>
- public interface IHasUserData
- {
- List<string> GetUserDataKeys();
-
- /// <summary>
- /// Fills the user data dto values.
- /// </summary>
- void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields);
-
- bool EnableRememberingTrackSelections { get; }
-
- bool SupportsPlayedStatus { get; }
-
- Guid Id { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHiddenFromDisplay.cs b/MediaBrowser.Controller/Entities/IHiddenFromDisplay.cs
deleted file mode 100644
index ba6311296a..0000000000
--- a/MediaBrowser.Controller/Entities/IHiddenFromDisplay.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHiddenFromDisplay
- {
- /// <summary>
- /// Determines whether the specified user is hidden.
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns><c>true</c> if the specified user is hidden; otherwise, <c>false</c>.</returns>
- bool IsHiddenFromUser(User user);
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs
deleted file mode 100644
index a02ca1c0c4..0000000000
--- a/MediaBrowser.Controller/Entities/IItemByName.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Collections.Generic;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Marker interface
- /// </summary>
- public interface IItemByName : IHasMetadata
- {
- IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query);
- }
-
- public interface IHasDualAccess : IItemByName
- {
- bool IsAccessedByName { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IMetadataContainer.cs b/MediaBrowser.Controller/Entities/IMetadataContainer.cs
deleted file mode 100644
index 33aa08425d..0000000000
--- a/MediaBrowser.Controller/Entities/IMetadataContainer.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IMetadataContainer
- {
- /// <summary>
- /// Refreshes all metadata.
- /// </summary>
- /// <param name="refreshOptions">The refresh options.</param>
- /// <param name="progress">The progress.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken);
- }
-}
diff --git a/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs b/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs
deleted file mode 100644
index fbe5a06d0e..0000000000
--- a/MediaBrowser.Controller/Entities/ISupportsBoxSetGrouping.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Marker interface to denote a class that supports being hidden underneath it's boxset.
- /// Just about anything can be placed into a boxset,
- /// but movies should also only appear underneath and not outside separately (subject to configuration).
- /// </summary>
- public interface ISupportsBoxSetGrouping
- {
- }
-}
diff --git a/MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs b/MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs
deleted file mode 100644
index 2507c8ee65..0000000000
--- a/MediaBrowser.Controller/Entities/ISupportsPlaceHolders.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface ISupportsPlaceHolders
- {
- /// <summary>
- /// Gets a value indicating whether this instance is place holder.
- /// </summary>
- /// <value><c>true</c> if this instance is place holder; otherwise, <c>false</c>.</value>
- bool IsPlaceHolder { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IVirtualFolderCreator.cs b/MediaBrowser.Controller/Entities/IVirtualFolderCreator.cs
deleted file mode 100644
index 57e9e8d5d9..0000000000
--- a/MediaBrowser.Controller/Entities/IVirtualFolderCreator.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IVirtualFolderCreator
- /// </summary>
- public interface IVirtualFolderCreator
- {
- /// <summary>
- /// Gets the folder.
- /// </summary>
- /// <returns>Folder.</returns>
- BasePluginFolder GetFolder();
- }
-}
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
deleted file mode 100644
index a7f6c60148..0000000000
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ /dev/null
@@ -1,243 +0,0 @@
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Configuration;
-using System.Linq;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Model.Querying;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class InternalItemsQuery
- {
- public bool Recursive { get; set; }
-
- public int? StartIndex { get; set; }
-
- public int? Limit { get; set; }
-
- public User User { get; set; }
-
- public BaseItem SimilarTo { get; set; }
-
- public bool? IsFolder { get; set; }
- public bool? IsFavorite { get; set; }
- public bool? IsFavoriteOrLiked { get; set; }
- public bool? IsLiked { get; set; }
- public bool? IsPlayed { get; set; }
- public bool? IsResumable { get; set; }
- public bool? IncludeItemsByName { get; set; }
-
- public string[] MediaTypes { get; set; }
- public string[] IncludeItemTypes { get; set; }
- public string[] ExcludeItemTypes { get; set; }
- public string[] ExcludeTags { get; set; }
- public string[] ExcludeInheritedTags { get; set; }
- public string[] Genres { get; set; }
-
- public bool? IsSpecialSeason { get; set; }
- public bool? IsMissing { get; set; }
- public bool? IsUnaired { get; set; }
- public bool? CollapseBoxSetItems { get; set; }
-
- public string NameStartsWithOrGreater { get; set; }
- public string NameStartsWith { get; set; }
- public string NameLessThan { get; set; }
- public string NameContains { get; set; }
- public string MinSortName { get; set; }
-
- public string PresentationUniqueKey { get; set; }
- public string Path { get; set; }
- public string PathNotStartsWith { get; set; }
- public string Name { get; set; }
-
- public string Person { get; set; }
- public string[] PersonIds { get; set; }
- public string[] ItemIds { get; set; }
- public string[] ExcludeItemIds { get; set; }
- public string AdjacentTo { get; set; }
- public string[] PersonTypes { get; set; }
-
- public bool? Is3D { get; set; }
- public bool? IsHD { get; set; }
- public bool? IsInBoxSet { get; set; }
- public bool? IsLocked { get; set; }
- public bool? IsPlaceHolder { get; set; }
-
- public bool? HasImdbId { get; set; }
- public bool? HasOverview { get; set; }
- public bool? HasTmdbId { get; set; }
- public bool? HasOfficialRating { get; set; }
- public bool? HasTvdbId { get; set; }
- public bool? HasThemeSong { get; set; }
- public bool? HasThemeVideo { get; set; }
- public bool? HasSubtitles { get; set; }
- public bool? HasSpecialFeature { get; set; }
- public bool? HasTrailer { get; set; }
- public bool? HasParentalRating { get; set; }
-
- public string[] StudioIds { get; set; }
- public string[] GenreIds { get; set; }
- public ImageType[] ImageTypes { get; set; }
- public VideoType[] VideoTypes { get; set; }
- public UnratedItem[] BlockUnratedItems { get; set; }
- public int[] Years { get; set; }
- public string[] Tags { get; set; }
- public string[] OfficialRatings { get; set; }
-
- public DateTime? MinPremiereDate { get; set; }
- public DateTime? MaxPremiereDate { get; set; }
- public DateTime? MinStartDate { get; set; }
- public DateTime? MaxStartDate { get; set; }
- public DateTime? MinEndDate { get; set; }
- public DateTime? MaxEndDate { get; set; }
- public bool? IsAiring { get; set; }
-
- public bool? IsMovie { get; set; }
- public bool? IsSports { get; set; }
- public bool? IsKids { get; set; }
- public bool? IsNews { get; set; }
- public bool? IsSeries { get; set; }
-
- public int? MinPlayers { get; set; }
- public int? MaxPlayers { get; set; }
- public int? MinIndexNumber { get; set; }
- public int? AiredDuringSeason { get; set; }
- public double? MinCriticRating { get; set; }
- public double? MinCommunityRating { get; set; }
-
- public string[] ChannelIds { get; set; }
-
- internal List<Guid> ItemIdsFromPersonFilters { get; set; }
- public int? ParentIndexNumber { get; set; }
- public int? ParentIndexNumberNotEquals { get; set; }
- public int? IndexNumber { get; set; }
- public int? MinParentalRating { get; set; }
- public int? MaxParentalRating { get; set; }
-
- public bool? HasDeadParentId { get; set; }
- public bool? IsVirtualItem { get; set; }
-
- public Guid? ParentId { get; set; }
- public string ParentType { get; set; }
- public string[] AncestorIds { get; set; }
- public string[] TopParentIds { get; set; }
-
- public BaseItem Parent
- {
- set
- {
- if (value == null)
- {
- ParentId = null;
- ParentType = null;
- }
- else
- {
- ParentId = value.Id;
- ParentType = value.GetType().Name;
- }
- }
- }
-
- public string[] PresetViews { get; set; }
- public TrailerType[] TrailerTypes { get; set; }
- public SourceType[] SourceTypes { get; set; }
-
- public SeriesStatus[] SeriesStatuses { get; set; }
- public string ExternalSeriesId { get; set; }
- public string ExternalId { get; set; }
-
- public string[] AlbumIds { get; set; }
- public string[] ArtistIds { get; set; }
- public string[] ExcludeArtistIds { get; set; }
- public string AncestorWithPresentationUniqueKey { get; set; }
- public string SeriesPresentationUniqueKey { get; set; }
-
- public bool GroupByPresentationUniqueKey { get; set; }
- public bool GroupBySeriesPresentationUniqueKey { get; set; }
- public bool EnableTotalRecordCount { get; set; }
- public bool ForceDirect { get; set; }
- public Dictionary<string, string> ExcludeProviderIds { get; set; }
- public bool EnableGroupByMetadataKey { get; set; }
- public bool? HasChapterImages { get; set; }
-
- public Tuple<string, SortOrder>[] OrderBy { get; set; }
-
- public DateTime? MinDateCreated { get; set; }
- public DateTime? MinDateLastSaved { get; set; }
- public DateTime? MinDateLastSavedForUser { get; set; }
-
- public DtoOptions DtoOptions { get; set; }
- public int MinSimilarityScore { get; set; }
- public string HasNoAudioTrackWithLanguage { get; set; }
- public string HasNoInternalSubtitleTrackWithLanguage { get; set; }
- public string HasNoExternalSubtitleTrackWithLanguage { get; set; }
- public string HasNoSubtitleTrackWithLanguage { get; set; }
-
- public InternalItemsQuery()
- {
- MinSimilarityScore = 20;
-
- GroupByPresentationUniqueKey = true;
- EnableTotalRecordCount = true;
-
- DtoOptions = new DtoOptions();
- AlbumIds = new string[] { };
- ArtistIds = new string[] { };
- ExcludeArtistIds = new string[] { };
- ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- BlockUnratedItems = new UnratedItem[] { };
- Tags = new string[] { };
- OfficialRatings = new string[] { };
- MediaTypes = new string[] { };
- IncludeItemTypes = new string[] { };
- ExcludeItemTypes = new string[] { };
- Genres = new string[] { };
- StudioIds = new string[] { };
- GenreIds = new string[] { };
- ImageTypes = new ImageType[] { };
- VideoTypes = new VideoType[] { };
- Years = new int[] { };
- PersonTypes = new string[] { };
- PersonIds = new string[] { };
- ChannelIds = new string[] { };
- ItemIds = new string[] { };
- ExcludeItemIds = new string[] { };
- AncestorIds = new string[] { };
- TopParentIds = new string[] { };
- ExcludeTags = new string[] { };
- ExcludeInheritedTags = new string[] { };
- PresetViews = new string[] { };
- TrailerTypes = new TrailerType[] { };
- SourceTypes = new SourceType[] { };
- SeriesStatuses = new SeriesStatus[] { };
- OrderBy = new Tuple<string, SortOrder>[] { };
- }
-
- public InternalItemsQuery(User user)
- : this()
- {
- SetUser(user);
- }
-
- public void SetUser(User user)
- {
- if (user != null)
- {
- var policy = user.Policy;
- MaxParentalRating = policy.MaxParentalRating;
-
- if (policy.MaxParentalRating.HasValue)
- {
- BlockUnratedItems = policy.BlockUnratedItems.Where(i => i != UnratedItem.Other).ToArray();
- }
-
- ExcludeInheritedTags = policy.BlockedTags;
-
- User = user;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs b/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs
deleted file mode 100644
index 9e0e9c2088..0000000000
--- a/MediaBrowser.Controller/Entities/InternalPeopleQuery.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class InternalPeopleQuery
- {
- public Guid ItemId { get; set; }
- public string[] PersonTypes { get; set; }
- public List<string> ExcludePersonTypes { get; set; }
- public int? MaxListOrder { get; set; }
- public Guid AppearsInItemId { get; set; }
- public string NameContains { get; set; }
-
- public InternalPeopleQuery()
- {
- PersonTypes = new string[] {};
- ExcludePersonTypes = new List<string>();
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
deleted file mode 100644
index bd0011c4b3..0000000000
--- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using MediaBrowser.Model.Entities;
-using System;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class ItemImageInfo
- {
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- public string Path { get; set; }
-
- /// <summary>
- /// Gets or sets the type.
- /// </summary>
- /// <value>The type.</value>
- public ImageType Type { get; set; }
-
- /// <summary>
- /// Gets or sets the date modified.
- /// </summary>
- /// <value>The date modified.</value>
- public DateTime DateModified { get; set; }
-
- public int Width { get; set; }
- public int Height { get; set; }
-
- [IgnoreDataMember]
- public bool IsLocalFile
- {
- get
- {
- if (Path != null)
- {
- if (Path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- }
- return true;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs
deleted file mode 100644
index 6031a2448a..0000000000
--- a/MediaBrowser.Controller/Entities/LinkedChild.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class LinkedChild
- {
- public string Path { get; set; }
- public LinkedChildType Type { get; set; }
-
- [IgnoreDataMember]
- public string Id { get; set; }
-
- /// <summary>
- /// Serves as a cache
- /// </summary>
- public Guid? ItemId { get; set; }
-
- public static LinkedChild Create(BaseItem item)
- {
- return new LinkedChild
- {
- Path = item.Path,
- Type = LinkedChildType.Manual
- };
- }
-
- public LinkedChild()
- {
- Id = Guid.NewGuid().ToString("N");
- }
- }
-
- public enum LinkedChildType
- {
- Manual = 0,
- Shortcut = 1
- }
-
- public class LinkedChildComparer : IEqualityComparer<LinkedChild>
- {
- private readonly IFileSystem _fileSystem;
-
- public LinkedChildComparer(IFileSystem fileSystem)
- {
- _fileSystem = fileSystem;
- }
-
- public bool Equals(LinkedChild x, LinkedChild y)
- {
- if (x.Type == y.Type)
- {
- return _fileSystem.AreEqual(x.Path, y.Path);
- }
- return false;
- }
-
- public int GetHashCode(LinkedChild obj)
- {
- return (obj.Path + obj.Type).GetHashCode();
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
deleted file mode 100644
index 268860ff01..0000000000
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ /dev/null
@@ -1,216 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Users;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.Movies
-{
- /// <summary>
- /// Class BoxSet
- /// </summary>
- public class BoxSet : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IHasShares
- {
- public List<Share> Shares { get; set; }
-
- public BoxSet()
- {
- RemoteTrailers = EmptyMediaUrlArray;
- LocalTrailerIds = EmptyGuidArray;
- RemoteTrailerIds = EmptyGuidArray;
-
- DisplayOrder = ItemSortBy.PremiereDate;
- Shares = new List<Share>();
- }
-
- [IgnoreDataMember]
- protected override bool FilterLinkedChildrenPerUser
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return true; }
- }
-
- public Guid[] LocalTrailerIds { get; set; }
- public Guid[] RemoteTrailerIds { get; set; }
-
- /// <summary>
- /// Gets or sets the remote trailers.
- /// </summary>
- /// <value>The remote trailers.</value>
- public MediaUrl[] RemoteTrailers { get; set; }
-
- /// <summary>
- /// Gets or sets the display order.
- /// </summary>
- /// <value>The display order.</value>
- public string DisplayOrder { get; set; }
-
- protected override bool GetBlockUnratedValue(UserPolicy config)
- {
- return config.BlockUnratedItems.Contains(UnratedItem.Movie);
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Movie;
- }
-
- protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
- {
- if (IsLegacyBoxSet)
- {
- return base.GetNonCachedChildren(directoryService);
- }
- return new List<BaseItem>();
- }
-
- protected override List<BaseItem> LoadChildren()
- {
- if (IsLegacyBoxSet)
- {
- return base.LoadChildren();
- }
-
- // Save a trip to the database
- return new List<BaseItem>();
- }
-
- [IgnoreDataMember]
- private bool IsLegacyBoxSet
- {
- get
- {
- if (string.IsNullOrWhiteSpace(Path))
- {
- return false;
- }
-
- if (LinkedChildren.Length > 0)
- {
- return false;
- }
-
- return !FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, Path);
- }
- }
-
- [IgnoreDataMember]
- public override bool IsPreSorted
- {
- get
- {
- return true;
- }
- }
-
- public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
- {
- return true;
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- /// <summary>
- /// Updates the official rating based on content and returns true or false indicating if it changed.
- /// </summary>
- /// <returns></returns>
- public bool UpdateRatingToContent()
- {
- var currentOfficialRating = OfficialRating;
-
- // Gather all possible ratings
- var ratings = GetLinkedChildren()
- .Select(i => i.OfficialRating)
- .Where(i => !string.IsNullOrEmpty(i))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .Select(i => new Tuple<string, int?>(i, LocalizationManager.GetRatingLevel(i)))
- .OrderBy(i => i.Item2 ?? 1000)
- .Select(i => i.Item1);
-
- OfficialRating = ratings.FirstOrDefault() ?? currentOfficialRating;
-
- return !string.Equals(currentOfficialRating ?? string.Empty, OfficialRating ?? string.Empty,
- StringComparison.OrdinalIgnoreCase);
- }
-
- public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
- {
- var children = base.GetChildren(user, includeLinkedChildren);
-
- if (string.Equals(DisplayOrder, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase))
- {
- // Sort by name
- return LibraryManager.Sort(children, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList();
- }
-
- if (string.Equals(DisplayOrder, ItemSortBy.PremiereDate, StringComparison.OrdinalIgnoreCase))
- {
- // Sort by release date
- return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending).ToList();
- }
-
- // Default sorting
- return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending).ToList();
- }
-
- public BoxSetInfo GetLookupInfo()
- {
- return GetItemLookupInfo<BoxSetInfo>();
- }
-
- public override bool IsVisible(User user)
- {
- var userId = user.Id.ToString("N");
-
- // Need to check Count > 0 for boxsets created prior to the introduction of Shares
- if (Shares.Count > 0 && Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)))
- {
- return true;
- }
-
- if (base.IsVisible(user))
- {
- return base.GetChildren(user, true).Count > 0;
- }
-
- return false;
- }
-
- public override bool IsVisibleStandalone(User user)
- {
- return IsVisible(user);
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
deleted file mode 100644
index 2e0e019443..0000000000
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ /dev/null
@@ -1,197 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Providers;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.Movies
-{
- /// <summary>
- /// Class Movie
- /// </summary>
- public class Movie : Video, IHasSpecialFeatures, IHasTrailers, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping
- {
- public Guid[] SpecialFeatureIds { get; set; }
-
- public Movie()
- {
- SpecialFeatureIds = EmptyGuidArray;
- RemoteTrailers = EmptyMediaUrlArray;
- LocalTrailerIds = EmptyGuidArray;
- RemoteTrailerIds = EmptyGuidArray;
- }
-
- public Guid[] LocalTrailerIds { get; set; }
- public Guid[] RemoteTrailerIds { get; set; }
-
- public MediaUrl[] RemoteTrailers { get; set; }
-
- /// <summary>
- /// Gets or sets the name of the TMDB collection.
- /// </summary>
- /// <value>The name of the TMDB collection.</value>
- public string TmdbCollectionName { get; set; }
-
- [IgnoreDataMember]
- public string CollectionName
- {
- get { return TmdbCollectionName; }
- set { TmdbCollectionName = value; }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
-
- // Must have a parent to have special features
- // In other words, it must be part of the Parent/Child tree
- if (LocationType == LocationType.FileSystem && GetParent() != null && !IsInMixedFolder)
- {
- var specialFeaturesChanged = await RefreshSpecialFeatures(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
-
- if (specialFeaturesChanged)
- {
- hasChanges = true;
- }
- }
-
- return hasChanges;
- }
-
- private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var newItems = LibraryManager.FindExtras(this, fileSystemChildren, options.DirectoryService).ToList();
- var newItemIds = newItems.Select(i => i.Id).ToArray();
-
- var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
-
- var ownerId = Id;
-
- var tasks = newItems.Select(i =>
- {
- var subOptions = new MetadataRefreshOptions(options);
-
- if (i.OwnerId != ownerId)
- {
- i.OwnerId = ownerId;
- subOptions.ForceSave = true;
- }
-
- return RefreshMetadataForOwnedItem(i, false, subOptions, cancellationToken);
- });
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
- SpecialFeatureIds = newItemIds;
-
- return itemsChanged;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Movie;
- }
-
- public MovieInfo GetLookupInfo()
- {
- var info = GetItemLookupInfo<MovieInfo>();
-
- if (!IsInMixedFolder)
- {
- var name = System.IO.Path.GetFileName(ContainingFolderPath);
-
- if (VideoType == VideoType.VideoFile || VideoType == VideoType.Iso)
- {
- if (string.Equals(name, System.IO.Path.GetFileName(Path), StringComparison.OrdinalIgnoreCase))
- {
- // if the folder has the file extension, strip it
- name = System.IO.Path.GetFileNameWithoutExtension(name);
- }
- }
-
- info.Name = name;
- }
-
- return info;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (!ProductionYear.HasValue)
- {
- var info = LibraryManager.ParseName(Name);
-
- var yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- else
- {
- // Try to get the year from the folder name
- if (!IsInMixedFolder)
- {
- info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
-
- yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- }
- }
- }
-
- return hasChanges;
- }
-
- public override List<ExternalUrl> GetRelatedUrls()
- {
- var list = base.GetRelatedUrls();
-
- var imdbId = this.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrWhiteSpace(imdbId))
- {
- list.Add(new ExternalUrl
- {
- Name = "Trakt",
- Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
- });
- }
-
- return list;
- }
-
- [IgnoreDataMember]
- public override bool StopRefreshIfLocalMetadataFound
- {
- get
- {
- // Need people id's from internet metadata
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs
deleted file mode 100644
index b7470d679d..0000000000
--- a/MediaBrowser.Controller/Entities/MusicVideo.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using System.Collections.Generic;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo>
- {
- [IgnoreDataMember]
- public string[] Artists { get; set; }
-
- public MusicVideo()
- {
- Artists = EmptyStringArray;
- }
-
- [IgnoreDataMember]
- public string[] AllArtists
- {
- get
- {
- return Artists;
- }
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Music;
- }
-
- public MusicVideoInfo GetLookupInfo()
- {
- return GetItemLookupInfo<MusicVideoInfo>();
- }
-
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (!ProductionYear.HasValue)
- {
- var info = LibraryManager.ParseName(Name);
-
- var yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- else
- {
- // Try to get the year from the folder name
- if (!IsInMixedFolder)
- {
- info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
-
- yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- }
- }
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs
deleted file mode 100644
index 412eb94998..0000000000
--- a/MediaBrowser.Controller/Entities/PeopleHelper.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace MediaBrowser.Controller.Entities
-{
- public static class PeopleHelper
- {
- public static void AddPerson(List<PersonInfo> people, PersonInfo person)
- {
- if (person == null)
- {
- throw new ArgumentNullException("person");
- }
-
- if (string.IsNullOrWhiteSpace(person.Name))
- {
- throw new ArgumentNullException();
- }
-
- // Normalize
- if (string.Equals(person.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
- {
- person.Type = PersonType.GuestStar;
- }
- else if (string.Equals(person.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
- {
- person.Type = PersonType.Director;
- }
- else if (string.Equals(person.Role, PersonType.Producer, StringComparison.OrdinalIgnoreCase))
- {
- person.Type = PersonType.Producer;
- }
- else if (string.Equals(person.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
- {
- person.Type = PersonType.Writer;
- }
-
- // If the type is GuestStar and there's already an Actor entry, then update it to avoid dupes
- if (string.Equals(person.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
- {
- var existing = people.FirstOrDefault(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && p.Type.Equals(PersonType.Actor, StringComparison.OrdinalIgnoreCase));
-
- if (existing != null)
- {
- existing.Type = PersonType.GuestStar;
- MergeExisting(existing, person);
- return;
- }
- }
-
- if (string.Equals(person.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
- {
- // If the actor already exists without a role and we have one, fill it in
- var existing = people.FirstOrDefault(p => p.Name.Equals(person.Name, StringComparison.OrdinalIgnoreCase) && (p.Type.Equals(PersonType.Actor, StringComparison.OrdinalIgnoreCase) || p.Type.Equals(PersonType.GuestStar, StringComparison.OrdinalIgnoreCase)));
- if (existing == null)
- {
- // Wasn't there - add it
- people.Add(person);
- }
- else
- {
- // Was there, if no role and we have one - fill it in
- if (string.IsNullOrWhiteSpace(existing.Role) && !string.IsNullOrWhiteSpace(person.Role))
- {
- existing.Role = person.Role;
- }
-
- MergeExisting(existing, person);
- }
- }
- else
- {
- var existing = people.FirstOrDefault(p =>
- string.Equals(p.Name, person.Name, StringComparison.OrdinalIgnoreCase) &&
- string.Equals(p.Type, person.Type, StringComparison.OrdinalIgnoreCase));
-
- // Check for dupes based on the combination of Name and Type
- if (existing == null)
- {
- people.Add(person);
- }
- else
- {
- MergeExisting(existing, person);
- }
- }
- }
-
- private static void MergeExisting(PersonInfo existing, PersonInfo person)
- {
- existing.SortOrder = person.SortOrder ?? existing.SortOrder;
- existing.ImageUrl = person.ImageUrl ?? existing.ImageUrl;
-
- foreach (var id in person.ProviderIds)
- {
- existing.SetProviderId(id.Key, id.Value);
- }
- }
-
- public static bool ContainsPerson(List<PersonInfo> people, string name)
- {
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentNullException("name");
- }
-
- foreach (var i in people)
- {
- if (string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
- }
- return false;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
deleted file mode 100644
index b3a91f9446..0000000000
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// This is the full Person object that can be retrieved with all of it's data.
- /// </summary>
- public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
- {
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
- return list;
- }
- public override string CreatePresentationUniqueKey()
- {
- return GetUserDataKeys()[0];
- }
-
- public PersonLookupInfo GetLookupInfo()
- {
- return GetItemLookupInfo<PersonLookupInfo>();
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- query.PersonIds = new[] { Id.ToString("N") };
-
- return LibraryManager.GetItemList(query);
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- [IgnoreDataMember]
- public override bool EnableAlphaNumericSorting
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAncestors
- {
- get
- {
- return false;
- }
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validFilename = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- string subFolderPrefix = null;
-
- foreach (char c in validFilename)
- {
- if (char.IsLetterOrDigit(c))
- {
- subFolderPrefix = c.ToString();
- break;
- }
- }
-
- var path = ConfigurationManager.ApplicationPaths.PeoplePath;
-
- return string.IsNullOrEmpty(subFolderPrefix) ?
- System.IO.Path.Combine(path, validFilename) :
- System.IO.Path.Combine(path, subFolderPrefix, validFilename);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
-
- return hasChanges;
- }
- }
-
- /// <summary>
- /// This is the small Person stub that is attached to BaseItems
- /// </summary>
- public class PersonInfo : IHasProviderIds
- {
- public PersonInfo()
- {
- ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- }
-
- public Guid ItemId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- public string Name { get; set; }
- /// <summary>
- /// Gets or sets the role.
- /// </summary>
- /// <value>The role.</value>
- public string Role { get; set; }
- /// <summary>
- /// Gets or sets the type.
- /// </summary>
- /// <value>The type.</value>
- public string Type { get; set; }
-
- /// <summary>
- /// Gets or sets the sort order - ascending
- /// </summary>
- /// <value>The sort order.</value>
- public int? SortOrder { get; set; }
-
- public string ImageUrl { get; set; }
-
- public Dictionary<string, string> ProviderIds { get; set; }
-
- /// <summary>
- /// Returns a <see cref="System.String" /> that represents this instance.
- /// </summary>
- /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
- public override string ToString()
- {
- return Name;
- }
-
- public bool IsType(string type)
- {
- return string.Equals(Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(Role, type, StringComparison.OrdinalIgnoreCase);
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs
deleted file mode 100644
index 11db633bad..0000000000
--- a/MediaBrowser.Controller/Entities/Photo.cs
+++ /dev/null
@@ -1,110 +0,0 @@
-using MediaBrowser.Model.Drawing;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class Photo : BaseItem
- {
- [IgnoreDataMember]
- public override bool SupportsLocalMetadata
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override string MediaType
- {
- get
- {
- return Model.Entities.MediaType.Photo;
- }
- }
-
- [IgnoreDataMember]
- public override Folder LatestItemsIndexContainer
- {
- get
- {
- return AlbumEntity;
- }
- }
-
-
- [IgnoreDataMember]
- public PhotoAlbum AlbumEntity
- {
- get
- {
- var parents = GetParents();
- foreach (var parent in parents)
- {
- var photoAlbum = parent as PhotoAlbum;
- if (photoAlbum != null)
- {
- return photoAlbum;
- }
- }
- return null;
- }
- }
-
- [IgnoreDataMember]
- public override bool EnableRefreshOnDateModifiedChange
- {
- get { return true; }
- }
-
- public override bool CanDownload()
- {
- return true;
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- if (Width.HasValue && Height.HasValue)
- {
- double width = Width.Value;
- double height = Height.Value;
-
- if (Orientation.HasValue)
- {
- switch (Orientation.Value)
- {
- case ImageOrientation.LeftBottom:
- case ImageOrientation.LeftTop:
- case ImageOrientation.RightBottom:
- case ImageOrientation.RightTop:
- var temp = height;
- height = width;
- width = temp;
- break;
- }
- }
-
- width /= Height.Value;
- return width;
- }
-
- return base.GetDefaultPrimaryImageAspectRatio();
- }
-
- public int? Width { get; set; }
- public int? Height { get; set; }
- public string CameraMake { get; set; }
- public string CameraModel { get; set; }
- public string Software { get; set; }
- public double? ExposureTime { get; set; }
- public double? FocalLength { get; set; }
- public ImageOrientation? Orientation { get; set; }
- public double? Aperture { get; set; }
- public double? ShutterSpeed { get; set; }
-
- public double? Latitude { get; set; }
- public double? Longitude { get; set; }
- public double? Altitude { get; set; }
- public int? IsoSpeedRating { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs
deleted file mode 100644
index af9d8c801d..0000000000
--- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class PhotoAlbum : Folder
- {
- [IgnoreDataMember]
- public override bool AlwaysScanInternalMetadataPath
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Share.cs b/MediaBrowser.Controller/Entities/Share.cs
deleted file mode 100644
index e194f62388..0000000000
--- a/MediaBrowser.Controller/Entities/Share.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasShares
- {
- List<Share> Shares { get; set; }
- }
-
- public class Share
- {
- public string UserId { get; set; }
- public bool CanEdit { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/SourceType.cs b/MediaBrowser.Controller/Entities/SourceType.cs
deleted file mode 100644
index 9c307b4e6e..0000000000
--- a/MediaBrowser.Controller/Entities/SourceType.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- public enum SourceType
- {
- Library = 0,
- Channel = 1,
- LiveTV = 2
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
deleted file mode 100644
index a6a72d9940..0000000000
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-using System;
-using System.Collections.Generic;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Studio
- /// </summary>
- public class Studio : BaseItem, IItemByName
- {
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.Insert(0, GetType().Name + "-" + (Name ?? string.Empty).RemoveDiacritics());
- return list;
- }
- public override string CreatePresentationUniqueKey()
- {
- return GetUserDataKeys()[0];
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- [IgnoreDataMember]
- public override bool IsDisplayedAsFolder
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsAncestors
- {
- get
- {
- return false;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 16;
- value /= 9;
-
- return value;
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- query.StudioIds = new[] { Id.ToString("N") };
-
- return LibraryManager.GetItemList(query);
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validName = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.StudioPath, validName);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
deleted file mode 100644
index 3f52dfc934..0000000000
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ /dev/null
@@ -1,385 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.TV
-{
- /// <summary>
- /// Class Episode
- /// </summary>
- public class Episode : Video, IHasTrailers, IHasLookupInfo<EpisodeInfo>, IHasSeries
- {
- public Episode()
- {
- RemoteTrailers = EmptyMediaUrlArray;
- LocalTrailerIds = EmptyGuidArray;
- RemoteTrailerIds = EmptyGuidArray;
- }
-
- public Guid[] LocalTrailerIds { get; set; }
- public Guid[] RemoteTrailerIds { get; set; }
- public MediaUrl[] RemoteTrailers { get; set; }
-
- /// <summary>
- /// Gets the season in which it aired.
- /// </summary>
- /// <value>The aired season.</value>
- public int? AirsBeforeSeasonNumber { get; set; }
- public int? AirsAfterSeasonNumber { get; set; }
- public int? AirsBeforeEpisodeNumber { get; set; }
-
- /// <summary>
- /// Gets or sets the DVD season number.
- /// </summary>
- /// <value>The DVD season number.</value>
- public int? DvdSeasonNumber { get; set; }
- /// <summary>
- /// Gets or sets the DVD episode number.
- /// </summary>
- /// <value>The DVD episode number.</value>
- public float? DvdEpisodeNumber { get; set; }
-
- /// <summary>
- /// Gets or sets the absolute episode number.
- /// </summary>
- /// <value>The absolute episode number.</value>
- public int? AbsoluteEpisodeNumber { get; set; }
-
- /// <summary>
- /// This is the ending episode number for double episodes.
- /// </summary>
- /// <value>The index number.</value>
- public int? IndexNumberEnd { get; set; }
-
- public string FindSeriesSortName()
- {
- var series = Series;
- return series == null ? SeriesName : series.SortName;
- }
-
- [IgnoreDataMember]
- protected override bool SupportsOwnedItems
- {
- get
- {
- return IsStacked || MediaSourceCount > 1;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public int? AiredSeasonNumber
- {
- get
- {
- return AirsAfterSeasonNumber ?? AirsBeforeSeasonNumber ?? ParentIndexNumber;
- }
- }
-
- [IgnoreDataMember]
- public override Folder LatestItemsIndexContainer
- {
- get
- {
- return Series;
- }
- }
-
- [IgnoreDataMember]
- public override Guid? DisplayParentId
- {
- get
- {
- return SeasonId;
- }
- }
-
- [IgnoreDataMember]
- protected override bool EnableDefaultVideoUserDataKeys
- {
- get
- {
- return false;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 16;
- value /= 9;
-
- return value;
- }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- var series = Series;
- if (series != null && ParentIndexNumber.HasValue && IndexNumber.HasValue)
- {
- var seriesUserDataKeys = series.GetUserDataKeys();
- var take = seriesUserDataKeys.Count;
- if (seriesUserDataKeys.Count > 1)
- {
- take--;
- }
- list.InsertRange(0, seriesUserDataKeys.Take(take).Select(i => i + ParentIndexNumber.Value.ToString("000") + IndexNumber.Value.ToString("000")));
- }
-
- return list;
- }
-
- /// <summary>
- /// This Episode's Series Instance
- /// </summary>
- /// <value>The series.</value>
- [IgnoreDataMember]
- public Series Series
- {
- get
- {
- var seriesId = SeriesId ?? FindSeriesId();
- return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
- }
- }
-
- [IgnoreDataMember]
- public Season Season
- {
- get
- {
- var seasonId = SeasonId ?? FindSeasonId();
- return seasonId.HasValue ? (LibraryManager.GetItemById(seasonId.Value) as Season) : null;
- }
- }
-
- [IgnoreDataMember]
- public bool IsInSeasonFolder
- {
- get
- {
- return FindParent<Season>() != null;
- }
- }
-
- [IgnoreDataMember]
- public string SeriesPresentationUniqueKey { get; set; }
-
- [IgnoreDataMember]
- public string SeriesName { get; set; }
-
- [IgnoreDataMember]
- public string SeasonName { get; set; }
-
- public string FindSeriesPresentationUniqueKey()
- {
- var series = Series;
- return series == null ? null : series.PresentationUniqueKey;
- }
-
- public string FindSeasonName()
- {
- var season = Season;
-
- if (season == null)
- {
- if (ParentIndexNumber.HasValue)
- {
- return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture);
- }
- return "Season Unknown";
- }
-
- return season.Name;
- }
-
- public string FindSeriesName()
- {
- var series = Series;
- return series == null ? SeriesName : series.Name;
- }
-
- public Guid? FindSeasonId()
- {
- var season = FindParent<Season>();
-
- // Episodes directly in series folder
- if (season == null)
- {
- var series = Series;
-
- if (series != null && ParentIndexNumber.HasValue)
- {
- var findNumber = ParentIndexNumber.Value;
-
- season = series.Children
- .OfType<Season>()
- .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == findNumber);
- }
- }
-
- return season == null ? (Guid?)null : season.Id;
- }
-
- /// <summary>
- /// Creates the name of the sort.
- /// </summary>
- /// <returns>System.String.</returns>
- protected override string CreateSortName()
- {
- return (ParentIndexNumber != null ? ParentIndexNumber.Value.ToString("000 - ") : "")
- + (IndexNumber != null ? IndexNumber.Value.ToString("0000 - ") : "") + Name;
- }
-
- /// <summary>
- /// Determines whether [contains episode number] [the specified number].
- /// </summary>
- /// <param name="number">The number.</param>
- /// <returns><c>true</c> if [contains episode number] [the specified number]; otherwise, <c>false</c>.</returns>
- public bool ContainsEpisodeNumber(int number)
- {
- if (IndexNumber.HasValue)
- {
- if (IndexNumberEnd.HasValue)
- {
- return number >= IndexNumber.Value && number <= IndexNumberEnd.Value;
- }
-
- return IndexNumber.Value == number;
- }
-
- return false;
- }
-
- [IgnoreDataMember]
- public override bool SupportsRemoteImageDownloading
- {
- get
- {
- if (IsMissingEpisode)
- {
- return false;
- }
-
- return true;
- }
- }
-
- [IgnoreDataMember]
- public bool IsMissingEpisode
- {
- get
- {
- return LocationType == LocationType.Virtual;
- }
- }
-
- [IgnoreDataMember]
- public Guid? SeasonId { get; set; }
- [IgnoreDataMember]
- public Guid? SeriesId { get; set; }
-
- public Guid? FindSeriesId()
- {
- var series = FindParent<Series>();
- return series == null ? (Guid?)null : series.Id;
- }
-
- public override IEnumerable<Guid> GetAncestorIds()
- {
- var list = base.GetAncestorIds().ToList();
-
- var seasonId = SeasonId;
-
- if (seasonId.HasValue && !list.Contains(seasonId.Value))
- {
- list.Add(seasonId.Value);
- }
-
- return list;
- }
-
- public override IEnumerable<FileSystemMetadata> GetDeletePaths()
- {
- return new[] {
- new FileSystemMetadata
- {
- FullName = Path,
- IsDirectory = IsFolder
- }
- }.Concat(GetLocalMetadataFilesToDelete());
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Series;
- }
-
- public EpisodeInfo GetLookupInfo()
- {
- var id = GetItemLookupInfo<EpisodeInfo>();
-
- var series = Series;
-
- if (series != null)
- {
- id.SeriesProviderIds = series.ProviderIds;
- }
-
- id.IsMissingEpisode = IsMissingEpisode;
- id.IndexNumberEnd = IndexNumberEnd;
-
- return id;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- try
- {
- if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
- {
- hasChanges = true;
- }
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
- }
-
- if (!ParentIndexNumber.HasValue)
- {
- var season = Season;
- if (season != null)
- {
- if (season.ParentIndexNumber.HasValue)
- {
- ParentIndexNumber = season.ParentIndexNumber;
- hasChanges = true;
- }
- }
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
deleted file mode 100644
index 00bb75fa78..0000000000
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ /dev/null
@@ -1,272 +0,0 @@
-using System;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Users;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.TV
-{
- /// <summary>
- /// Class Season
- /// </summary>
- public class Season : Folder, IHasSeries, IHasLookupInfo<SeasonInfo>
- {
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool IsPreSorted
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsDateLastMediaAdded
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override Guid? DisplayParentId
- {
- get { return SeriesId; }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- public string FindSeriesSortName()
- {
- var series = Series;
- return series == null ? SeriesName : series.SortName;
- }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- var series = Series;
- if (series != null)
- {
- list.InsertRange(0, series.GetUserDataKeys().Select(i => i + (IndexNumber ?? 0).ToString("000")));
- }
-
- return list;
- }
-
- public override int GetChildCount(User user)
- {
- var result = GetChildren(user, true).Count;
-
- return result;
- }
-
- /// <summary>
- /// This Episode's Series Instance
- /// </summary>
- /// <value>The series.</value>
- [IgnoreDataMember]
- public Series Series
- {
- get
- {
- var seriesId = SeriesId ?? FindSeriesId();
- return seriesId.HasValue ? (LibraryManager.GetItemById(seriesId.Value) as Series) : null;
- }
- }
-
- [IgnoreDataMember]
- public string SeriesPath
- {
- get
- {
- var series = Series;
-
- if (series != null)
- {
- return series.Path;
- }
-
- return FileSystem.GetDirectoryName(Path);
- }
- }
-
- public override string CreatePresentationUniqueKey()
- {
- if (IndexNumber.HasValue)
- {
- var series = Series;
- if (series != null)
- {
- return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000");
- }
- }
-
- return base.CreatePresentationUniqueKey();
- }
-
- /// <summary>
- /// Creates the name of the sort.
- /// </summary>
- /// <returns>System.String.</returns>
- protected override string CreateSortName()
- {
- return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name;
- }
-
- protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
- {
- if (query.User == null)
- {
- return base.GetItemsInternal(query);
- }
-
- var user = query.User;
-
- Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
-
- var items = GetEpisodes(user, query.DtoOptions).Where(filter);
-
- var result = PostFilterAndSort(items, query, false, false);
-
- return result;
- }
-
- /// <summary>
- /// Gets the episodes.
- /// </summary>
- public List<BaseItem> GetEpisodes(User user, DtoOptions options)
- {
- return GetEpisodes(Series, user, options);
- }
-
- public List<BaseItem> GetEpisodes(Series series, User user, DtoOptions options)
- {
- return GetEpisodes(series, user, null, options);
- }
-
- public List<BaseItem> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options)
- {
- return series.GetSeasonEpisodes(this, user, allSeriesEpisodes, options);
- }
-
- public List<BaseItem> GetEpisodes()
- {
- return Series.GetSeasonEpisodes(this, null, null, new DtoOptions(true));
- }
-
- public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
- {
- return GetEpisodes(user, new DtoOptions(true));
- }
-
- protected override bool GetBlockUnratedValue(UserPolicy config)
- {
- // Don't block. Let either the entire series rating or episode rating determine it
- return false;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Series;
- }
-
- [IgnoreDataMember]
- public string SeriesPresentationUniqueKey { get; set; }
-
- [IgnoreDataMember]
- public string SeriesName { get; set; }
-
- [IgnoreDataMember]
- public Guid? SeriesId { get; set; }
-
- public string FindSeriesPresentationUniqueKey()
- {
- var series = Series;
- return series == null ? null : series.PresentationUniqueKey;
- }
-
- public string FindSeriesName()
- {
- var series = Series;
- return series == null ? SeriesName : series.Name;
- }
-
- public Guid? FindSeriesId()
- {
- var series = FindParent<Series>();
- return series == null ? (Guid?)null : series.Id;
- }
-
- /// <summary>
- /// Gets the lookup information.
- /// </summary>
- /// <returns>SeasonInfo.</returns>
- public SeasonInfo GetLookupInfo()
- {
- var id = GetItemLookupInfo<SeasonInfo>();
-
- var series = Series;
-
- if (series != null)
- {
- id.SeriesProviderIds = series.ProviderIds;
- }
-
- return id;
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
- {
- IndexNumber = IndexNumber ?? LibraryManager.GetSeasonNumberFromPath(Path);
-
- // If a change was made record it
- if (IndexNumber.HasValue)
- {
- hasChanges = true;
- }
- }
-
- return hasChanges;
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
deleted file mode 100644
index ccd0a76369..0000000000
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ /dev/null
@@ -1,559 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Querying;
-using MediaBrowser.Model.Users;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Model.Extensions;
-using MediaBrowser.Model.Providers;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities.TV
-{
- /// <summary>
- /// Class Series
- /// </summary>
- public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer
- {
- public Series()
- {
- RemoteTrailers = EmptyMediaUrlArray;
- LocalTrailerIds = EmptyGuidArray;
- RemoteTrailerIds = EmptyGuidArray;
- AirDays = new DayOfWeek[] { };
- }
-
- public DayOfWeek[] AirDays { get; set; }
- public string AirTime { get; set; }
-
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool IsPreSorted
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsDateLastMediaAdded
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return true; }
- }
-
- public Guid[] LocalTrailerIds { get; set; }
- public Guid[] RemoteTrailerIds { get; set; }
-
- public MediaUrl[] RemoteTrailers { get; set; }
-
- /// <summary>
- /// airdate, dvd or absolute
- /// </summary>
- public string DisplayOrder { get; set; }
-
- /// <summary>
- /// Gets or sets the status.
- /// </summary>
- /// <value>The status.</value>
- public SeriesStatus? Status { get; set; }
-
- /// <summary>
- /// Gets or sets the date last episode added.
- /// </summary>
- /// <value>The date last episode added.</value>
- [IgnoreDataMember]
- public DateTime DateLastEpisodeAdded
- {
- get
- {
- return DateLastMediaAdded ?? DateTime.MinValue;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- public override string CreatePresentationUniqueKey()
- {
- if (LibraryManager.GetLibraryOptions(this).EnableAutomaticSeriesGrouping)
- {
- var userdatakeys = GetUserDataKeys();
-
- if (userdatakeys.Count > 1)
- {
- return AddLibrariesToPresentationUniqueKey(userdatakeys[0]);
- }
- }
-
- return base.CreatePresentationUniqueKey();
- }
-
- private string AddLibrariesToPresentationUniqueKey(string key)
- {
- var lang = GetPreferredMetadataLanguage();
- if (!string.IsNullOrWhiteSpace(lang))
- {
- key += "-" + lang;
- }
-
- var folders = LibraryManager.GetCollectionFolders(this)
- .Select(i => i.Id.ToString("N"))
- .ToArray();
-
- if (folders.Length == 0)
- {
- return key;
- }
-
- return key + "-" + string.Join("-", folders);
- }
-
- private static string GetUniqueSeriesKey(BaseItem series)
- {
- return series.GetPresentationUniqueKey();
- }
-
- public override int GetChildCount(User user)
- {
- var seriesKey = GetUniqueSeriesKey(this);
-
- var result = LibraryManager.GetCount(new InternalItemsQuery(user)
- {
- AncestorWithPresentationUniqueKey = null,
- SeriesPresentationUniqueKey = seriesKey,
- IncludeItemTypes = new[] { typeof(Season).Name },
- IsVirtualItem = false,
- Limit = 0,
- DtoOptions = new Dto.DtoOptions(false)
- {
- EnableImages = false
- }
- });
-
- return result;
- }
-
- public override int GetRecursiveChildCount(User user)
- {
- var seriesKey = GetUniqueSeriesKey(this);
-
- var query = new InternalItemsQuery(user)
- {
- AncestorWithPresentationUniqueKey = null,
- SeriesPresentationUniqueKey = seriesKey,
- DtoOptions = new Dto.DtoOptions(false)
- {
- EnableImages = false
- }
- };
-
- if (query.IncludeItemTypes.Length == 0)
- {
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
- }
- query.IsVirtualItem = false;
- query.Limit = 0;
- var totalRecordCount = LibraryManager.GetCount(query);
-
- return totalRecordCount;
- }
-
- /// <summary>
- /// Gets the user data key.
- /// </summary>
- /// <returns>System.String.</returns>
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- var key = this.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrWhiteSpace(key))
- {
- list.Insert(0, key);
- }
-
- key = this.GetProviderId(MetadataProviders.Tvdb);
- if (!string.IsNullOrWhiteSpace(key))
- {
- list.Insert(0, key);
- }
-
- return list;
- }
-
- public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
- {
- return GetSeasons(user, new DtoOptions(true));
- }
-
- public List<BaseItem> GetSeasons(User user, DtoOptions options)
- {
- var query = new InternalItemsQuery(user)
- {
- DtoOptions = options
- };
-
- SetSeasonQueryOptions(query, user);
-
- return LibraryManager.GetItemList(query);
- }
-
- private void SetSeasonQueryOptions(InternalItemsQuery query, User user)
- {
- var config = user.Configuration;
-
- var seriesKey = GetUniqueSeriesKey(this);
-
- query.AncestorWithPresentationUniqueKey = null;
- query.SeriesPresentationUniqueKey = seriesKey;
- query.IncludeItemTypes = new[] { typeof(Season).Name };
- query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
-
- if (!config.DisplayMissingEpisodes)
- {
- query.IsMissing = false;
- }
- }
-
- protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
- {
- if (query.User == null)
- {
- return base.GetItemsInternal(query);
- }
-
- var user = query.User;
-
- if (query.Recursive)
- {
- var seriesKey = GetUniqueSeriesKey(this);
-
- query.AncestorWithPresentationUniqueKey = null;
- query.SeriesPresentationUniqueKey = seriesKey;
- if (query.OrderBy.Length == 0)
- {
- query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
- }
- if (query.IncludeItemTypes.Length == 0)
- {
- query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
- }
- query.IsVirtualItem = false;
- return LibraryManager.GetItemsResult(query);
- }
-
- SetSeasonQueryOptions(query, user);
-
- return LibraryManager.GetItemsResult(query);
- }
-
- public IEnumerable<BaseItem> GetEpisodes(User user, DtoOptions options)
- {
- var seriesKey = GetUniqueSeriesKey(this);
-
- var query = new InternalItemsQuery(user)
- {
- AncestorWithPresentationUniqueKey = null,
- SeriesPresentationUniqueKey = seriesKey,
- IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
- OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
- DtoOptions = options
- };
- var config = user.Configuration;
- if (!config.DisplayMissingEpisodes)
- {
- query.IsMissing = false;
- }
-
- var allItems = LibraryManager.GetItemList(query);
-
- var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
-
- var allEpisodes = allItems.OfType<Season>()
- .SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes, options))
- .Reverse();
-
- // Specials could appear twice based on above - once in season 0, once in the aired season
- // This depends on settings for that series
- // When this happens, remove the duplicate from season 0
-
- return allEpisodes.DistinctBy(i => i.Id).Reverse();
- }
-
- public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
- {
- // Refresh bottom up, children first, then the boxset
- // By then hopefully the movies within will have Tmdb collection values
- var items = GetRecursiveChildren();
-
- var totalItems = items.Count;
- var numComplete = 0;
-
- // Refresh current item
- await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
-
- // Refresh seasons
- foreach (var item in items)
- {
- if (!(item is Season))
- {
- continue;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- if (refreshOptions.RefreshItem(item))
- {
- await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= totalItems;
- progress.Report(percent * 100);
- }
-
- // Refresh episodes and other children
- foreach (var item in items)
- {
- if ((item is Season))
- {
- continue;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
-
- var skipItem = false;
-
- var episode = item as Episode;
-
- if (episode != null
- && refreshOptions.MetadataRefreshMode != MetadataRefreshMode.FullRefresh
- && !refreshOptions.ReplaceAllMetadata
- && episode.IsMissingEpisode
- && episode.LocationType == LocationType.Virtual
- && episode.PremiereDate.HasValue
- && (DateTime.UtcNow - episode.PremiereDate.Value).TotalDays > 30)
- {
- skipItem = true;
- }
-
- if (!skipItem)
- {
- if (refreshOptions.RefreshItem(item))
- {
- await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
- }
- }
-
- numComplete++;
- double percent = numComplete;
- percent /= totalItems;
- progress.Report(percent * 100);
- }
-
- refreshOptions = new MetadataRefreshOptions(refreshOptions);
- refreshOptions.IsPostRecursiveRefresh = true;
- await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
- }
-
- public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options)
- {
- var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons;
-
- // add optimization when this setting is not enabled
- var seriesKey = queryFromSeries ?
- GetUniqueSeriesKey(this) :
- GetUniqueSeriesKey(parentSeason);
-
- var query = new InternalItemsQuery(user)
- {
- AncestorWithPresentationUniqueKey = queryFromSeries ? null : seriesKey,
- SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null,
- IncludeItemTypes = new[] { typeof(Episode).Name },
- OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
- DtoOptions = options
- };
- if (user != null)
- {
- var config = user.Configuration;
- if (!config.DisplayMissingEpisodes)
- {
- query.IsMissing = false;
- }
- }
-
- var allItems = LibraryManager.GetItemList(query);
-
- return GetSeasonEpisodes(parentSeason, user, allItems, options);
- }
-
- public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<BaseItem> allSeriesEpisodes, DtoOptions options)
- {
- if (allSeriesEpisodes == null)
- {
- return GetSeasonEpisodes(parentSeason, user, options);
- }
-
- var episodes = FilterEpisodesBySeason(allSeriesEpisodes, parentSeason, ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons);
-
- var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
-
- return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending).ToList();
- }
-
- /// <summary>
- /// Filters the episodes by season.
- /// </summary>
- public static IEnumerable<BaseItem> FilterEpisodesBySeason(IEnumerable<BaseItem> episodes, Season parentSeason, bool includeSpecials)
- {
- var seasonNumber = parentSeason.IndexNumber;
- var seasonPresentationKey = GetUniqueSeriesKey(parentSeason);
-
- var supportSpecialsInSeason = includeSpecials && seasonNumber.HasValue && seasonNumber.Value != 0;
-
- return episodes.Where(episode =>
- {
- var episodeItem = (Episode)episode;
-
- var currentSeasonNumber = supportSpecialsInSeason ? episodeItem.AiredSeasonNumber : episode.ParentIndexNumber;
- if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
- {
- return true;
- }
-
- if (!currentSeasonNumber.HasValue && !seasonNumber.HasValue && parentSeason.LocationType == LocationType.Virtual)
- {
- return true;
- }
-
- var season = episodeItem.Season;
- return season != null && string.Equals(GetUniqueSeriesKey(season), seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
- });
- }
-
- /// <summary>
- /// Filters the episodes by season.
- /// </summary>
- public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, int seasonNumber, bool includeSpecials)
- {
- if (!includeSpecials || seasonNumber < 1)
- {
- return episodes.Where(i => (i.ParentIndexNumber ?? -1) == seasonNumber);
- }
-
- return episodes.Where(i =>
- {
- var episode = i;
-
- if (episode != null)
- {
- var currentSeasonNumber = episode.AiredSeasonNumber;
-
- return currentSeasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber;
- }
-
- return false;
- });
- }
-
-
- protected override bool GetBlockUnratedValue(UserPolicy config)
- {
- return config.BlockUnratedItems.Contains(UnratedItem.Series);
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Series;
- }
-
- public SeriesInfo GetLookupInfo()
- {
- var info = GetItemLookupInfo<SeriesInfo>();
-
- return info;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (!ProductionYear.HasValue)
- {
- var info = LibraryManager.ParseName(Name);
-
- var yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- }
-
- return hasChanges;
- }
-
- public override List<ExternalUrl> GetRelatedUrls()
- {
- var list = base.GetRelatedUrls();
-
- var imdbId = this.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrWhiteSpace(imdbId))
- {
- list.Add(new ExternalUrl
- {
- Name = "Trakt",
- Url = string.Format("https://trakt.tv/shows/{0}", imdbId)
- });
- }
-
- return list;
- }
-
- [IgnoreDataMember]
- public override bool StopRefreshIfLocalMetadataFound
- {
- get
- {
- // Need people id's from internet metadata
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/TagExtensions.cs b/MediaBrowser.Controller/Entities/TagExtensions.cs
deleted file mode 100644
index e5d8f35d92..0000000000
--- a/MediaBrowser.Controller/Entities/TagExtensions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- public static class TagExtensions
- {
- public static void AddTag(this BaseItem item, string name)
- {
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentNullException("name");
- }
-
- var current = item.Tags;
-
- if (!current.Contains(name, StringComparer.OrdinalIgnoreCase))
- {
- if (current.Length == 0)
- {
- item.Tags = new[] { name };
- }
- else
- {
- var list = current.ToArray(current.Length + 1);
- list[list.Length - 1] = name;
-
- item.Tags = list;
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
deleted file mode 100644
index c5144aadf4..0000000000
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Entities;
-using System.Collections.Generic;
-using MediaBrowser.Model.Providers;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Trailer
- /// </summary>
- public class Trailer : Video, IHasLookupInfo<TrailerInfo>
- {
- public Trailer()
- {
- RemoteTrailers = new List<MediaUrl>();
- TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer };
- }
-
- public List<TrailerType> TrailerTypes { get; set; }
-
- public List<MediaUrl> RemoteTrailers { get; set; }
-
- [IgnoreDataMember]
- public bool IsLocalTrailer
- {
- get { return TrailerTypes.Contains(TrailerType.LocalTrailer); }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- public override UnratedItem GetBlockUnratedType()
- {
- return UnratedItem.Trailer;
- }
-
- public TrailerInfo GetLookupInfo()
- {
- var info = GetItemLookupInfo<TrailerInfo>();
-
- info.IsLocalTrailer = TrailerTypes.Contains(TrailerType.LocalTrailer);
-
- if (!IsInMixedFolder && LocationType == LocationType.FileSystem)
- {
- info.Name = System.IO.Path.GetFileName(ContainingFolderPath);
- }
-
- return info;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (!ProductionYear.HasValue)
- {
- var info = LibraryManager.ParseName(Name);
-
- var yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- else
- {
- // Try to get the year from the folder name
- if (!IsInMixedFolder)
- {
- info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
-
- yearInName = info.Year;
-
- if (yearInName.HasValue)
- {
- ProductionYear = yearInName;
- hasChanges = true;
- }
- }
- }
- }
-
- return hasChanges;
- }
-
- public override List<ExternalUrl> GetRelatedUrls()
- {
- var list = base.GetRelatedUrls();
-
- var imdbId = this.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrWhiteSpace(imdbId))
- {
- list.Add(new ExternalUrl
- {
- Name = "Trakt",
- Url = string.Format("https://trakt.tv/movies/{0}", imdbId)
- });
- }
-
- return list;
- }
-
- [IgnoreDataMember]
- public override bool StopRefreshIfLocalMetadataFound
- {
- get
- {
- // Need people id's from internet metadata
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
deleted file mode 100644
index 821327b7f3..0000000000
--- a/MediaBrowser.Controller/Entities/User.cs
+++ /dev/null
@@ -1,351 +0,0 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
-using MediaBrowser.Model.Connect;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Users;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class User
- /// </summary>
- public class User : BaseItem
- {
- public static IUserManager UserManager { get; set; }
- public static IXmlSerializer XmlSerializer { get; set; }
-
- /// <summary>
- /// From now on all user paths will be Id-based.
- /// This is for backwards compatibility.
- /// </summary>
- public bool UsesIdForConfigurationPath { get; set; }
-
- /// <summary>
- /// Gets or sets the password.
- /// </summary>
- /// <value>The password.</value>
- public string Password { get; set; }
- public string EasyPassword { get; set; }
- public string Salt { get; set; }
-
- public string ConnectUserName { get; set; }
- public string ConnectUserId { get; set; }
- public UserLinkType? ConnectLinkType { get; set; }
- public string ConnectAccessKey { get; set; }
-
- // Strictly to remove IgnoreDataMember
- public override ItemImageInfo[] ImageInfos
- {
- get
- {
- return base.ImageInfos;
- }
- set
- {
- base.ImageInfos = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- [IgnoreDataMember]
- public override string Path
- {
- get
- {
- // Return this so that metadata providers will look in here
- return ConfigurationDirectoryPath;
- }
- set
- {
- base.Path = value;
- }
- }
-
- private string _name;
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- public override string Name
- {
- get
- {
- return _name;
- }
- set
- {
- _name = value;
-
- // lazy load this again
- SortName = null;
- }
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Gets the root folder.
- /// </summary>
- /// <value>The root folder.</value>
- [IgnoreDataMember]
- public Folder RootFolder
- {
- get
- {
- return LibraryManager.GetUserRootFolder();
- }
- }
-
- /// <summary>
- /// Gets or sets the last login date.
- /// </summary>
- /// <value>The last login date.</value>
- public DateTime? LastLoginDate { get; set; }
- /// <summary>
- /// Gets or sets the last activity date.
- /// </summary>
- /// <value>The last activity date.</value>
- public DateTime? LastActivityDate { get; set; }
-
- private volatile UserConfiguration _config;
- private readonly object _configSyncLock = new object();
- [IgnoreDataMember]
- public UserConfiguration Configuration
- {
- get
- {
- if (_config == null)
- {
- lock (_configSyncLock)
- {
- if (_config == null)
- {
- _config = UserManager.GetUserConfiguration(this);
- }
- }
- }
-
- return _config;
- }
- set { _config = value; }
- }
-
- private volatile UserPolicy _policy;
- private readonly object _policySyncLock = new object();
- [IgnoreDataMember]
- public UserPolicy Policy
- {
- get
- {
- if (_policy == null)
- {
- lock (_policySyncLock)
- {
- if (_policy == null)
- {
- _policy = UserManager.GetUserPolicy(this);
- }
- }
- }
-
- return _policy;
- }
- set { _policy = value; }
- }
-
- /// <summary>
- /// Renames the user.
- /// </summary>
- /// <param name="newName">The new name.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public Task Rename(string newName)
- {
- if (string.IsNullOrEmpty(newName))
- {
- throw new ArgumentNullException("newName");
- }
-
- // If only the casing is changing, leave the file system alone
- if (!UsesIdForConfigurationPath && !string.Equals(newName, Name, StringComparison.OrdinalIgnoreCase))
- {
- UsesIdForConfigurationPath = true;
-
- // Move configuration
- var newConfigDirectory = GetConfigurationDirectoryPath(newName);
- var oldConfigurationDirectory = ConfigurationDirectoryPath;
-
- // Exceptions will be thrown if these paths already exist
- if (FileSystem.DirectoryExists(newConfigDirectory))
- {
- FileSystem.DeleteDirectory(newConfigDirectory, true);
- }
-
- if (FileSystem.DirectoryExists(oldConfigurationDirectory))
- {
- FileSystem.MoveDirectory(oldConfigurationDirectory, newConfigDirectory);
- }
- else
- {
- FileSystem.CreateDirectory(newConfigDirectory);
- }
- }
-
- Name = newName;
-
- return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(Logger, FileSystem))
- {
- ReplaceAllMetadata = true,
- ImageRefreshMode = ImageRefreshMode.FullRefresh,
- MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
- ForceSave = true
-
- }, CancellationToken.None);
- }
-
- public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
- {
- UserManager.UpdateUser(this);
- }
-
- /// <summary>
- /// Gets the path to the user's configuration directory
- /// </summary>
- /// <value>The configuration directory path.</value>
- [IgnoreDataMember]
- public string ConfigurationDirectoryPath
- {
- get
- {
- return GetConfigurationDirectoryPath(Name);
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
-
- /// <summary>
- /// Gets the configuration directory path.
- /// </summary>
- /// <param name="username">The username.</param>
- /// <returns>System.String.</returns>
- private string GetConfigurationDirectoryPath(string username)
- {
- var parentPath = ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath;
-
- // Legacy
- if (!UsesIdForConfigurationPath)
- {
- if (string.IsNullOrEmpty(username))
- {
- throw new ArgumentNullException("username");
- }
-
- var safeFolderName = FileSystem.GetValidFilename(username);
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, safeFolderName);
- }
-
- return System.IO.Path.Combine(parentPath, Id.ToString("N"));
- }
-
- public bool IsParentalScheduleAllowed()
- {
- return IsParentalScheduleAllowed(DateTime.UtcNow);
- }
-
- public bool IsParentalScheduleAllowed(DateTime date)
- {
- var schedules = Policy.AccessSchedules;
-
- if (schedules.Length == 0)
- {
- return true;
- }
-
- foreach (var i in schedules)
- {
- if (IsParentalScheduleAllowed(i, date))
- {
- return true;
- }
- }
- return false;
- }
-
- private bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
- {
- if (date.Kind != DateTimeKind.Utc)
- {
- throw new ArgumentException("Utc date expected");
- }
-
- var localTime = date.ToLocalTime();
-
- return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) &&
- IsWithinTime(schedule, localTime);
- }
-
- private bool IsWithinTime(AccessSchedule schedule, DateTime localTime)
- {
- var hour = localTime.TimeOfDay.TotalHours;
-
- return hour >= schedule.StartHour && hour <= schedule.EndHour;
- }
-
- public bool IsFolderGrouped(Guid id)
- {
- foreach (var i in Configuration.GroupedFolders)
- {
- if (new Guid(i) == id)
- {
- return true;
- }
- }
- return false;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/UserItemData.cs b/MediaBrowser.Controller/Entities/UserItemData.cs
deleted file mode 100644
index 0e13269499..0000000000
--- a/MediaBrowser.Controller/Entities/UserItemData.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using System;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class UserItemData
- /// </summary>
- public class UserItemData
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the key.
- /// </summary>
- /// <value>The key.</value>
- public string Key { get; set; }
-
- /// <summary>
- /// The _rating
- /// </summary>
- private double? _rating;
- /// <summary>
- /// Gets or sets the users 0-10 rating
- /// </summary>
- /// <value>The rating.</value>
- /// <exception cref="System.ArgumentOutOfRangeException">Rating;A 0 to 10 rating is required for UserItemData.</exception>
- public double? Rating
- {
- get
- {
- return _rating;
- }
- set
- {
- if (value.HasValue)
- {
- if (value.Value < 0 || value.Value > 10)
- {
- throw new ArgumentOutOfRangeException("value", "A 0 to 10 rating is required for UserItemData.");
- }
- }
-
- _rating = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the playback position ticks.
- /// </summary>
- /// <value>The playback position ticks.</value>
- public long PlaybackPositionTicks { get; set; }
-
- /// <summary>
- /// Gets or sets the play count.
- /// </summary>
- /// <value>The play count.</value>
- public int PlayCount { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance is favorite.
- /// </summary>
- /// <value><c>true</c> if this instance is favorite; otherwise, <c>false</c>.</value>
- public bool IsFavorite { get; set; }
-
- /// <summary>
- /// Gets or sets the last played date.
- /// </summary>
- /// <value>The last played date.</value>
- public DateTime? LastPlayedDate { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this <see cref="UserItemData" /> is played.
- /// </summary>
- /// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
- public bool Played { get; set; }
- /// <summary>
- /// Gets or sets the index of the audio stream.
- /// </summary>
- /// <value>The index of the audio stream.</value>
- public int? AudioStreamIndex { get; set; }
- /// <summary>
- /// Gets or sets the index of the subtitle stream.
- /// </summary>
- /// <value>The index of the subtitle stream.</value>
- public int? SubtitleStreamIndex { get; set; }
-
- public const double MinLikeValue = 6.5;
-
- /// <summary>
- /// This is an interpreted property to indicate likes or dislikes
- /// This should never be serialized.
- /// </summary>
- /// <value><c>null</c> if [likes] contains no value, <c>true</c> if [likes]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public bool? Likes
- {
- get
- {
- if (Rating != null)
- {
- return Rating >= MinLikeValue;
- }
-
- return null;
- }
- set
- {
- if (value.HasValue)
- {
- Rating = value.Value ? 10 : 1;
- }
- else
- {
- Rating = null;
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs
deleted file mode 100644
index 2ed3bf20fa..0000000000
--- a/MediaBrowser.Controller/Entities/UserRootFolder.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Library;
-using MediaBrowser.Model.Querying;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Special class used for User Roots. Children contain actual ones defined for this user
- /// PLUS the virtual folders from the physical root (added by plug-ins).
- /// </summary>
- public class UserRootFolder : Folder
- {
- private List<Guid> _childrenIds = null;
- private readonly object _childIdsLock = new object();
- protected override List<BaseItem> LoadChildren()
- {
- lock (_childIdsLock)
- {
- if (_childrenIds == null)
- {
- var list = base.LoadChildren();
- _childrenIds = list.Select(i => i.Id).ToList();
- return list;
- }
-
- return _childrenIds.Select(LibraryManager.GetItemById).Where(i => i != null).ToList();
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- private void ClearCache()
- {
- lock (_childIdsLock)
- {
- _childrenIds = null;
- }
- }
-
- protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
- {
- if (query.Recursive)
- {
- return QueryRecursive(query);
- }
-
- var result = UserViewManager.GetUserViews(new UserViewQuery
- {
- UserId = query.User.Id.ToString("N"),
- PresetViews = query.PresetViews
-
- }, CancellationToken.None).Result;
-
- var user = query.User;
- Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
-
- return PostFilterAndSort(result.Where(filter), query, true, true);
- }
-
- public override int GetChildCount(User user)
- {
- return GetChildren(user, true).Count;
- }
-
- [IgnoreDataMember]
- protected override bool SupportsShortcutChildren
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool IsPreSorted
- {
- get
- {
- return true;
- }
- }
-
- protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
- {
- var list = base.GetEligibleChildrenForRecursiveChildren(user).ToList();
- list.AddRange(LibraryManager.RootFolder.VirtualChildren);
-
- return list;
- }
-
- public override bool BeforeMetadataRefresh()
- {
- ClearCache();
-
- var hasChanges = base.BeforeMetadataRefresh();
-
- if (string.Equals("default", Name, StringComparison.OrdinalIgnoreCase))
- {
- Name = "Media Folders";
- hasChanges = true;
- }
-
- return hasChanges;
- }
-
- protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
- {
- ClearCache();
-
- return base.GetNonCachedChildren(directoryService);
- }
-
- protected override async Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
- {
- ClearCache();
-
- await base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService)
- .ConfigureAwait(false);
-
- ClearCache();
-
- // Not the best way to handle this, but it solves an issue
- // CollectionFolders aren't always getting saved after changes
- // This means that grabbing the item by Id may end up returning the old one
- // Fix is in two places - make sure the folder gets saved
- // And here to remedy it for affected users.
- // In theory this can be removed eventually.
- foreach (var item in Children)
- {
- LibraryManager.RegisterItem(item);
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
deleted file mode 100644
index 2152e65cfb..0000000000
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-using MediaBrowser.Controller.Playlists;
-using MediaBrowser.Controller.TV;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Querying;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using MediaBrowser.Model.Serialization;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Dto;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class UserView : Folder
- {
- public string ViewType { get; set; }
- public Guid DisplayParentId { get; set; }
-
- public Guid? UserId { get; set; }
-
- public static ITVSeriesManager TVSeriesManager;
- public static IPlaylistManager PlaylistManager;
-
- public override IEnumerable<Guid> GetIdsForAncestorQuery()
- {
- var list = new List<Guid>();
-
- if (DisplayParentId != Guid.Empty)
- {
- list.Add(DisplayParentId);
- }
- else if (ParentId != Guid.Empty)
- {
- list.Add(ParentId);
- }
- else
- {
- list.Add(Id);
- }
- return list;
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return false;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return false;
- }
- }
-
- //public override double? GetDefaultPrimaryImageAspectRatio()
- //{
- // double value = 16;
- // value /= 9;
-
- // return value;
- //}
-
- public override int GetChildCount(User user)
- {
- return GetChildren(user, true).Count;
- }
-
- protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query)
- {
- var parent = this as Folder;
-
- if (DisplayParentId != Guid.Empty)
- {
- parent = LibraryManager.GetItemById(DisplayParentId) as Folder ?? parent;
- }
- else if (ParentId != Guid.Empty)
- {
- parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
- }
-
- return new UserViewBuilder(UserViewManager, LiveTvManager, ChannelManager, LibraryManager, Logger, UserDataManager, TVSeriesManager, ConfigurationManager, PlaylistManager)
- .GetUserItems(parent, this, ViewType, query).Result;
- }
-
- public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
- {
- var result = GetItemList(new InternalItemsQuery
- {
- User = user,
- EnableTotalRecordCount = false,
- DtoOptions = new DtoOptions(true)
-
- });
-
- return result.ToList();
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
- {
- var result = GetItemList(new InternalItemsQuery
- {
- User = user,
- Recursive = true,
- EnableTotalRecordCount = false,
-
- ForceDirect = true,
-
- DtoOptions = query.DtoOptions
-
- });
-
- return result.Where(i => UserViewBuilder.FilterItem(i, query));
- }
-
- protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
- {
- return GetChildren(user, false);
- }
-
- public static bool IsUserSpecific(Folder folder)
- {
- var standaloneTypes = new List<string>
- {
- CollectionType.Playlists
- };
-
- var collectionFolder = folder as ICollectionFolder;
-
- if (collectionFolder == null)
- {
- return false;
- }
-
- var supportsUserSpecific = folder as ISupportsUserSpecificView;
- if (supportsUserSpecific != null && supportsUserSpecific.EnableUserSpecificView)
- {
- return true;
- }
-
- return standaloneTypes.Contains(collectionFolder.CollectionType ?? string.Empty);
- }
-
- public static bool IsEligibleForGrouping(Folder folder)
- {
- var collectionFolder = folder as ICollectionFolder;
- return collectionFolder != null && IsEligibleForGrouping(collectionFolder.CollectionType);
- }
-
- public static bool IsEligibleForGrouping(string viewType)
- {
- var types = new[]
- {
- CollectionType.Movies,
- CollectionType.TvShows,
- string.Empty
- };
-
- return types.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
- }
-
- public static bool EnableOriginalFolder(string viewType)
- {
- var types = new[]
- {
- CollectionType.Games,
- CollectionType.Books,
- CollectionType.MusicVideos,
- CollectionType.HomeVideos,
- CollectionType.Photos,
- CollectionType.Music,
- CollectionType.BoxSets
- };
-
- return types.Contains(viewType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
- }
-
- protected override Task ValidateChildrenInternal(IProgress<double> progress, System.Threading.CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, Providers.MetadataRefreshOptions refreshOptions, Providers.IDirectoryService directoryService)
- {
- return Task.FromResult(true);
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
deleted file mode 100644
index 97b96127a2..0000000000
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ /dev/null
@@ -1,1778 +0,0 @@
-using MediaBrowser.Controller.Channels;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
-using MediaBrowser.Controller.Playlists;
-using MediaBrowser.Controller.TV;
-using MediaBrowser.Model.Channels;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.LiveTv;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Querying;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class UserViewBuilder
- {
- private readonly IChannelManager _channelManager;
- private readonly ILiveTvManager _liveTvManager;
- private readonly IUserViewManager _userViewManager;
- private readonly ILibraryManager _libraryManager;
- private readonly ILogger _logger;
- private readonly IUserDataManager _userDataManager;
- private readonly ITVSeriesManager _tvSeriesManager;
- private readonly IServerConfigurationManager _config;
- private readonly IPlaylistManager _playlistManager;
-
- public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, IServerConfigurationManager config, IPlaylistManager playlistManager)
- {
- _userViewManager = userViewManager;
- _liveTvManager = liveTvManager;
- _channelManager = channelManager;
- _libraryManager = libraryManager;
- _logger = logger;
- _userDataManager = userDataManager;
- _tvSeriesManager = tvSeriesManager;
- _config = config;
- _playlistManager = playlistManager;
- }
-
- public async Task<QueryResult<BaseItem>> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query)
- {
- var user = query.User;
-
- //if (query.IncludeItemTypes != null &&
- // query.IncludeItemTypes.Length == 1 &&
- // string.Equals(query.IncludeItemTypes[0], "Playlist", StringComparison.OrdinalIgnoreCase))
- //{
- // if (!string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
- // {
- // return await FindPlaylists(queryParent, user, query).ConfigureAwait(false);
- // }
- //}
-
- switch (viewType)
- {
- case CollectionType.Channels:
- {
- var result = await _channelManager.GetChannelsInternal(new ChannelQuery
- {
- UserId = user == null ? null : user.Id.ToString("N"),
- Limit = query.Limit,
- StartIndex = query.StartIndex
-
- }, CancellationToken.None).ConfigureAwait(false);
-
- return GetResult(result);
- }
-
- case SpecialFolder.LiveTvChannels:
- {
- var result = _liveTvManager.GetInternalChannels(new LiveTvChannelQuery
- {
- UserId = query.User.Id.ToString("N"),
- Limit = query.Limit,
- StartIndex = query.StartIndex
-
- }, new DtoOptions(), CancellationToken.None);
-
- return GetResult(result);
- }
-
- case SpecialFolder.LiveTvNowPlaying:
- {
- var result = _liveTvManager.GetRecommendedProgramsInternal(new RecommendedProgramQuery
- {
- UserId = query.User.Id.ToString("N"),
- Limit = query.Limit,
- IsAiring = true
-
- }, new Dto.DtoOptions(), CancellationToken.None);
-
- return GetResult(result);
- }
-
- case SpecialFolder.LiveTvRecordingGroups:
- {
- var result = await _liveTvManager.GetInternalRecordings(new RecordingQuery
- {
- UserId = query.User.Id.ToString("N"),
- Status = RecordingStatus.Completed,
- Limit = query.Limit,
- StartIndex = query.StartIndex
-
- }, new DtoOptions(), CancellationToken.None).ConfigureAwait(false);
-
- return GetResult(result);
- }
-
- case CollectionType.LiveTv:
- {
- return await GetLiveTvView(queryParent, user, query).ConfigureAwait(false);
- }
-
- case CollectionType.Photos:
- case CollectionType.Books:
- case CollectionType.HomeVideos:
- case CollectionType.Games:
- case CollectionType.MusicVideos:
- {
- if (query.Recursive)
- {
- query.Recursive = true;
- query.Parent = queryParent;
- query.SetUser(user);
-
- return _libraryManager.GetItemsResult(query);
- }
- return GetResult(queryParent.GetChildren(user, true), queryParent, query);
- }
-
- case CollectionType.Folders:
- return GetResult(user.RootFolder.GetChildren(user, true), queryParent, query);
-
- case CollectionType.Playlists:
- return GetPlaylistsView(queryParent, user, query);
-
- case CollectionType.BoxSets:
- return GetBoxsetView(queryParent, user, query);
-
- case CollectionType.TvShows:
- return GetTvView(queryParent, user, query);
-
- case CollectionType.Movies:
- return GetMovieFolders(queryParent, user, query);
-
- case SpecialFolder.TvShowSeries:
- return GetTvSeries(queryParent, user, query);
-
- case SpecialFolder.TvGenres:
- return GetTvGenres(queryParent, user, query);
-
- case SpecialFolder.TvGenre:
- return GetTvGenreItems(queryParent, displayParent, user, query);
-
- case SpecialFolder.TvResume:
- return GetTvResume(queryParent, user, query);
-
- case SpecialFolder.TvNextUp:
- return GetTvNextUp(queryParent, query);
-
- case SpecialFolder.TvLatest:
- return GetTvLatest(queryParent, user, query);
-
- case SpecialFolder.MovieFavorites:
- return GetFavoriteMovies(queryParent, user, query);
-
- case SpecialFolder.MovieLatest:
- return GetMovieLatest(queryParent, user, query);
-
- case SpecialFolder.MovieGenres:
- return GetMovieGenres(queryParent, user, query);
-
- case SpecialFolder.MovieGenre:
- return GetMovieGenreItems(queryParent, displayParent, user, query);
-
- case SpecialFolder.MovieResume:
- return GetMovieResume(queryParent, user, query);
-
- case SpecialFolder.MovieMovies:
- return GetMovieMovies(queryParent, user, query);
-
- case SpecialFolder.MovieCollections:
- return GetMovieCollections(queryParent, user, query);
-
- case SpecialFolder.TvFavoriteEpisodes:
- return GetFavoriteEpisodes(queryParent, user, query);
-
- case SpecialFolder.TvFavoriteSeries:
- return GetFavoriteSeries(queryParent, user, query);
-
- case CollectionType.Music:
- return GetMusicFolders(queryParent, user, query);
-
- case SpecialFolder.MusicGenres:
- return GetMusicGenres(queryParent, user, query);
-
- case SpecialFolder.MusicLatest:
- return GetMusicLatest(queryParent, user, query);
-
- case SpecialFolder.MusicPlaylists:
- return GetMusicPlaylists(queryParent, user, query);
-
- case SpecialFolder.MusicAlbums:
- return GetMusicAlbums(queryParent, user, query);
-
- case SpecialFolder.MusicAlbumArtists:
- return GetMusicAlbumArtists(queryParent, user, query);
-
- case SpecialFolder.MusicArtists:
- return GetMusicArtists(queryParent, user, query);
-
- case SpecialFolder.MusicSongs:
- return GetMusicSongs(queryParent, user, query);
-
- case SpecialFolder.MusicFavorites:
- return GetMusicFavorites(queryParent, user, query);
-
- case SpecialFolder.MusicFavoriteAlbums:
- return GetFavoriteAlbums(queryParent, user, query);
-
- case SpecialFolder.MusicFavoriteArtists:
- return GetFavoriteArtists(queryParent, user, query);
-
- case SpecialFolder.MusicFavoriteSongs:
- return GetFavoriteSongs(queryParent, user, query);
-
- default:
- {
- if (queryParent is UserView)
- {
- return GetResult(GetMediaFolders(user).OfType<Folder>().SelectMany(i => i.GetChildren(user, true)), queryParent, query);
- }
- return GetResult(queryParent.GetChildren(user, true), queryParent, query);
- }
- }
- }
-
- private QueryResult<BaseItem> GetMusicFolders(Folder parent, User user, InternalItemsQuery query)
- {
- if (query.Recursive)
- {
- query.Recursive = true;
- query.SetUser(user);
-
- if (query.IncludeItemTypes.Length == 0)
- {
- query.IncludeItemTypes = new[] { typeof(MusicArtist).Name, typeof(MusicAlbum).Name, typeof(Audio.Audio).Name, typeof(MusicVideo).Name };
- }
-
- return parent.QueryRecursive(query);
- }
-
- var list = new List<BaseItem>();
-
- list.Add(GetUserView(SpecialFolder.MusicLatest, "Latest", "0", parent));
- list.Add(GetUserView(SpecialFolder.MusicPlaylists, "Playlists", "1", parent));
- list.Add(GetUserView(SpecialFolder.MusicAlbums, "Albums", "2", parent));
- list.Add(GetUserView(SpecialFolder.MusicAlbumArtists, "HeaderAlbumArtists", "3", parent));
- list.Add(GetUserView(SpecialFolder.MusicArtists, "Artists", "4", parent));
- list.Add(GetUserView(SpecialFolder.MusicSongs, "Songs", "5", parent));
- list.Add(GetUserView(SpecialFolder.MusicGenres, "Genres", "6", parent));
- list.Add(GetUserView(SpecialFolder.MusicFavorites, "Favorites", "7", parent));
-
- return GetResult(list, parent, query);
- }
-
- private QueryResult<BaseItem> GetMusicFavorites(Folder parent, User user, InternalItemsQuery query)
- {
- var list = new List<BaseItem>();
-
- list.Add(GetUserView(SpecialFolder.MusicFavoriteAlbums, "HeaderFavoriteAlbums", "0", parent));
- list.Add(GetUserView(SpecialFolder.MusicFavoriteArtists, "HeaderFavoriteArtists", "1", parent));
- list.Add(GetUserView(SpecialFolder.MusicFavoriteSongs, "HeaderFavoriteSongs", "2", parent));
-
- return GetResult(list, parent, query);
- }
-
- private QueryResult<BaseItem> GetMusicGenres(Folder parent, User user, InternalItemsQuery query)
- {
- var result = _libraryManager.GetMusicGenres(new InternalItemsQuery(user)
- {
- AncestorIds = new[] { parent.Id.ToString("N") },
- StartIndex = query.StartIndex,
- Limit = query.Limit
- });
-
- return new QueryResult<BaseItem>
- {
- TotalRecordCount = result.TotalRecordCount,
- Items = result.Items.Select(i => i.Item1).ToArray()
- };
- }
-
- private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
- {
- var artists = _libraryManager.GetAlbumArtists(new InternalItemsQuery(user)
- {
- AncestorIds = new[] { parent.Id.ToString("N") },
- StartIndex = query.StartIndex,
- Limit = query.Limit
- });
-
- return new QueryResult<BaseItem>
- {
- TotalRecordCount = artists.TotalRecordCount,
- Items = artists.Items.Select(i => i.Item1).ToArray()
- };
- }
-
- private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
- {
- var artists = _libraryManager.GetArtists(new InternalItemsQuery(user)
- {
- AncestorIds = new[] { parent.Id.ToString("N") },
- StartIndex = query.StartIndex,
- Limit = query.Limit
- });
-
- return new QueryResult<BaseItem>
- {
- TotalRecordCount = artists.TotalRecordCount,
- Items = artists.Items.Select(i => i.Item1).ToArray()
- };
- }
-
- private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
- {
- var artists = _libraryManager.GetArtists(new InternalItemsQuery(user)
- {
- AncestorIds = new[] { parent.Id.ToString("N") },
- StartIndex = query.StartIndex,
- Limit = query.Limit,
- IsFavorite = true
- });
-
- return new QueryResult<BaseItem>
- {
- TotalRecordCount = artists.TotalRecordCount,
- Items = artists.Items.Select(i => i.Item1).ToArray()
- };
- }
-
- private QueryResult<BaseItem> GetMusicPlaylists(Folder parent, User user, InternalItemsQuery query)
- {
- query.Parent = null;
- query.IncludeItemTypes = new[] { typeof(Playlist).Name };
- query.SetUser(user);
- query.Recursive = true;
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetMusicAlbums(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
-
- query.IncludeItemTypes = new[] { typeof(MusicAlbum).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetMusicSongs(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
-
- query.IncludeItemTypes = new[] { typeof(Audio.Audio).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetMusicLatest(Folder parent, User user, InternalItemsQuery query)
- {
- var items = _userViewManager.GetLatestItems(new LatestItemsQuery
- {
- UserId = user.Id.ToString("N"),
- Limit = GetSpecialItemsLimit(),
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
- ParentId = parent == null ? null : parent.Id.ToString("N"),
- GroupItems = true
-
- }, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null);
-
- query.OrderBy = new Tuple<string, SortOrder>[] { };
-
- return PostFilterAndSort(items, parent, null, query, false, true);
- }
-
- private QueryResult<BaseItem> GetFavoriteSongs(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Audio.Audio).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetFavoriteAlbums(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(MusicAlbum).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private int GetSpecialItemsLimit()
- {
- return 50;
- }
-
- private QueryResult<BaseItem> GetMovieFolders(Folder parent, User user, InternalItemsQuery query)
- {
- if (query.Recursive)
- {
- query.Recursive = true;
- query.SetUser(user);
-
- if (query.IncludeItemTypes.Length == 0)
- {
- query.IncludeItemTypes = new[] { typeof(Movie).Name, typeof(BoxSet).Name };
- }
-
- return parent.QueryRecursive(query);
- }
-
- var list = new List<BaseItem>();
-
- list.Add(GetUserView(SpecialFolder.MovieResume, "HeaderContinueWatching", "0", parent));
- list.Add(GetUserView(SpecialFolder.MovieLatest, "Latest", "1", parent));
- list.Add(GetUserView(SpecialFolder.MovieMovies, "Movies", "2", parent));
- list.Add(GetUserView(SpecialFolder.MovieCollections, "Collections", "3", parent));
- list.Add(GetUserView(SpecialFolder.MovieFavorites, "Favorites", "4", parent));
- list.Add(GetUserView(SpecialFolder.MovieGenres, "Genres", "5", parent));
-
- return GetResult(list, parent, query);
- }
-
- private QueryResult<BaseItem> GetFavoriteMovies(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetFavoriteSeries(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Series).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetFavoriteEpisodes(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.IsFavorite = true;
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetMovieMovies(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
-
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetMovieCollections(Folder parent, User user, InternalItemsQuery query)
- {
- return GetBoxsetView(parent, user, query);
- }
-
- private QueryResult<BaseItem> GetMovieLatest(Folder parent, User user, InternalItemsQuery query)
- {
- query.OrderBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
-
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
-
- return ConvertToResult(_libraryManager.GetItemList(query));
- }
-
- private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
- {
- query.OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
- query.IsResumable = true;
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
-
- return ConvertToResult(_libraryManager.GetItemList(query));
- }
-
- private QueryResult<BaseItem> ConvertToResult(List<BaseItem> items)
- {
- var arr = items.ToArray();
- return new QueryResult<BaseItem>
- {
- Items = arr,
- TotalRecordCount = arr.Length
- };
- }
-
- private QueryResult<BaseItem> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
- {
- var genres = parent.QueryRecursive(new InternalItemsQuery(user)
- {
- IncludeItemTypes = new[] { typeof(Movie).Name },
- Recursive = true,
- EnableTotalRecordCount = false
-
- }).Items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(i =>
- {
- try
- {
- return _libraryManager.GetGenre(i);
- }
- catch
- {
- // Full exception logged at lower levels
- _logger.Error("Error getting genre");
- return null;
- }
-
- })
- .Where(i => i != null)
- .Select(i => GetUserViewWithName(i.Name, SpecialFolder.MovieGenre, i.SortName, parent));
-
- return GetResult(genres, parent, query);
- }
-
- private QueryResult<BaseItem> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = queryParent;
- query.GenreIds = new[] { displayParent.Id.ToString("N") };
- query.SetUser(user);
-
- query.IncludeItemTypes = new[] { typeof(Movie).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetPlaylistsView(Folder parent, User user, InternalItemsQuery query)
- {
- return GetResult(_playlistManager.GetPlaylists(user.Id.ToString("N")), parent, query);
- }
-
- private QueryResult<BaseItem> GetBoxsetView(Folder parent, User user, InternalItemsQuery query)
- {
- query.Parent = null;
- query.IncludeItemTypes = new[] { typeof(BoxSet).Name };
- query.SetUser(user);
- query.Recursive = true;
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetTvView(Folder parent, User user, InternalItemsQuery query)
- {
- if (query.Recursive)
- {
- query.Recursive = true;
- query.SetUser(user);
-
- if (query.IncludeItemTypes.Length == 0)
- {
- query.IncludeItemTypes = new[] { typeof(Series).Name, typeof(Season).Name, typeof(Episode).Name };
- }
-
- return parent.QueryRecursive(query);
- }
-
- var list = new List<BaseItem>();
-
- list.Add(GetUserView(SpecialFolder.TvResume, "HeaderContinueWatching", "0", parent));
- list.Add(GetUserView(SpecialFolder.TvNextUp, "HeaderNextUp", "1", parent));
- list.Add(GetUserView(SpecialFolder.TvLatest, "Latest", "2", parent));
- list.Add(GetUserView(SpecialFolder.TvShowSeries, "Shows", "3", parent));
- list.Add(GetUserView(SpecialFolder.TvFavoriteSeries, "HeaderFavoriteShows", "4", parent));
- list.Add(GetUserView(SpecialFolder.TvFavoriteEpisodes, "HeaderFavoriteEpisodes", "5", parent));
- list.Add(GetUserView(SpecialFolder.TvGenres, "Genres", "6", parent));
-
- return GetResult(list, parent, query);
- }
-
- private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
- {
- query.OrderBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
-
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
- query.IsVirtualItem = false;
-
- return ConvertToResult(_libraryManager.GetItemList(query));
- }
-
- private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
- {
- var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows, string.Empty });
-
- var result = _tvSeriesManager.GetNextUp(new NextUpQuery
- {
- Limit = query.Limit,
- StartIndex = query.StartIndex,
- UserId = query.User.Id.ToString("N")
-
- }, parentFolders, query.DtoOptions);
-
- return result;
- }
-
- private QueryResult<BaseItem> GetTvResume(Folder parent, User user, InternalItemsQuery query)
- {
- query.OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
- query.IsResumable = true;
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
- query.Limit = GetSpecialItemsLimit();
- query.IncludeItemTypes = new[] { typeof(Episode).Name };
-
- return ConvertToResult(_libraryManager.GetItemList(query));
- }
-
- private QueryResult<BaseItem> GetTvSeries(Folder parent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = parent;
- query.SetUser(user);
-
- query.IncludeItemTypes = new[] { typeof(Series).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
- {
- var genres = parent.QueryRecursive(new InternalItemsQuery(user)
- {
- IncludeItemTypes = new[] { typeof(Series).Name },
- Recursive = true,
- EnableTotalRecordCount = false
-
- }).Items
- .SelectMany(i => i.Genres)
- .DistinctNames()
- .Select(i =>
- {
- try
- {
- return _libraryManager.GetGenre(i);
- }
- catch
- {
- // Full exception logged at lower levels
- _logger.Error("Error getting genre");
- return null;
- }
-
- })
- .Where(i => i != null)
- .Select(i => GetUserViewWithName(i.Name, SpecialFolder.TvGenre, i.SortName, parent));
-
- return GetResult(genres, parent, query);
- }
-
- private QueryResult<BaseItem> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
- {
- query.Recursive = true;
- query.Parent = queryParent;
- query.GenreIds = new[] { displayParent.Id.ToString("N") };
- query.SetUser(user);
-
- query.IncludeItemTypes = new[] { typeof(Series).Name };
-
- return _libraryManager.GetItemsResult(query);
- }
-
- private QueryResult<BaseItem> GetResult<T>(QueryResult<T> result)
- where T : BaseItem
- {
- return new QueryResult<BaseItem>
- {
- Items = result.Items,
- TotalRecordCount = result.TotalRecordCount
- };
- }
-
- private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
- BaseItem queryParent,
- InternalItemsQuery query)
- where T : BaseItem
- {
- items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager));
-
- return PostFilterAndSort(items, queryParent, null, query, _libraryManager, _config, true, true);
- }
-
- public static bool FilterItem(BaseItem item, InternalItemsQuery query)
- {
- return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
- }
-
- private QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
- BaseItem queryParent,
- int? totalRecordLimit,
- InternalItemsQuery query,
- bool collapseBoxSetItems,
- bool enableSorting)
- {
- return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _config, collapseBoxSetItems, enableSorting);
- }
-
- public static QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
- BaseItem queryParent,
- int? totalRecordLimit,
- InternalItemsQuery query,
- ILibraryManager libraryManager,
- IServerConfigurationManager configurationManager,
- bool collapseBoxSetItems,
- bool enableSorting)
- {
- var user = query.User;
-
- items = FilterVirtualEpisodes(items,
- query.IsMissing,
- query.IsUnaired);
-
- if (collapseBoxSetItems && user != null)
- {
- items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, user, configurationManager);
- }
-
- // This must be the last filter
- if (!string.IsNullOrEmpty(query.AdjacentTo))
- {
- items = FilterForAdjacency(items.ToList(), query.AdjacentTo);
- }
-
- return SortAndPage(items, totalRecordLimit, query, libraryManager, enableSorting);
- }
-
- public static IEnumerable<BaseItem> CollapseBoxSetItemsIfNeeded(IEnumerable<BaseItem> items,
- InternalItemsQuery query,
- BaseItem queryParent,
- User user,
- IServerConfigurationManager configurationManager)
- {
- if (items == null)
- {
- throw new ArgumentNullException("items");
- }
-
- if (CollapseBoxSetItems(query, queryParent, user, configurationManager))
- {
- items = BaseItem.CollectionManager.CollapseItemsWithinBoxSets(items, user);
- }
-
- items = ApplyPostCollectionCollapseFilters(query, items, user);
-
- return items;
- }
-
- private static IEnumerable<BaseItem> ApplyPostCollectionCollapseFilters(InternalItemsQuery request,
- IEnumerable<BaseItem> items,
- User user)
- {
- if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater))
- {
- items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.SortName, StringComparison.CurrentCultureIgnoreCase) < 1);
- }
- if (!string.IsNullOrEmpty(request.NameStartsWith))
- {
- items = items.Where(i => string.Compare(request.NameStartsWith, i.SortName.Substring(0, 1), StringComparison.CurrentCultureIgnoreCase) == 0);
- }
-
- if (!string.IsNullOrEmpty(request.NameLessThan))
- {
- items = items.Where(i => string.Compare(request.NameLessThan, i.SortName, StringComparison.CurrentCultureIgnoreCase) == 1);
- }
-
- return items;
- }
-
- public static bool CollapseBoxSetItems(InternalItemsQuery query,
- BaseItem queryParent,
- User user,
- IServerConfigurationManager configurationManager)
- {
- // Could end up stuck in a loop like this
- if (queryParent is BoxSet)
- {
- return false;
- }
-
- var param = query.CollapseBoxSetItems;
-
- if (!param.HasValue)
- {
- if (user != null && !configurationManager.Configuration.EnableGroupingIntoCollections)
- {
- return false;
- }
-
- if (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains("Movie", StringComparer.OrdinalIgnoreCase))
- {
- param = true;
- }
- }
-
- return param.HasValue && param.Value && AllowBoxSetCollapsing(query);
- }
-
- private static bool AllowBoxSetCollapsing(InternalItemsQuery request)
- {
- if (request.IsFavorite.HasValue)
- {
- return false;
- }
- if (request.IsFavoriteOrLiked.HasValue)
- {
- return false;
- }
- if (request.IsLiked.HasValue)
- {
- return false;
- }
- if (request.IsPlayed.HasValue)
- {
- return false;
- }
- if (request.IsResumable.HasValue)
- {
- return false;
- }
- if (request.IsFolder.HasValue)
- {
- return false;
- }
-
- if (request.Genres.Length > 0)
- {
- return false;
- }
-
- if (request.GenreIds.Length > 0)
- {
- return false;
- }
-
- if (request.HasImdbId.HasValue)
- {
- return false;
- }
-
- if (request.HasOfficialRating.HasValue)
- {
- return false;
- }
-
- if (request.HasOverview.HasValue)
- {
- return false;
- }
-
- if (request.HasParentalRating.HasValue)
- {
- return false;
- }
-
- if (request.HasSpecialFeature.HasValue)
- {
- return false;
- }
-
- if (request.HasSubtitles.HasValue)
- {
- return false;
- }
-
- if (request.HasThemeSong.HasValue)
- {
- return false;
- }
-
- if (request.HasThemeVideo.HasValue)
- {
- return false;
- }
-
- if (request.HasTmdbId.HasValue)
- {
- return false;
- }
-
- if (request.HasTrailer.HasValue)
- {
- return false;
- }
-
- if (request.ImageTypes.Length > 0)
- {
- return false;
- }
-
- if (request.Is3D.HasValue)
- {
- return false;
- }
-
- if (request.IsHD.HasValue)
- {
- return false;
- }
-
- if (request.IsInBoxSet.HasValue)
- {
- return false;
- }
-
- if (request.IsLocked.HasValue)
- {
- return false;
- }
-
- if (request.IsPlaceHolder.HasValue)
- {
- return false;
- }
-
- if (request.IsPlayed.HasValue)
- {
- return false;
- }
-
- if (!string.IsNullOrWhiteSpace(request.Person))
- {
- return false;
- }
-
- if (request.PersonIds.Length > 0)
- {
- return false;
- }
-
- if (request.ItemIds.Length > 0)
- {
- return false;
- }
-
- if (request.StudioIds.Length > 0)
- {
- return false;
- }
-
- if (request.GenreIds.Length > 0)
- {
- return false;
- }
-
- if (request.VideoTypes.Length > 0)
- {
- return false;
- }
-
- if (request.Years.Length > 0)
- {
- return false;
- }
-
- if (request.Tags.Length > 0)
- {
- return false;
- }
-
- if (request.OfficialRatings.Length > 0)
- {
- return false;
- }
-
- if (request.MinPlayers.HasValue)
- {
- return false;
- }
-
- if (request.MaxPlayers.HasValue)
- {
- return false;
- }
-
- if (request.MinCommunityRating.HasValue)
- {
- return false;
- }
-
- if (request.MinCriticRating.HasValue)
- {
- return false;
- }
-
- if (request.MinIndexNumber.HasValue)
- {
- return false;
- }
-
- return true;
- }
-
- private static IEnumerable<BaseItem> FilterVirtualEpisodes(
- IEnumerable<BaseItem> items,
- bool? isMissing,
- bool? isUnaired)
- {
- if (isMissing.HasValue)
- {
- var val = isMissing.Value;
- items = items.Where(i =>
- {
- var e = i as Episode;
- if (e != null)
- {
- return e.IsMissingEpisode == val;
- }
- return true;
- });
- }
-
- if (isUnaired.HasValue)
- {
- var val = isUnaired.Value;
- items = items.Where(i =>
- {
- var e = i as Episode;
- if (e != null)
- {
- return e.IsUnaired == val;
- }
- return true;
- });
- }
-
- return items;
- }
-
- public static QueryResult<BaseItem> SortAndPage(IEnumerable<BaseItem> items,
- int? totalRecordLimit,
- InternalItemsQuery query,
- ILibraryManager libraryManager, bool enableSorting)
- {
- items = items.DistinctBy(i => i.GetPresentationUniqueKey(), StringComparer.OrdinalIgnoreCase);
-
- if (query.OrderBy.Length > 0)
- {
- items = libraryManager.Sort(items, query.User, query.OrderBy);
- }
-
- var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();
- var totalCount = itemsArray.Length;
-
- if (query.Limit.HasValue)
- {
- itemsArray = itemsArray.Skip(query.StartIndex ?? 0).Take(query.Limit.Value).ToArray();
- }
- else if (query.StartIndex.HasValue)
- {
- itemsArray = itemsArray.Skip(query.StartIndex.Value).ToArray();
- }
-
- return new QueryResult<BaseItem>
- {
- TotalRecordCount = totalCount,
- Items = itemsArray
- };
- }
-
- public static bool Filter(BaseItem item, User user, InternalItemsQuery query, IUserDataManager userDataManager, ILibraryManager libraryManager)
- {
- if (query.ItemIdsFromPersonFilters == null)
- {
- if (query.PersonIds.Length > 0)
- {
- var names = query.PersonIds
- .Select(libraryManager.GetItemById)
- .Select(i => i == null ? null : i.Name)
- .Where(i => !string.IsNullOrWhiteSpace(i))
- .ToList();
-
- var itemIdList = new List<Guid>();
- foreach (var name in names)
- {
- itemIdList.AddRange(libraryManager.GetItemIds(new InternalItemsQuery
- {
- Person = name
- }));
- }
- query.ItemIdsFromPersonFilters = itemIdList;
- }
-
- // Apply person filter
- else if (!string.IsNullOrWhiteSpace(query.Person))
- {
- var itemIdList = new List<Guid>();
-
- itemIdList.AddRange(libraryManager.GetItemIds(new InternalItemsQuery
- {
- Person = query.Person,
- PersonTypes = query.PersonTypes
- }));
- query.ItemIdsFromPersonFilters = itemIdList;
- }
- }
-
- if (query.MediaTypes.Length > 0 && !query.MediaTypes.Contains(item.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
-
- if (query.IncludeItemTypes.Length > 0 && !query.IncludeItemTypes.Contains(item.GetClientTypeName(), StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
-
- if (query.ExcludeItemTypes.Length > 0 && query.ExcludeItemTypes.Contains(item.GetClientTypeName(), StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
-
- if (query.IsVirtualItem.HasValue && item.IsVirtualItem != query.IsVirtualItem.Value)
- {
- return false;
- }
-
- if (query.IsFolder.HasValue && query.IsFolder.Value != item.IsFolder)
- {
- return false;
- }
-
- UserItemData userData = null;
-
- if (query.IsLiked.HasValue)
- {
- userData = userData ?? userDataManager.GetUserData(user, item);
-
- if (!userData.Likes.HasValue || userData.Likes != query.IsLiked.Value)
- {
- return false;
- }
- }
-
- if (query.IsFavoriteOrLiked.HasValue)
- {
- userData = userData ?? userDataManager.GetUserData(user, item);
- var isFavoriteOrLiked = userData.IsFavorite || (userData.Likes ?? false);
-
- if (isFavoriteOrLiked != query.IsFavoriteOrLiked.Value)
- {
- return false;
- }
- }
-
- if (query.IsFavorite.HasValue)
- {
- userData = userData ?? userDataManager.GetUserData(user, item);
-
- if (userData.IsFavorite != query.IsFavorite.Value)
- {
- return false;
- }
- }
-
- if (query.IsResumable.HasValue)
- {
- userData = userData ?? userDataManager.GetUserData(user, item);
- var isResumable = userData.PlaybackPositionTicks > 0;
-
- if (isResumable != query.IsResumable.Value)
- {
- return false;
- }
- }
-
- if (query.IsPlayed.HasValue)
- {
- if (item.IsPlayed(user) != query.IsPlayed.Value)
- {
- return false;
- }
- }
-
- if (query.IsInBoxSet.HasValue)
- {
- var val = query.IsInBoxSet.Value;
- if (item.GetParents().OfType<BoxSet>().Any() != val)
- {
- return false;
- }
- }
-
- // Filter by Video3DFormat
- if (query.Is3D.HasValue)
- {
- var val = query.Is3D.Value;
- var video = item as Video;
-
- if (video == null || val != video.Video3DFormat.HasValue)
- {
- return false;
- }
- }
-
- if (query.IsHD.HasValue)
- {
- var val = query.IsHD.Value;
- var video = item as Video;
-
- if (video == null || !video.IsHD.HasValue || val != video.IsHD)
- {
- return false;
- }
- }
-
- if (query.IsLocked.HasValue)
- {
- var val = query.IsLocked.Value;
- if (item.IsLocked != val)
- {
- return false;
- }
- }
-
- if (query.HasOverview.HasValue)
- {
- var filterValue = query.HasOverview.Value;
-
- var hasValue = !string.IsNullOrEmpty(item.Overview);
-
- if (hasValue != filterValue)
- {
- return false;
- }
- }
-
- if (query.HasImdbId.HasValue)
- {
- var filterValue = query.HasImdbId.Value;
-
- var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Imdb));
-
- if (hasValue != filterValue)
- {
- return false;
- }
- }
-
- if (query.HasTmdbId.HasValue)
- {
- var filterValue = query.HasTmdbId.Value;
-
- var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tmdb));
-
- if (hasValue != filterValue)
- {
- return false;
- }
- }
-
- if (query.HasTvdbId.HasValue)
- {
- var filterValue = query.HasTvdbId.Value;
-
- var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tvdb));
-
- if (hasValue != filterValue)
- {
- return false;
- }
- }
-
- if (query.HasOfficialRating.HasValue)
- {
- var filterValue = query.HasOfficialRating.Value;
-
- var hasValue = !string.IsNullOrEmpty(item.OfficialRating);
-
- if (hasValue != filterValue)
- {
- return false;
- }
- }
-
- if (query.IsPlaceHolder.HasValue)
- {
- var filterValue = query.IsPlaceHolder.Value;
-
- var isPlaceHolder = false;
-
- var hasPlaceHolder = item as ISupportsPlaceHolders;
-
- if (hasPlaceHolder != null)
- {
- isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
- }
-
- if (isPlaceHolder != filterValue)
- {
- return false;
- }
- }
-
- if (query.HasSpecialFeature.HasValue)
- {
- var filterValue = query.HasSpecialFeature.Value;
-
- var movie = item as IHasSpecialFeatures;
-
- if (movie != null)
- {
- var ok = filterValue
- ? movie.SpecialFeatureIds.Length > 0
- : movie.SpecialFeatureIds.Length == 0;
-
- if (!ok)
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
-
- if (query.HasSubtitles.HasValue)
- {
- var val = query.HasSubtitles.Value;
-
- var video = item as Video;
-
- if (video == null || val != video.HasSubtitles)
- {
- return false;
- }
- }
-
- if (query.HasParentalRating.HasValue)
- {
- var val = query.HasParentalRating.Value;
-
- var rating = item.CustomRating;
-
- if (string.IsNullOrEmpty(rating))
- {
- rating = item.OfficialRating;
- }
-
- if (val)
- {
- if (string.IsNullOrEmpty(rating))
- {
- return false;
- }
- }
- else
- {
- if (!string.IsNullOrEmpty(rating))
- {
- return false;
- }
- }
- }
-
- if (query.HasTrailer.HasValue)
- {
- var val = query.HasTrailer.Value;
- var trailerCount = 0;
-
- var hasTrailers = item as IHasTrailers;
- if (hasTrailers != null)
- {
- trailerCount = hasTrailers.GetTrailerIds().Count;
- }
-
- var ok = val ? trailerCount > 0 : trailerCount == 0;
-
- if (!ok)
- {
- return false;
- }
- }
-
- if (query.HasThemeSong.HasValue)
- {
- var filterValue = query.HasThemeSong.Value;
-
- var themeCount = item.ThemeSongIds.Length;
- var ok = filterValue ? themeCount > 0 : themeCount == 0;
-
- if (!ok)
- {
- return false;
- }
- }
-
- if (query.HasThemeVideo.HasValue)
- {
- var filterValue = query.HasThemeVideo.Value;
-
- var themeCount = item.ThemeVideoIds.Length;
- var ok = filterValue ? themeCount > 0 : themeCount == 0;
-
- if (!ok)
- {
- return false;
- }
- }
-
- // Apply genre filter
- if (query.Genres.Length > 0 && !query.Genres.Any(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
- {
- return false;
- }
-
- // Filter by VideoType
- if (query.VideoTypes.Length > 0)
- {
- var video = item as Video;
- if (video == null || !query.VideoTypes.Contains(video.VideoType))
- {
- return false;
- }
- }
-
- if (query.ImageTypes.Length > 0 && !query.ImageTypes.Any(item.HasImage))
- {
- return false;
- }
-
- // Apply studio filter
- if (query.StudioIds.Length > 0 && !query.StudioIds.Any(id =>
- {
- var studioItem = libraryManager.GetItemById(id);
- return studioItem != null && item.Studios.Contains(studioItem.Name, StringComparer.OrdinalIgnoreCase);
- }))
- {
- return false;
- }
-
- // Apply genre filter
- if (query.GenreIds.Length > 0 && !query.GenreIds.Any(id =>
- {
- var genreItem = libraryManager.GetItemById(id);
- return genreItem != null && item.Genres.Contains(genreItem.Name, StringComparer.OrdinalIgnoreCase);
- }))
- {
- return false;
- }
-
- // Apply year filter
- if (query.Years.Length > 0)
- {
- if (!(item.ProductionYear.HasValue && query.Years.Contains(item.ProductionYear.Value)))
- {
- return false;
- }
- }
-
- // Apply official rating filter
- if (query.OfficialRatings.Length > 0 && !query.OfficialRatings.Contains(item.OfficialRating ?? string.Empty))
- {
- return false;
- }
-
- if (query.ItemIds.Length > 0)
- {
- if (!query.ItemIds.Contains(item.Id.ToString("N"), StringComparer.OrdinalIgnoreCase))
- {
- return false;
- }
- }
-
- // Apply person filter
- if (query.ItemIdsFromPersonFilters != null)
- {
- if (!query.ItemIdsFromPersonFilters.Contains(item.Id))
- {
- return false;
- }
- }
-
- // Apply tag filter
- var tags = query.Tags;
- if (tags.Length > 0)
- {
- if (!tags.Any(v => item.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
- {
- return false;
- }
- }
-
- if (query.MinPlayers.HasValue)
- {
- var filterValue = query.MinPlayers.Value;
-
- var game = item as Game;
-
- if (game != null)
- {
- var players = game.PlayersSupported ?? 1;
-
- var ok = players >= filterValue;
-
- if (!ok)
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
-
- if (query.MaxPlayers.HasValue)
- {
- var filterValue = query.MaxPlayers.Value;
-
- var game = item as Game;
-
- if (game != null)
- {
- var players = game.PlayersSupported ?? 1;
-
- var ok = players <= filterValue;
-
- if (!ok)
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
-
- if (query.MinCommunityRating.HasValue)
- {
- var val = query.MinCommunityRating.Value;
-
- if (!(item.CommunityRating.HasValue && item.CommunityRating >= val))
- {
- return false;
- }
- }
-
- if (query.MinCriticRating.HasValue)
- {
- var val = query.MinCriticRating.Value;
-
- if (!(item.CriticRating.HasValue && item.CriticRating >= val))
- {
- return false;
- }
- }
-
- if (query.MinIndexNumber.HasValue)
- {
- var val = query.MinIndexNumber.Value;
-
- if (!(item.IndexNumber.HasValue && item.IndexNumber.Value >= val))
- {
- return false;
- }
- }
-
- if (query.MinPremiereDate.HasValue)
- {
- var val = query.MinPremiereDate.Value;
-
- if (!(item.PremiereDate.HasValue && item.PremiereDate.Value >= val))
- {
- return false;
- }
- }
-
- if (query.MaxPremiereDate.HasValue)
- {
- var val = query.MaxPremiereDate.Value;
-
- if (!(item.PremiereDate.HasValue && item.PremiereDate.Value <= val))
- {
- return false;
- }
- }
-
- if (query.ParentIndexNumber.HasValue)
- {
- var filterValue = query.ParentIndexNumber.Value;
-
- if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value != filterValue)
- {
- return false;
- }
- }
-
- if (query.SeriesStatuses.Length > 0)
- {
- var ok = new[] { item }.OfType<Series>().Any(p => p.Status.HasValue && query.SeriesStatuses.Contains(p.Status.Value));
- if (!ok)
- {
- return false;
- }
- }
-
- if (query.AiredDuringSeason.HasValue)
- {
- var episode = item as Episode;
-
- if (episode == null)
- {
- return false;
- }
-
- if (!Series.FilterEpisodesBySeason(new[] { episode }, query.AiredDuringSeason.Value, true).Any())
- {
- return false;
- }
- }
-
- return true;
- }
-
- private IEnumerable<BaseItem> GetMediaFolders(User user)
- {
- if (user == null)
- {
- return _libraryManager.RootFolder
- .Children
- .OfType<Folder>()
- .Where(UserView.IsEligibleForGrouping);
- }
- return user.RootFolder
- .GetChildren(user, true)
- .OfType<Folder>()
- .Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i));
- }
-
- private List<BaseItem> GetMediaFolders(User user, IEnumerable<string> viewTypes)
- {
- if (user == null)
- {
- return GetMediaFolders(null)
- .Where(i =>
- {
- var folder = i as ICollectionFolder;
-
- return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
- }).ToList();
- }
- return GetMediaFolders(user)
- .Where(i =>
- {
- var folder = i as ICollectionFolder;
-
- return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
- }).ToList();
- }
-
- private List<BaseItem> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes)
- {
- if (parent == null || parent is UserView)
- {
- return GetMediaFolders(user, viewTypes);
- }
-
- return new List<BaseItem> { parent };
- }
-
- private async Task<QueryResult<BaseItem>> GetLiveTvView(Folder queryParent, User user, InternalItemsQuery query)
- {
- if (query.Recursive)
- {
- return await _liveTvManager.GetInternalRecordings(new RecordingQuery
- {
- IsInProgress = false,
- Status = RecordingStatus.Completed,
- UserId = user.Id.ToString("N")
-
- }, new DtoOptions(), CancellationToken.None).ConfigureAwait(false);
- }
-
- var list = new List<BaseItem>();
-
- //list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false));
- list.Add(GetUserView(SpecialFolder.LiveTvChannels, "Channels", string.Empty, user.RootFolder));
- list.Add(GetUserView(SpecialFolder.LiveTvRecordingGroups, "HeaderRecordingGroups", string.Empty, user.RootFolder));
-
- return GetResult(list, queryParent, query);
- }
-
- private UserView GetUserViewWithName(string name, string type, string sortName, BaseItem parent)
- {
- return _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, sortName, CancellationToken.None);
- }
-
- private UserView GetUserView(string type, string localizationKey, string sortName, BaseItem parent)
- {
- return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, localizationKey, sortName, CancellationToken.None);
- }
-
- public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, string adjacentToId)
- {
- var adjacentToIdGuid = new Guid(adjacentToId);
- var adjacentToItem = list.FirstOrDefault(i => i.Id == adjacentToIdGuid);
-
- var index = list.IndexOf(adjacentToItem);
-
- var previousId = Guid.Empty;
- var nextId = Guid.Empty;
-
- if (index > 0)
- {
- previousId = list[index - 1].Id;
- }
-
- if (index < list.Count - 1)
- {
- nextId = list[index + 1].Id;
- }
-
- return list.Where(i => i.Id == previousId || i.Id == nextId || i.Id == adjacentToIdGuid);
- }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
deleted file mode 100644
index dca1cfd01b..0000000000
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ /dev/null
@@ -1,806 +0,0 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.MediaInfo;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Extensions;
-
-using MediaBrowser.Controller.Channels;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Extensions;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Video
- /// </summary>
- public class Video : BaseItem,
- IHasAspectRatio,
- ISupportsPlaceHolders,
- IHasMediaSources
- {
- [IgnoreDataMember]
- public string PrimaryVersionId { get; set; }
-
- public string[] AdditionalParts { get; set; }
- public string[] LocalAlternateVersions { get; set; }
- public LinkedChild[] LinkedAlternateVersions { get; set; }
-
- [IgnoreDataMember]
- public override bool SupportsPlayedStatus
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public override bool SupportsInheritedParentImages
- {
- get
- {
- return true;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsPositionTicksResume
- {
- get
- {
- var extraType = ExtraType;
- if (extraType.HasValue)
- {
- if (extraType.Value == Model.Entities.ExtraType.Sample)
- {
- return false;
- }
- if (extraType.Value == Model.Entities.ExtraType.ThemeVideo)
- {
- return false;
- }
- if (extraType.Value == Model.Entities.ExtraType.Trailer)
- {
- return false;
- }
- }
- return true;
- }
- }
-
- public void SetPrimaryVersionId(string id)
- {
- if (string.IsNullOrWhiteSpace(id))
- {
- PrimaryVersionId = null;
- }
- else
- {
- PrimaryVersionId = id;
- }
-
- PresentationUniqueKey = CreatePresentationUniqueKey();
- }
-
- public override string CreatePresentationUniqueKey()
- {
- if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
- {
- return PrimaryVersionId;
- }
-
- return base.CreatePresentationUniqueKey();
- }
-
- [IgnoreDataMember]
- public override bool EnableRefreshOnDateModifiedChange
- {
- get
- {
- return VideoType == VideoType.VideoFile || VideoType == VideoType.Iso;
- }
- }
-
- [IgnoreDataMember]
- public override bool SupportsThemeMedia
- {
- get { return true; }
- }
-
- /// <summary>
- /// Gets or sets the timestamp.
- /// </summary>
- /// <value>The timestamp.</value>
- public TransportStreamTimestamp? Timestamp { get; set; }
-
- /// <summary>
- /// Gets or sets the subtitle paths.
- /// </summary>
- /// <value>The subtitle paths.</value>
- public string[] SubtitleFiles { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether this instance has subtitles.
- /// </summary>
- /// <value><c>true</c> if this instance has subtitles; otherwise, <c>false</c>.</value>
- public bool HasSubtitles { get; set; }
-
- public bool IsPlaceHolder { get; set; }
- public bool IsShortcut { get; set; }
- public string ShortcutPath { get; set; }
-
- /// <summary>
- /// Gets or sets the default index of the video stream.
- /// </summary>
- /// <value>The default index of the video stream.</value>
- public int? DefaultVideoStreamIndex { get; set; }
-
- /// <summary>
- /// Gets or sets the type of the video.
- /// </summary>
- /// <value>The type of the video.</value>
- public VideoType VideoType { get; set; }
-
- /// <summary>
- /// Gets or sets the type of the iso.
- /// </summary>
- /// <value>The type of the iso.</value>
- public IsoType? IsoType { get; set; }
-
- /// <summary>
- /// Gets or sets the video3 D format.
- /// </summary>
- /// <value>The video3 D format.</value>
- public Video3DFormat? Video3DFormat { get; set; }
-
- public string[] GetPlayableStreamFileNames()
- {
- var videoType = VideoType;
-
- if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.BluRay)
- {
- videoType = VideoType.BluRay;
- }
- else if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.Dvd)
- {
- videoType = VideoType.Dvd;
- }
- else
- {
- return new string[] { };
- }
- return MediaEncoder.GetPlayableStreamFileNames(Path, videoType);
- }
-
- /// <summary>
- /// Gets or sets the aspect ratio.
- /// </summary>
- /// <value>The aspect ratio.</value>
- public string AspectRatio { get; set; }
-
- public Video()
- {
- AdditionalParts = EmptyStringArray;
- LocalAlternateVersions = EmptyStringArray;
- SubtitleFiles = EmptyStringArray;
- LinkedAlternateVersions = EmptyLinkedChildArray;
- }
-
- public override bool CanDownload()
- {
- if (VideoType == VideoType.Dvd || VideoType == VideoType.BluRay)
- {
- return false;
- }
-
- var locationType = LocationType;
- return locationType != LocationType.Remote &&
- locationType != LocationType.Virtual;
- }
-
- [IgnoreDataMember]
- public override bool SupportsAddingToPlaylist
- {
- get { return true; }
- }
-
- [IgnoreDataMember]
- public int MediaSourceCount
- {
- get
- {
- if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
- {
- var item = LibraryManager.GetItemById(PrimaryVersionId) as Video;
- if (item != null)
- {
- return item.MediaSourceCount;
- }
- }
- return LinkedAlternateVersions.Length + LocalAlternateVersions.Length + 1;
- }
- }
-
- [IgnoreDataMember]
- public bool IsStacked
- {
- get { return AdditionalParts.Length > 0; }
- }
-
- [IgnoreDataMember]
- public bool HasLocalAlternateVersions
- {
- get { return LocalAlternateVersions.Length > 0; }
- }
-
- public IEnumerable<Guid> GetAdditionalPartIds()
- {
- return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
- }
-
- public IEnumerable<Guid> GetLocalAlternateVersionIds()
- {
- return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
- }
-
- [IgnoreDataMember]
- public override SourceType SourceType
- {
- get
- {
- if (IsActiveRecording())
- {
- return SourceType.LiveTV;
- }
-
- return base.SourceType;
- }
- }
-
- protected bool IsActiveRecording()
- {
- return LiveTvManager.GetActiveRecordingInfo(Path) != null;
- }
-
- public override bool CanDelete()
- {
- if (IsActiveRecording())
- {
- return false;
- }
-
- return base.CanDelete();
- }
-
- [IgnoreDataMember]
- public bool IsCompleteMedia
- {
- get { return !IsActiveRecording(); }
- }
-
- [IgnoreDataMember]
- protected virtual bool EnableDefaultVideoUserDataKeys
- {
- get
- {
- return true;
- }
- }
-
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- if (EnableDefaultVideoUserDataKeys)
- {
- if (ExtraType.HasValue)
- {
- var key = this.GetProviderId(MetadataProviders.Tmdb);
- if (!string.IsNullOrWhiteSpace(key))
- {
- list.Insert(0, GetUserDataKey(key));
- }
-
- key = this.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrWhiteSpace(key))
- {
- list.Insert(0, GetUserDataKey(key));
- }
- }
- else
- {
- var key = this.GetProviderId(MetadataProviders.Imdb);
- if (!string.IsNullOrWhiteSpace(key))
- {
- list.Insert(0, key);
- }
-
- key = this.GetProviderId(MetadataProviders.Tmdb);
- if (!string.IsNullOrWhiteSpace(key))
- {
- list.Insert(0, key);
- }
- }
- }
-
- return list;
- }
-
- private string GetUserDataKey(string providerId)
- {
- var key = providerId + "-" + ExtraType.ToString().ToLower();
-
- // Make sure different trailers have their own data.
- if (RunTimeTicks.HasValue)
- {
- key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
- }
-
- return key;
- }
-
- public IEnumerable<Video> GetLinkedAlternateVersions()
- {
- return LinkedAlternateVersions
- .Select(GetLinkedChild)
- .Where(i => i != null)
- .OfType<Video>()
- .OrderBy(i => i.SortName);
- }
-
- /// <summary>
- /// Gets the additional parts.
- /// </summary>
- /// <returns>IEnumerable{Video}.</returns>
- public IEnumerable<Video> GetAdditionalParts()
- {
- return GetAdditionalPartIds()
- .Select(i => LibraryManager.GetItemById(i))
- .Where(i => i != null)
- .OfType<Video>()
- .OrderBy(i => i.SortName);
- }
-
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- if (IsStacked)
- {
- return FileSystem.GetDirectoryName(Path);
- }
-
- if (!IsPlaceHolder)
- {
- if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd)
- {
- return Path;
- }
- }
-
- return base.ContainingFolderPath;
- }
- }
-
- [IgnoreDataMember]
- public override string FileNameWithoutExtension
- {
- get
- {
- if (LocationType == LocationType.FileSystem)
- {
- if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd)
- {
- return System.IO.Path.GetFileName(Path);
- }
-
- return System.IO.Path.GetFileNameWithoutExtension(Path);
- }
-
- return null;
- }
- }
-
- internal override ItemUpdateType UpdateFromResolvedItem(BaseItem newItem)
- {
- var updateType = base.UpdateFromResolvedItem(newItem);
-
- var newVideo = newItem as Video;
- if (newVideo != null)
- {
- if (!AdditionalParts.SequenceEqual(newVideo.AdditionalParts, StringComparer.Ordinal))
- {
- AdditionalParts = newVideo.AdditionalParts;
- updateType |= ItemUpdateType.MetadataImport;
- }
- if (!LocalAlternateVersions.SequenceEqual(newVideo.LocalAlternateVersions, StringComparer.Ordinal))
- {
- LocalAlternateVersions = newVideo.LocalAlternateVersions;
- updateType |= ItemUpdateType.MetadataImport;
- }
- if (VideoType != newVideo.VideoType)
- {
- VideoType = newVideo.VideoType;
- updateType |= ItemUpdateType.MetadataImport;
- }
- }
-
- return updateType;
- }
-
- public static string[] QueryPlayableStreamFiles(string rootPath, VideoType videoType)
- {
- if (videoType == VideoType.Dvd)
- {
- return FileSystem.GetFiles(rootPath, new[] { ".vob" }, false, true)
- .OrderByDescending(i => i.Length)
- .ThenBy(i => i.FullName)
- .Take(1)
- .Select(i => i.FullName)
- .ToArray();
- }
- if (videoType == VideoType.BluRay)
- {
- return FileSystem.GetFiles(rootPath, new[] { ".m2ts" }, false, true)
- .OrderByDescending(i => i.Length)
- .ThenBy(i => i.FullName)
- .Take(1)
- .Select(i => i.FullName)
- .ToArray();
- }
- return new string[] { };
- }
-
- /// <summary>
- /// Gets a value indicating whether [is3 D].
- /// </summary>
- /// <value><c>true</c> if [is3 D]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public bool Is3D
- {
- get { return Video3DFormat.HasValue; }
- }
-
- /// <summary>
- /// Gets the type of the media.
- /// </summary>
- /// <value>The type of the media.</value>
- [IgnoreDataMember]
- public override string MediaType
- {
- get
- {
- return Model.Entities.MediaType.Video;
- }
- }
-
- protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
- {
- var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
-
- if (IsStacked)
- {
- var tasks = AdditionalParts
- .Select(i => RefreshMetadataForOwnedVideo(options, true, i, cancellationToken));
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
- }
-
- // Must have a parent to have additional parts or alternate versions
- // In other words, it must be part of the Parent/Child tree
- // The additional parts won't have additional parts themselves
- if (LocationType == LocationType.FileSystem && GetParent() != null)
- {
- if (!IsStacked)
- {
- RefreshLinkedAlternateVersions();
-
- var tasks = LocalAlternateVersions
- .Select(i => RefreshMetadataForOwnedVideo(options, false, i, cancellationToken));
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
- }
- }
-
- return hasChanges;
- }
-
- private void RefreshLinkedAlternateVersions()
- {
- foreach (var child in LinkedAlternateVersions)
- {
- // Reset the cached value
- if (child.ItemId.HasValue && child.ItemId.Value == Guid.Empty)
- {
- child.ItemId = null;
- }
- }
- }
-
- public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
- {
- base.UpdateToRepository(updateReason, cancellationToken);
-
- var localAlternates = GetLocalAlternateVersionIds()
- .Select(i => LibraryManager.GetItemById(i))
- .Where(i => i != null);
-
- foreach (var item in localAlternates)
- {
- item.ImageInfos = ImageInfos;
- item.Overview = Overview;
- item.ProductionYear = ProductionYear;
- item.PremiereDate = PremiereDate;
- item.CommunityRating = CommunityRating;
- item.OfficialRating = OfficialRating;
- item.Genres = Genres;
- item.ProviderIds = ProviderIds;
-
- item.UpdateToRepository(ItemUpdateType.MetadataDownload, cancellationToken);
- }
- }
-
- public override IEnumerable<FileSystemMetadata> GetDeletePaths()
- {
- if (!IsInMixedFolder)
- {
- return new[] {
- new FileSystemMetadata
- {
- FullName = ContainingFolderPath,
- IsDirectory = true
- }
- };
- }
-
- return base.GetDeletePaths();
- }
-
- public List<MediaStream> GetMediaStreams()
- {
- return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
- {
- ItemId = Id
- });
- }
-
- public virtual MediaStream GetDefaultVideoStream()
- {
- if (!DefaultVideoStreamIndex.HasValue)
- {
- return null;
- }
-
- return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
- {
- ItemId = Id,
- Index = DefaultVideoStreamIndex.Value
-
- }).FirstOrDefault();
- }
-
- private List<Tuple<Video, MediaSourceType>> GetAllVideosForMediaSources()
- {
- var list = new List<Tuple<Video, MediaSourceType>>();
-
- list.Add(new Tuple<Video, MediaSourceType>(this, MediaSourceType.Default));
- list.AddRange(GetLinkedAlternateVersions().Select(i => new Tuple<Video, MediaSourceType>(i, MediaSourceType.Grouping)));
-
- if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
- {
- var primary = LibraryManager.GetItemById(PrimaryVersionId) as Video;
- if (primary != null)
- {
- var existingIds = list.Select(i => i.Item1.Id).ToList();
- list.Add(new Tuple<Video, MediaSourceType>(primary, MediaSourceType.Grouping));
- list.AddRange(primary.GetLinkedAlternateVersions().Where(i => !existingIds.Contains(i.Id)).Select(i => new Tuple<Video, MediaSourceType>(i, MediaSourceType.Grouping)));
- }
- }
-
- var localAlternates = list
- .SelectMany(i => i.Item1.GetLocalAlternateVersionIds())
- .Select(LibraryManager.GetItemById)
- .Where(i => i != null)
- .OfType<Video>()
- .ToList();
-
- list.AddRange(localAlternates.Select(i => new Tuple<Video, MediaSourceType>(i, MediaSourceType.Default)));
-
- return list;
- }
-
- public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
- {
- if (SourceType == SourceType.Channel)
- {
- var sources = ChannelManager.GetStaticMediaSources(this, CancellationToken.None)
- .ToList();
-
- if (sources.Count > 0)
- {
- return sources;
- }
-
- return new List<MediaSourceInfo>
- {
- GetVersionInfo(enablePathSubstitution, this, MediaSourceType.Placeholder)
- };
- }
-
- var list = GetAllVideosForMediaSources();
- var result = list.Select(i => GetVersionInfo(enablePathSubstitution, i.Item1, i.Item2)).ToList();
-
- if (IsActiveRecording())
- {
- foreach (var mediaSource in result)
- {
- mediaSource.Type = MediaSourceType.Placeholder;
- }
- }
-
- return result.OrderBy(i =>
- {
- if (i.VideoType == VideoType.VideoFile)
- {
- return 0;
- }
-
- return 1;
-
- }).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
- .ThenByDescending(i =>
- {
- var stream = i.VideoStream;
-
- return stream == null || stream.Width == null ? 0 : stream.Width.Value;
- })
- .ToList();
- }
-
- private static MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, Video media, MediaSourceType type)
- {
- if (media == null)
- {
- throw new ArgumentNullException("media");
- }
-
- var locationType = media.LocationType;
-
- var info = new MediaSourceInfo
- {
- Id = media.Id.ToString("N"),
- IsoType = media.IsoType,
- Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File,
- MediaStreams = MediaSourceManager.GetMediaStreams(media.Id),
- Name = GetMediaSourceName(media),
- Path = enablePathSubstitution ? GetMappedPath(media, media.Path, locationType) : media.Path,
- RunTimeTicks = media.RunTimeTicks,
- Video3DFormat = media.Video3DFormat,
- VideoType = media.VideoType,
- Container = media.Container,
- Size = media.Size,
- Timestamp = media.Timestamp,
- Type = type,
- SupportsDirectStream = media.VideoType == VideoType.VideoFile,
- IsRemote = media.IsShortcut
- };
-
- if (info.Protocol == MediaProtocol.File)
- {
- info.ETag = media.DateModified.Ticks.ToString(CultureInfo.InvariantCulture).GetMD5().ToString("N");
- }
-
- if (media.IsShortcut)
- {
- info.Path = media.ShortcutPath;
-
- if (!string.IsNullOrWhiteSpace(info.Path))
- {
- if (info.Path.StartsWith("Http", StringComparison.OrdinalIgnoreCase))
- {
- info.Protocol = MediaProtocol.Http;
- info.SupportsDirectStream = false;
- }
- else if (info.Path.StartsWith("Rtmp", StringComparison.OrdinalIgnoreCase))
- {
- info.Protocol = MediaProtocol.Rtmp;
- info.SupportsDirectStream = false;
- }
- else if (info.Path.StartsWith("Rtsp", StringComparison.OrdinalIgnoreCase))
- {
- info.Protocol = MediaProtocol.Rtsp;
- info.SupportsDirectStream = false;
- }
- else
- {
- info.Protocol = MediaProtocol.File;
- }
- }
- }
-
- if (string.IsNullOrEmpty(info.Container))
- {
- if (media.VideoType == VideoType.VideoFile || media.VideoType == VideoType.Iso)
- {
- if (!string.IsNullOrWhiteSpace(media.Path) && locationType != LocationType.Remote && locationType != LocationType.Virtual)
- {
- info.Container = System.IO.Path.GetExtension(media.Path).TrimStart('.');
- }
- }
- }
-
- info.Bitrate = media.TotalBitrate;
- info.InferTotalBitrate();
-
- return info;
- }
-
- private static string GetMediaSourceName(Video video)
- {
- var terms = new List<string>();
-
- var locationType = video.LocationType;
- var path = video.Path;
- if ((locationType == LocationType.FileSystem || locationType == LocationType.Offline) && !string.IsNullOrWhiteSpace(path))
- {
- terms.Add(System.IO.Path.GetFileName(path));
- }
- else
- {
- terms.Add(video.Name);
- }
-
- if (video.Video3DFormat.HasValue)
- {
- terms.Add("3D");
- }
-
- if (video.VideoType == VideoType.BluRay)
- {
- terms.Add("Bluray");
- }
- else if (video.VideoType == VideoType.Dvd)
- {
- terms.Add("DVD");
- }
- else if (video.VideoType == VideoType.Iso)
- {
- if (video.IsoType.HasValue)
- {
- if (video.IsoType.Value == Model.Entities.IsoType.BluRay)
- {
- terms.Add("Bluray");
- }
- else if (video.IsoType.Value == Model.Entities.IsoType.Dvd)
- {
- terms.Add("DVD");
- }
- }
- else
- {
- terms.Add("ISO");
- }
- }
-
- return string.Join("/", terms.ToArray(terms.Count));
- }
-
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs
deleted file mode 100644
index 49b967104e..0000000000
--- a/MediaBrowser.Controller/Entities/Year.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using MediaBrowser.Model.Serialization;
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Class Year
- /// </summary>
- public class Year : BaseItem, IItemByName
- {
- public override List<string> GetUserDataKeys()
- {
- var list = base.GetUserDataKeys();
-
- list.Insert(0, "Year-" + Name);
- return list;
- }
-
- /// <summary>
- /// Returns the folder containing the item.
- /// If the item is a folder, it returns the folder itself
- /// </summary>
- /// <value>The containing folder path.</value>
- [IgnoreDataMember]
- public override string ContainingFolderPath
- {
- get
- {
- return Path;
- }
- }
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 2;
- value /= 3;
-
- return value;
- }
-
- [IgnoreDataMember]
- public override bool SupportsAncestors
- {
- get
- {
- return false;
- }
- }
-
- public override bool CanDelete()
- {
- return false;
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance is owned item.
- /// </summary>
- /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IsOwnedItem
- {
- get
- {
- return false;
- }
- }
-
- public override bool IsSaveLocalMetadataEnabled()
- {
- return true;
- }
-
- public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
- {
- int year;
-
- var usCulture = new CultureInfo("en-US");
-
- if (!int.TryParse(Name, NumberStyles.Integer, usCulture, out year))
- {
- return new List<BaseItem>();
- }
-
- query.Years = new[] { year };
-
- return LibraryManager.GetItemList(query);
- }
-
- public int? GetYearValue()
- {
- int i;
-
- if (int.TryParse(Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out i))
- {
- return i;
- }
-
- return null;
- }
-
- [IgnoreDataMember]
- public override bool SupportsPeople
- {
- get
- {
- return false;
- }
- }
-
- public static string GetPath(string name)
- {
- return GetPath(name, true);
- }
-
- public static string GetPath(string name, bool normalizeName)
- {
- // Trim the period at the end because windows will have a hard time with that
- var validName = normalizeName ?
- FileSystem.GetValidFilename(name).Trim().TrimEnd('.') :
- name;
-
- return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.YearPath, validName);
- }
-
- private string GetRebasedPath()
- {
- return GetPath(System.IO.Path.GetFileName(Path), false);
- }
-
- public override bool RequiresRefresh()
- {
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Logger.Debug("{0} path has changed from {1} to {2}", GetType().Name, Path, newPath);
- return true;
- }
- return base.RequiresRefresh();
- }
-
- /// <summary>
- /// This is called before any metadata refresh and returns true or false indicating if changes were made
- /// </summary>
- public override bool BeforeMetadataRefresh()
- {
- var hasChanges = base.BeforeMetadataRefresh();
-
- var newPath = GetRebasedPath();
- if (!string.Equals(Path, newPath, StringComparison.Ordinal))
- {
- Path = newPath;
- hasChanges = true;
- }
-
- return hasChanges;
- }
- }
-}