aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2015-10-26 18:50:19 -0400
committerLuke <luke.pulverenti@gmail.com>2015-10-26 18:50:19 -0400
commit35778ebc02e5931142a1fe31a256b7488a07c5c2 (patch)
treeced0290be8820f5e507b51ca4c5165212b1879d1 /MediaBrowser.Controller/Entities
parentc0dc8d055bfd4d2f58591083beb9e9128357aad6 (diff)
parent8d77308593c3b16b733b0109323770d9dfe7e166 (diff)
Merge pull request #1222 from MediaBrowser/dev
3.0.5768.7
Diffstat (limited to 'MediaBrowser.Controller/Entities')
-rw-r--r--MediaBrowser.Controller/Entities/AggregateFolder.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs21
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs242
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs10
-rw-r--r--MediaBrowser.Controller/Entities/CollectionFolder.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs98
-rw-r--r--MediaBrowser.Controller/Entities/Game.cs10
-rw-r--r--MediaBrowser.Controller/Entities/IHasImages.cs38
-rw-r--r--MediaBrowser.Controller/Entities/IHasMetadata.cs21
-rw-r--r--MediaBrowser.Controller/Entities/IHasPreferredMetadataLanguage.cs21
-rw-r--r--MediaBrowser.Controller/Entities/IHasProgramAttributes.cs2
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs7
-rw-r--r--MediaBrowser.Controller/Entities/ItemImageInfo.cs17
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs6
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs11
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs6
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs1
-rw-r--r--MediaBrowser.Controller/Entities/Trailer.cs3
-rw-r--r--MediaBrowser.Controller/Entities/User.cs11
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs30
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs67
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs29
22 files changed, 386 insertions, 281 deletions
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
index 66a0d551b2..14f8c1617a 100644
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs
@@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
+using CommonIO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Providers;
namespace MediaBrowser.Controller.Entities
@@ -62,7 +64,7 @@ namespace MediaBrowser.Controller.Entities
public List<string> PhysicalLocationsList { get; set; }
- protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
+ protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{
return CreateResolveArgs(directoryService).FileSystemChildren;
}
@@ -73,7 +75,7 @@ namespace MediaBrowser.Controller.Entities
var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths , directoryService)
{
- FileInfo = new DirectoryInfo(path),
+ FileInfo = FileSystem.GetDirectoryInfo(path),
Path = path,
Parent = Parent
};
@@ -94,7 +96,7 @@ namespace MediaBrowser.Controller.Entities
{
var paths = LibraryManager.NormalizeRootPathList(fileSystemDictionary.Keys);
- fileSystemDictionary = paths.Select(i => (FileSystemInfo)new DirectoryInfo(i)).ToDictionary(i => i.FullName);
+ fileSystemDictionary = paths.Select(FileSystem.GetDirectoryInfo).ToDictionary(i => i.FullName);
}
args.FileSystemDictionary = fileSystemDictionary;
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 623329ca66..43b980c20d 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -24,14 +24,20 @@ namespace MediaBrowser.Controller.Entities.Audio
IThemeMedia,
IArchivable
{
- public string FormatName { get; set; }
public long? Size { get; set; }
public string Container { get; set; }
public int? TotalBitrate { get; set; }
public List<string> Tags { get; set; }
- public ExtraType ExtraType { get; set; }
+ public ExtraType? ExtraType { get; set; }
- public bool IsThemeMedia { get; set; }
+ [IgnoreDataMember]
+ public bool IsThemeMedia
+ {
+ get
+ {
+ return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeSong;
+ }
+ }
public Audio()
{
@@ -46,12 +52,6 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; }
}
- /// <summary>
- /// Gets or sets a value indicating whether this instance has embedded image.
- /// </summary>
- /// <value><c>true</c> if this instance has embedded image; otherwise, <c>false</c>.</value>
- public bool HasEmbeddedImage { get; set; }
-
[IgnoreDataMember]
protected override bool SupportsOwnedItems
{
@@ -212,8 +212,7 @@ namespace MediaBrowser.Controller.Entities.Audio
Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path,
RunTimeTicks = i.RunTimeTicks,
Container = i.Container,
- Size = i.Size,
- Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList()
+ Size = i.Size
};
if (string.IsNullOrEmpty(info.Container))
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 594b5ca93c..ec688bd9f4 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -23,6 +23,7 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
namespace MediaBrowser.Controller.Entities
{
@@ -38,7 +39,6 @@ namespace MediaBrowser.Controller.Entities
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LockedFields = new List<MetadataFields>();
ImageInfos = new List<ItemImageInfo>();
- Identities = new List<IItemIdentity>();
}
/// <summary>
@@ -56,12 +56,16 @@ namespace MediaBrowser.Controller.Entities
public static string ThemeSongFilename = "theme";
public static string ThemeVideosFolderName = "backdrops";
+ public string PreferredMetadataCountryCode { get; set; }
+ public string PreferredMetadataLanguage { get; set; }
+
public List<ItemImageInfo> ImageInfos { get; set; }
/// <summary>
/// Gets or sets the channel identifier.
/// </summary>
/// <value>The channel identifier.</value>
+ [IgnoreDataMember]
public string ChannelId { get; set; }
[IgnoreDataMember]
@@ -121,6 +125,12 @@ namespace MediaBrowser.Controller.Entities
public Guid Id { 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>
+ public bool? IsHD { 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>
@@ -162,6 +172,26 @@ namespace MediaBrowser.Controller.Entities
}
}
+ /// <summary>
+ /// Id of the program.
+ /// </summary>
+ [IgnoreDataMember]
+ public string ExternalId
+ {
+ get { return this.GetProviderId("ProviderExternalId"); }
+ set
+ {
+ this.SetProviderId("ProviderExternalId", value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the etag.
+ /// </summary>
+ /// <value>The etag.</value>
+ [IgnoreDataMember]
+ public string ExternalEtag { get; set; }
+
[IgnoreDataMember]
public virtual bool IsHidden
{
@@ -183,7 +213,7 @@ namespace MediaBrowser.Controller.Entities
{
// Local trailer, special feature, theme video, etc.
// An item that belongs to another item but is not part of the Parent-Child tree
- return !IsFolder && Parent == null && LocationType == LocationType.FileSystem;
+ return !IsFolder && ParentId == Guid.Empty && LocationType == LocationType.FileSystem;
}
}
@@ -305,6 +335,9 @@ namespace MediaBrowser.Controller.Entities
public DateTime DateLastSaved { get; set; }
+ [IgnoreDataMember]
+ public DateTime DateLastRefreshed { get; set; }
+
/// <summary>
/// The logger
/// </summary>
@@ -331,30 +364,8 @@ namespace MediaBrowser.Controller.Entities
return Name;
}
- /// <summary>
- /// Returns true if this item should not attempt to fetch metadata
- /// </summary>
- /// <value><c>true</c> if [dont fetch meta]; otherwise, <c>false</c>.</value>
- [Obsolete("Please use IsLocked instead of DontFetchMeta")]
- public bool DontFetchMeta { get; set; }
-
- [IgnoreDataMember]
- public bool IsLocked
- {
- get
- {
- return DontFetchMeta;
- }
- set
- {
- DontFetchMeta = value;
- }
- }
-
- public bool IsUnidentified { get; set; }
-
[IgnoreDataMember]
- public List<IItemIdentity> Identities { get; set; }
+ public bool IsLocked { get; set; }
/// <summary>
/// Gets or sets the locked fields.
@@ -484,7 +495,6 @@ namespace MediaBrowser.Controller.Entities
public Guid ParentId { get; set; }
- private Folder _parent;
/// <summary>
/// Gets or sets the parent.
/// </summary>
@@ -494,11 +504,6 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (_parent != null)
- {
- return _parent;
- }
-
if (ParentId != Guid.Empty)
{
return LibraryManager.GetItemById(ParentId) as Folder;
@@ -506,12 +511,14 @@ namespace MediaBrowser.Controller.Entities
return null;
}
- set { _parent = value; }
+ set
+ {
+
+ }
}
public void SetParent(Folder parent)
{
- Parent = parent;
ParentId = parent == null ? Guid.Empty : parent.Id;
}
@@ -558,6 +565,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the end date.
/// </summary>
/// <value>The end date.</value>
+ [IgnoreDataMember]
public DateTime? EndDate { get; set; }
/// <summary>
@@ -582,6 +590,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the custom rating.
/// </summary>
/// <value>The custom rating.</value>
+ //[IgnoreDataMember]
public string CustomRating { get; set; }
/// <summary>
@@ -591,12 +600,6 @@ namespace MediaBrowser.Controller.Entities
public string Overview { get; set; }
/// <summary>
- /// Gets or sets the people.
- /// </summary>
- /// <value>The people.</value>
- public List<PersonInfo> People { get; set; }
-
- /// <summary>
/// Gets or sets the studios.
/// </summary>
/// <value>The studios.</value>
@@ -618,6 +621,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets or sets the community rating.
/// </summary>
/// <value>The community rating.</value>
+ //[IgnoreDataMember]
public float? CommunityRating { get; set; }
/// <summary>
@@ -643,6 +647,7 @@ namespace MediaBrowser.Controller.Entities
/// This could be episode number, album track number, etc.
/// </summary>
/// <value>The index number.</value>
+ //[IgnoreDataMember]
public int? IndexNumber { get; set; }
/// <summary>
@@ -662,7 +667,7 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (!string.IsNullOrEmpty(CustomRating))
+ if (!string.IsNullOrWhiteSpace(CustomRating))
{
return CustomRating;
}
@@ -701,16 +706,16 @@ namespace MediaBrowser.Controller.Entities
/// Loads the theme songs.
/// </summary>
/// <returns>List{Audio.Audio}.</returns>
- private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
+ private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
- var files = fileSystemChildren.OfType<DirectoryInfo>()
+ var files = fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
+ .SelectMany(i => directoryService.GetFiles(i.FullName))
.ToList();
// Support plex/xbmc convention
- files.AddRange(fileSystemChildren.OfType<FileInfo>()
- .Where(i => string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
+ files.AddRange(fileSystemChildren
+ .Where(i => !i.IsDirectory && string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
);
return LibraryManager.ResolvePaths(files, directoryService, null)
@@ -737,11 +742,11 @@ namespace MediaBrowser.Controller.Entities
/// Loads the video backdrops.
/// </summary>
/// <returns>List{Video}.</returns>
- private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
+ private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
- var files = fileSystemChildren.OfType<DirectoryInfo>()
+ var files = fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly));
+ .SelectMany(i => directoryService.GetFiles(i.FullName));
return LibraryManager.ResolvePaths(files, directoryService, null)
.OfType<Video>()
@@ -765,7 +770,7 @@ namespace MediaBrowser.Controller.Entities
public Task RefreshMetadata(CancellationToken cancellationToken)
{
- return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService()), cancellationToken);
+ return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
}
/// <summary>
@@ -786,7 +791,7 @@ namespace MediaBrowser.Controller.Entities
{
var files = locationType != LocationType.Remote && locationType != LocationType.Virtual ?
GetFileSystemChildren(options.DirectoryService).ToList() :
- new List<FileSystemInfo>();
+ new List<FileSystemMetadata>();
var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false);
@@ -833,7 +838,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="fileSystemChildren"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
- protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var themeSongsChanged = false;
@@ -864,14 +869,14 @@ namespace MediaBrowser.Controller.Entities
return themeSongsChanged || themeVideosChanged || localTrailersChanged;
}
- protected virtual IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
+ protected virtual IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{
var path = ContainingFolderPath;
return directoryService.GetFileSystemEntries(path);
}
- private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newItems = LibraryManager.FindTrailers(this, fileSystemChildren, options.DirectoryService).ToList();
@@ -888,7 +893,7 @@ namespace MediaBrowser.Controller.Entities
return itemsChanged;
}
- private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList();
@@ -902,7 +907,7 @@ namespace MediaBrowser.Controller.Entities
if (!i.IsThemeMedia)
{
- i.IsThemeMedia = true;
+ i.ExtraType = ExtraType.ThemeVideo;
subOptions.ForceSave = true;
}
@@ -919,7 +924,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Refreshes the theme songs.
/// </summary>
- private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList();
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList();
@@ -932,7 +937,7 @@ namespace MediaBrowser.Controller.Entities
if (!i.IsThemeMedia)
{
- i.IsThemeMedia = true;
+ i.ExtraType = ExtraType.ThemeSong;
subOptions.ForceSave = true;
}
@@ -999,18 +1004,11 @@ namespace MediaBrowser.Controller.Entities
/// <returns>System.String.</returns>
public string GetPreferredMetadataLanguage()
{
- string lang = null;
-
- var hasLang = this as IHasPreferredMetadataLanguage;
-
- if (hasLang != null)
- {
- lang = hasLang.PreferredMetadataLanguage;
- }
+ string lang = PreferredMetadataLanguage;
if (string.IsNullOrWhiteSpace(lang))
{
- lang = Parents.OfType<IHasPreferredMetadataLanguage>()
+ lang = Parents
.Select(i => i.PreferredMetadataLanguage)
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
@@ -1036,18 +1034,11 @@ namespace MediaBrowser.Controller.Entities
/// <returns>System.String.</returns>
public string GetPreferredMetadataCountryCode()
{
- string lang = null;
-
- var hasLang = this as IHasPreferredMetadataLanguage;
-
- if (hasLang != null)
- {
- lang = hasLang.PreferredMetadataCountryCode;
- }
+ string lang = PreferredMetadataCountryCode;
if (string.IsNullOrWhiteSpace(lang))
{
- lang = Parents.OfType<IHasPreferredMetadataLanguage>()
+ lang = Parents
.Select(i => i.PreferredMetadataCountryCode)
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
@@ -1114,7 +1105,14 @@ namespace MediaBrowser.Controller.Entities
// Could not determine the integer value
if (!value.HasValue)
{
- return true;
+ 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;
@@ -1165,6 +1163,17 @@ namespace MediaBrowser.Controller.Entities
/// <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(UnratedItem.Other);
}
@@ -1418,7 +1427,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns>
public virtual Task ChangedExternally()
{
- ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions());
+ ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(FileSystem));
return Task.FromResult(true);
}
@@ -1434,7 +1443,24 @@ namespace MediaBrowser.Controller.Entities
return GetImageInfo(type, imageIndex) != null;
}
- public void SetImagePath(ImageType type, int index, FileSystemInfo file)
+ 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)
+ {
+ ImageInfos.Remove(existingImage);
+ }
+
+ ImageInfos.Add(image);
+ }
+
+ public void SetImagePath(ImageType type, int index, FileSystemMetadata file)
{
if (type == ImageType.Chapter)
{
@@ -1475,18 +1501,21 @@ namespace MediaBrowser.Controller.Entities
// Remove it from the item
RemoveImage(info);
- // Delete the source file
- var currentFile = new FileInfo(info.Path);
-
- // Deletion will fail if the file is hidden so remove the attribute first
- if (currentFile.Exists)
+ if (info.IsLocalFile)
{
- if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ // Delete the source file
+ var currentFile = new FileInfo(info.Path);
+
+ // Deletion will fail if the file is hidden so remove the attribute first
+ if (currentFile.Exists)
{
- currentFile.Attributes &= ~FileAttributes.Hidden;
- }
+ if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ {
+ currentFile.Attributes &= ~FileAttributes.Hidden;
+ }
- FileSystem.DeleteFile(currentFile.FullName);
+ FileSystem.DeleteFile(currentFile.FullName);
+ }
}
return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
@@ -1507,11 +1536,16 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public bool ValidateImages(IDirectoryService directoryService)
{
- var allDirectories = ImageInfos.Select(i => System.IO.Path.GetDirectoryName(i.Path)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
- var allFiles = allDirectories.SelectMany(directoryService.GetFiles).Select(i => i.FullName).ToList();
+ var allFiles = ImageInfos
+ .Where(i => i.IsLocalFile)
+ .Select(i => System.IO.Path.GetDirectoryName(i.Path))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .SelectMany(directoryService.GetFiles)
+ .Select(i => i.FullName)
+ .ToList();
var deletedImages = ImageInfos
- .Where(image => !allFiles.Contains(image.Path, StringComparer.OrdinalIgnoreCase))
+ .Where(image => image.IsLocalFile && !allFiles.Contains(image.Path, StringComparer.OrdinalIgnoreCase))
.ToList();
if (deletedImages.Count > 0)
@@ -1584,11 +1618,6 @@ namespace MediaBrowser.Controller.Entities
return ImageInfos.Where(i => i.Type == imageType);
}
- public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images)
- {
- return AddImages(imageType, images.Cast<FileSystemInfo>().ToList());
- }
-
/// <summary>
/// Adds the images.
/// </summary>
@@ -1596,7 +1625,7 @@ namespace MediaBrowser.Controller.Entities
/// <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<FileSystemInfo> images)
+ public bool AddImages(ImageType imageType, List<FileSystemMetadata> images)
{
if (imageType == ImageType.Chapter)
{
@@ -1606,7 +1635,7 @@ namespace MediaBrowser.Controller.Entities
var existingImages = GetImages(imageType)
.ToList();
- var newImageList = new List<FileSystemInfo>();
+ var newImageList = new List<FileSystemMetadata>();
var imageAdded = false;
foreach (var newImage in images)
@@ -1626,7 +1655,10 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
+ if (existing.IsLocalFile)
+ {
+ existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
+ }
}
}
@@ -1635,7 +1667,7 @@ namespace MediaBrowser.Controller.Entities
var newImagePaths = images.Select(i => i.FullName).ToList();
var deleted = existingImages
- .Where(i => !newImagePaths.Contains(i.Path, StringComparer.OrdinalIgnoreCase) && !File.Exists(i.Path))
+ .Where(i => i.IsLocalFile && !newImagePaths.Contains(i.Path, StringComparer.OrdinalIgnoreCase) && !FileSystem.FileExists(i.Path))
.ToList();
ImageInfos = ImageInfos.Except(deleted).ToList();
@@ -1646,7 +1678,7 @@ namespace MediaBrowser.Controller.Entities
return newImageList.Count > 0;
}
- private ItemImageInfo GetImageInfo(FileSystemInfo file, ImageType type)
+ private ItemImageInfo GetImageInfo(FileSystemMetadata file, ImageType type)
{
return new ItemImageInfo
{
@@ -1686,6 +1718,12 @@ namespace MediaBrowser.Controller.Entities
return Task.FromResult(true);
}
+ if (!info1.IsLocalFile || !info2.IsLocalFile)
+ {
+ // TODO: Not supported yet
+ return Task.FromResult(true);
+ }
+
var path1 = info1.Path;
var path2 = info2.Path;
@@ -1769,7 +1807,7 @@ namespace MediaBrowser.Controller.Entities
{
foreach (var map in ConfigurationManager.Configuration.PathSubstitutions)
{
- path = FileSystem.SubstitutePath(path, map.From, map.To);
+ path = LibraryManager.SubstitutePath(path, map.From, map.To);
}
}
@@ -1810,7 +1848,7 @@ namespace MediaBrowser.Controller.Entities
if (video == null)
{
- video = LibraryManager.ResolvePath(new FileInfo(path)) as Video;
+ video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
newOptions.ForceSave = true;
}
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
index e59db67a6a..d31675baf6 100644
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -7,7 +7,7 @@ using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller.Entities
{
- public class Book : BaseItem, IHasTags, IHasPreferredMetadataLanguage, IHasLookupInfo<BookInfo>, IHasSeries
+ public class Book : BaseItem, IHasTags, IHasLookupInfo<BookInfo>, IHasSeries
{
public override string MediaType
{
@@ -25,14 +25,6 @@ namespace MediaBrowser.Controller.Entities
public string SeriesName { get; set; }
- public string PreferredMetadataLanguage { get; set; }
-
- /// <summary>
- /// Gets or sets the preferred metadata country code.
- /// </summary>
- /// <value>The preferred metadata country code.</value>
- public string PreferredMetadataCountryCode { get; set; }
-
public Book()
{
Tags = new List<string>();
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index 8821f35c8b..946d95a0bb 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -8,6 +8,8 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Controller.Entities
{
@@ -80,7 +82,7 @@ namespace MediaBrowser.Controller.Entities
public List<string> PhysicalLocationsList { get; set; }
- protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
+ protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService)
{
return CreateResolveArgs(directoryService).FileSystemChildren;
}
@@ -107,7 +109,7 @@ namespace MediaBrowser.Controller.Entities
var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
{
- FileInfo = new DirectoryInfo(path),
+ FileInfo = FileSystem.GetDirectoryInfo(path),
Path = path,
Parent = Parent,
CollectionType = CollectionType
@@ -129,7 +131,7 @@ namespace MediaBrowser.Controller.Entities
{
var paths = LibraryManager.NormalizeRootPathList(fileSystemDictionary.Keys);
- fileSystemDictionary = paths.Select(i => (FileSystemInfo)new DirectoryInfo(i)).ToDictionary(i => i.FullName);
+ fileSystemDictionary = paths.Select(FileSystem.GetDirectoryInfo).ToDictionary(i => i.FullName);
}
args.FileSystemDictionary = fileSystemDictionary;
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index c3ac77328d..05965e1b5a 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -13,13 +13,15 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Controller.Entities
{
/// <summary>
/// Class Folder
/// </summary>
- public class Folder : BaseItem, IHasThemeMedia, IHasTags, IHasPreferredMetadataLanguage
+ public class Folder : BaseItem, IHasThemeMedia, IHasTags
{
public static IUserManager UserManager { get; set; }
public static IUserViewManager UserViewManager { get; set; }
@@ -28,14 +30,6 @@ namespace MediaBrowser.Controller.Entities
public List<Guid> ThemeVideoIds { get; set; }
public List<string> Tags { get; set; }
- public string PreferredMetadataLanguage { get; set; }
-
- /// <summary>
- /// Gets or sets the preferred metadata country code.
- /// </summary>
- /// <value>The preferred metadata country code.</value>
- public string PreferredMetadataCountryCode { get; set; }
-
public Folder()
{
LinkedChildren = new List<LinkedChild>();
@@ -48,7 +42,7 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
public virtual bool IsPreSorted
{
- get { return ConfigurationManager.Configuration.EnableWindowsShortcuts; }
+ get { return false; }
}
/// <summary>
@@ -120,7 +114,7 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
protected virtual bool SupportsShortcutChildren
{
- get { return false; }
+ get { return ConfigurationManager.Configuration.EnableWindowsShortcuts; }
}
/// <summary>
@@ -213,7 +207,7 @@ namespace MediaBrowser.Controller.Entities
return base.OfficialRatingForComparison;
}
- return !string.IsNullOrEmpty(base.OfficialRatingForComparison) ? base.OfficialRatingForComparison : "None";
+ return !string.IsNullOrWhiteSpace(base.OfficialRatingForComparison) ? base.OfficialRatingForComparison : "None";
}
}
@@ -320,7 +314,7 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
public IEnumerable<BaseItem> Children
{
- get { return ActualChildren; }
+ get { return ActualChildren.ToList(); }
}
/// <summary>
@@ -371,7 +365,7 @@ namespace MediaBrowser.Controller.Entities
public Task ValidateChildren(IProgress<double> progress, CancellationToken cancellationToken)
{
- return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService()));
+ return ValidateChildren(progress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(FileSystem)));
}
/// <summary>
@@ -474,7 +468,7 @@ namespace MediaBrowser.Controller.Entities
currentChild.DateModified = child.DateModified;
}
- currentChild.IsOffline = false;
+ await UpdateIsOffline(currentChild, false).ConfigureAwait(false);
validChildren.Add(currentChild);
}
else
@@ -509,12 +503,12 @@ namespace MediaBrowser.Controller.Entities
else if (!string.IsNullOrEmpty(item.Path) && IsPathOffline(item.Path))
{
- item.IsOffline = true;
+ await UpdateIsOffline(item, true).ConfigureAwait(false);
validChildren.Add(item);
}
else
{
- item.IsOffline = false;
+ await UpdateIsOffline(item, false).ConfigureAwait(false);
actualRemovals.Add(item);
}
}
@@ -569,6 +563,17 @@ namespace MediaBrowser.Controller.Entities
progress.Report(100);
}
+ private Task UpdateIsOffline(BaseItem item, bool newValue)
+ {
+ if (item.IsOffline != newValue)
+ {
+ item.IsOffline = newValue;
+ return item.UpdateToRepository(ItemUpdateType.None, CancellationToken.None);
+ }
+
+ return Task.FromResult(true);
+ }
+
private async Task RefreshMetadataRecursive(MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
{
var children = ActualChildren.ToList();
@@ -691,9 +696,9 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <param name="path">The path.</param>
/// <returns><c>true</c> if the specified path is offline; otherwise, <c>false</c>.</returns>
- private bool IsPathOffline(string path)
+ public static bool IsPathOffline(string path)
{
- if (File.Exists(path))
+ if (FileSystem.FileExists(path))
{
return false;
}
@@ -703,7 +708,7 @@ namespace MediaBrowser.Controller.Entities
// Depending on whether the path is local or unc, it may return either null or '\' at the top
while (!string.IsNullOrEmpty(path) && path.Length > 1)
{
- if (Directory.Exists(path))
+ if (FileSystem.DirectoryExists(path))
{
return false;
}
@@ -725,12 +730,12 @@ namespace MediaBrowser.Controller.Entities
/// <param name="folders">The folders.</param>
/// <param name="path">The path.</param>
/// <returns><c>true</c> if the specified folders contains path; otherwise, <c>false</c>.</returns>
- private bool ContainsPath(IEnumerable<VirtualFolderInfo> folders, string path)
+ private static bool ContainsPath(IEnumerable<VirtualFolderInfo> folders, string path)
{
return folders.SelectMany(i => i.Locations).Any(i => ContainsPath(i, path));
}
- private bool ContainsPath(string parent, string path)
+ private static bool ContainsPath(string parent, string path)
{
return string.Equals(parent, path, StringComparison.OrdinalIgnoreCase) || FileSystem.ContainsSubPath(parent, path);
}
@@ -752,21 +757,24 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
protected IEnumerable<BaseItem> GetCachedChildren()
{
- var childrenItems = ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
-
- //var children = ItemRepository.GetChildren(Id).Select(RetrieveChild).Where(i => i != null).ToList();
-
- //if (children.Count != childrenItems.Count)
- //{
- // var b = this;
- //}
+ if (ConfigurationManager.Configuration.DisableStartupScan)
+ {
+ return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
+ //return ItemRepository.GetItems(new InternalItemsQuery
+ //{
+ // ParentId = Id
- return childrenItems;
+ //}).Items.Select(RetrieveChild).Where(i => i != null);
+ }
+ else
+ {
+ return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
+ }
}
private BaseItem RetrieveChild(BaseItem child)
{
- if (child.Id == Guid.Empty)
+ if (child == null || child.Id == Guid.Empty)
{
Logger.Error("Item found with empty Id: " + (child.Path ?? child.Name));
return null;
@@ -1064,7 +1072,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var changesFound = false;
@@ -1085,7 +1093,7 @@ namespace MediaBrowser.Controller.Entities
/// Refreshes the linked children.
/// </summary>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- private bool RefreshLinkedChildren(IEnumerable<FileSystemInfo> fileSystemChildren)
+ private bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
{
var currentManualLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Manual).ToList();
var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList();
@@ -1170,9 +1178,16 @@ namespace MediaBrowser.Controller.Entities
DateTime? datePlayed,
bool resetPosition)
{
+ var itemsResult = await GetItems(new InternalItemsQuery
+ {
+ User = user,
+ Recursive = true,
+ IsFolder = false
+
+ }).ConfigureAwait(false);
+
// Sweep through recursively and update status
- var tasks = GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual)
- .Select(c => c.MarkPlayed(user, datePlayed, resetPosition));
+ var tasks = itemsResult.Items.Select(c => c.MarkPlayed(user, datePlayed, resetPosition));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
@@ -1184,9 +1199,16 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Task.</returns>
public override async Task MarkUnplayed(User user)
{
+ var itemsResult = await GetItems(new InternalItemsQuery
+ {
+ User = user,
+ Recursive = true,
+ IsFolder = false
+
+ }).ConfigureAwait(false);
+
// Sweep through recursively and update status
- var tasks = GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual)
- .Select(c => c.MarkUnplayed(user));
+ var tasks = itemsResult.Items.Select(c => c.MarkUnplayed(user));
await Task.WhenAll(tasks).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
index 15d2d755a8..ed3e85d586 100644
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ b/MediaBrowser.Controller/Entities/Game.cs
@@ -8,19 +8,11 @@ using System.Linq;
namespace MediaBrowser.Controller.Entities
{
- public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasPreferredMetadataLanguage, IHasLookupInfo<GameInfo>
+ public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasTags, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo>
{
public List<Guid> ThemeSongIds { get; set; }
public List<Guid> ThemeVideoIds { get; set; }
- public string PreferredMetadataLanguage { get; set; }
-
- /// <summary>
- /// Gets or sets the preferred metadata country code.
- /// </summary>
- /// <value>The preferred metadata country code.</value>
- public string PreferredMetadataCountryCode { get; set; }
-
public Game()
{
MultiPartGameFiles = new List<string>();
diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs
index ffb351c943..28835168a6 100644
--- a/MediaBrowser.Controller/Entities/IHasImages.cs
+++ b/MediaBrowser.Controller/Entities/IHasImages.cs
@@ -2,7 +2,11 @@
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
using System.IO;
+using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Library;
namespace MediaBrowser.Controller.Entities
{
@@ -67,7 +71,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="type">The type.</param>
/// <param name="index">The index.</param>
/// <param name="file">The file.</param>
- void SetImagePath(ImageType type, int index, FileSystemInfo file);
+ void SetImagePath(ImageType type, int index, FileSystemMetadata file);
/// <summary>
/// Determines whether the specified type has image.
@@ -134,7 +138,7 @@ namespace MediaBrowser.Controller.Entities
/// <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<FileSystemInfo> images);
+ bool AddImages(ImageType imageType, List<FileSystemMetadata> images);
/// <summary>
/// Determines whether [is save local metadata enabled].
@@ -189,6 +193,21 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <param name="image">The image.</param>
void RemoveImage(ItemImageInfo image);
+
+ /// <summary>
+ /// Updates to repository.
+ /// </summary>
+ /// <param name="updateReason">The update reason.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task.</returns>
+ Task 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);
}
public static class HasImagesExtensions
@@ -215,7 +234,7 @@ namespace MediaBrowser.Controller.Entities
/// <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 IHasImages item, ImageType imageType, FileSystemInfo file)
+ public static void SetImagePath(this IHasImages item, ImageType imageType, FileSystemMetadata file)
{
item.SetImagePath(imageType, 0, file);
}
@@ -228,7 +247,18 @@ namespace MediaBrowser.Controller.Entities
/// <param name="file">The file.</param>
public static void SetImagePath(this IHasImages item, ImageType imageType, string file)
{
- item.SetImagePath(imageType, new FileInfo(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/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs
index 158bcb6d19..473ee120ea 100644
--- a/MediaBrowser.Controller/Entities/IHasMetadata.cs
+++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs
@@ -31,13 +31,11 @@ namespace MediaBrowser.Controller.Entities
DateTime DateLastSaved { get; set; }
/// <summary>
- /// Updates to repository.
+ /// Gets or sets the date last refreshed.
/// </summary>
- /// <param name="updateReason">The update reason.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken);
-
+ /// <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>
@@ -45,17 +43,6 @@ namespace MediaBrowser.Controller.Entities
bool BeforeMetadataRefresh();
/// <summary>
- /// Gets or sets a value indicating whether this instance is unidentified.
- /// </summary>
- /// <value><c>true</c> if this instance is unidentified; otherwise, <c>false</c>.</value>
- bool IsUnidentified { get; set; }
-
- /// <summary>
- /// Gets the item identities.
- /// </summary>
- List<IItemIdentity> Identities { get; set; }
-
- /// <summary>
/// Afters the metadata refresh.
/// </summary>
void AfterMetadataRefresh();
diff --git a/MediaBrowser.Controller/Entities/IHasPreferredMetadataLanguage.cs b/MediaBrowser.Controller/Entities/IHasPreferredMetadataLanguage.cs
deleted file mode 100644
index e3a233e49e..0000000000
--- a/MediaBrowser.Controller/Entities/IHasPreferredMetadataLanguage.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- /// <summary>
- /// Interface IHasPreferredMetadataLanguage
- /// </summary>
- public interface IHasPreferredMetadataLanguage
- {
- /// <summary>
- /// Gets or sets the preferred metadata language.
- /// </summary>
- /// <value>The preferred metadata language.</value>
- string PreferredMetadataLanguage { get; set; }
-
- /// <summary>
- /// Gets or sets the preferred metadata country code.
- /// </summary>
- /// <value>The preferred metadata country code.</value>
- string PreferredMetadataCountryCode { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
index 9938a44894..1c3270d72c 100644
--- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
+++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs
@@ -15,6 +15,6 @@ namespace MediaBrowser.Controller.Entities
bool IsLive { get; set; }
bool IsPremiere { get; set; }
ProgramAudio? Audio { get; set; }
- DateTime? OriginalAirDate { get; set; }
+ string EpisodeTitle { get; set; }
}
}
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index 0af4972f74..785e2fd2bb 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -52,7 +52,6 @@ namespace MediaBrowser.Controller.Entities
public bool? IsHD { get; set; }
public bool? IsInBoxSet { get; set; }
public bool? IsLocked { get; set; }
- public bool? IsUnidentified { get; set; }
public bool? IsPlaceHolder { get; set; }
public bool? IsYearMismatched { get; set; }
@@ -98,7 +97,11 @@ namespace MediaBrowser.Controller.Entities
public bool? IsCurrentSchema { get; set; }
public bool? HasDeadParentId { get; set; }
-
+ public bool? IsOffline { get; set; }
+ public LocationType? LocationType { get; set; }
+
+ public Guid? ParentId { get; set; }
+
public InternalItemsQuery()
{
Tags = new string[] { };
diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
index b36b818ffe..bb113e596d 100644
--- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs
+++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Model.Entities;
using System;
+using System.Runtime.Serialization;
namespace MediaBrowser.Controller.Entities
{
@@ -22,5 +23,21 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The date modified.</value>
public DateTime DateModified { 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/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 083ec0cb4c..1a8148edfb 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -8,6 +8,8 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Controller.Entities.Movies
{
@@ -122,7 +124,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return key;
}
- protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
@@ -141,7 +143,7 @@ namespace MediaBrowser.Controller.Entities.Movies
return hasChanges;
}
- private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ 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).ToList();
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index 5163c3de4a..92ca9e9703 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -296,9 +296,16 @@ namespace MediaBrowser.Controller.Entities.TV
{
var hasChanges = base.BeforeMetadataRefresh();
- if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
+ try
{
- hasChanges = true;
+ if (LibraryManager.FillMissingEpisodeNumbersFromPath(this))
+ {
+ hasChanges = true;
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error in FillMissingEpisodeNumbersFromPath. Episode: {0}", ex, Path ?? Name ?? Id.ToString());
}
return hasChanges;
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index cfd6b46e0f..21b89d7a99 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -62,17 +62,13 @@ namespace MediaBrowser.Controller.Entities.TV
}
/// <summary>
- /// The _series
- /// </summary>
- private Series _series;
- /// <summary>
/// This Episode's Series Instance
/// </summary>
/// <value>The series.</value>
[IgnoreDataMember]
public Series Series
{
- get { return _series ?? (_series = FindParent<Series>()); }
+ get { return FindParent<Series>(); }
}
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 2663d19e8f..b23833845e 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -20,7 +20,6 @@ namespace MediaBrowser.Controller.Entities.TV
public List<Guid> SpecialFeatureIds { get; set; }
public string OriginalTitle { get; set; }
- public int SeasonCount { get; set; }
public int? AnimeSeriesIndex { get; set; }
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index f44128e2d6..6ec512783d 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
+using MediaBrowser.Controller.Entities.Movies;
namespace MediaBrowser.Controller.Entities
{
@@ -78,7 +79,7 @@ namespace MediaBrowser.Controller.Entities
protected override string CreateUserDataKey()
{
- var key = this.GetProviderId(MetadataProviders.Imdb) ?? this.GetProviderId(MetadataProviders.Tmdb);
+ var key = Movie.GetMovieUserDataKey(this);
if (!string.IsNullOrWhiteSpace(key))
{
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index 71e3d1ce03..a9e314ede1 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.Entities
{
public static IUserManager UserManager { get; set; }
public static IXmlSerializer XmlSerializer { get; set; }
+ public bool EnableUserViews { get; set; }
/// <summary>
/// From now on all user paths will be Id-based.
@@ -177,24 +178,24 @@ namespace MediaBrowser.Controller.Entities
var oldConfigurationDirectory = ConfigurationDirectoryPath;
// Exceptions will be thrown if these paths already exist
- if (Directory.Exists(newConfigDirectory))
+ if (FileSystem.DirectoryExists(newConfigDirectory))
{
FileSystem.DeleteDirectory(newConfigDirectory, true);
}
- if (Directory.Exists(oldConfigurationDirectory))
+ if (FileSystem.DirectoryExists(oldConfigurationDirectory))
{
- Directory.Move(oldConfigurationDirectory, newConfigDirectory);
+ FileSystem.MoveDirectory(oldConfigurationDirectory, newConfigDirectory);
}
else
{
- Directory.CreateDirectory(newConfigDirectory);
+ FileSystem.CreateDirectory(newConfigDirectory);
}
}
Name = newName;
- return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService())
+ return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem))
{
ReplaceAllMetadata = true,
ImageRefreshMode = ImageRefreshMode.FullRefresh,
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index 488e54cc3c..5ee49ae5a3 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -13,6 +13,7 @@ namespace MediaBrowser.Controller.Entities
{
public string ViewType { get; set; }
public Guid ParentId { get; set; }
+ public Guid DisplayParentId { get; set; }
public Guid? UserId { get; set; }
@@ -28,7 +29,11 @@ namespace MediaBrowser.Controller.Entities
{
var parent = this as Folder;
- if (ParentId != Guid.Empty)
+ if (DisplayParentId != Guid.Empty)
+ {
+ parent = LibraryManager.GetItemById(DisplayParentId) as Folder ?? parent;
+ }
+ else if (ParentId != Guid.Empty)
{
parent = LibraryManager.GetItemById(ParentId) as Folder ?? parent;
}
@@ -82,7 +87,28 @@ namespace MediaBrowser.Controller.Entities
{
CollectionType.Books,
CollectionType.HomeVideos,
- CollectionType.Photos
+ CollectionType.Photos,
+ CollectionType.Playlists,
+ CollectionType.BoxSets,
+ CollectionType.MusicVideos
+ };
+
+ var collectionFolder = folder as ICollectionFolder;
+
+ if (collectionFolder == null)
+ {
+ return false;
+ }
+
+ return standaloneTypes.Contains(collectionFolder.CollectionType ?? string.Empty);
+ }
+
+ public static bool IsUserSpecific(Folder folder)
+ {
+ var standaloneTypes = new List<string>
+ {
+ CollectionType.Playlists,
+ CollectionType.BoxSets
};
var collectionFolder = folder as ICollectionFolder;
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index cee5dadd25..f5800ce818 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -577,19 +577,9 @@ namespace MediaBrowser.Controller.Entities
private async Task<QueryResult<BaseItem>> GetBoxsetView(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetMediaFolders(user).SelectMany(i =>
- {
- var hasCollectionType = i as ICollectionFolder;
- Func<BaseItem, bool> filter = b => b is BoxSet;
-
- if (hasCollectionType != null && string.Equals(hasCollectionType.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
- {
- return i.GetChildren(user, true).Where(filter);
- }
-
- return i.GetRecursiveChildren(user, filter);
+ var collections = _collectionManager.GetCollections(user);
- }), parent, query);
+ return GetResult(collections, parent, query);
}
private async Task<QueryResult<BaseItem>> GetPhotosView(Folder queryParent, User user, InternalItemsQuery query)
@@ -1041,11 +1031,6 @@ namespace MediaBrowser.Controller.Entities
return false;
}
- if (request.IsUnidentified.HasValue)
- {
- return false;
- }
-
if (request.IsYearMismatched.HasValue)
{
return false;
@@ -1412,16 +1397,7 @@ namespace MediaBrowser.Controller.Entities
var val = query.IsHD.Value;
var video = item as Video;
- if (video == null || val != video.IsHD)
- {
- return false;
- }
- }
-
- if (query.IsUnidentified.HasValue)
- {
- var val = query.IsUnidentified.Value;
- if (item.IsUnidentified != val)
+ if (video == null || !video.IsHD.HasValue || val != video.IsHD)
{
return false;
}
@@ -1808,6 +1784,13 @@ namespace MediaBrowser.Controller.Entities
private IEnumerable<Folder> GetMediaFolders(User user)
{
+ if (user == null)
+ {
+ return _libraryManager.RootFolder
+ .Children
+ .OfType<Folder>()
+ .Where(i => !UserView.IsExcludedFromGrouping(i));
+ }
return user.RootFolder
.GetChildren(user, true, true)
.OfType<Folder>()
@@ -1816,6 +1799,16 @@ namespace MediaBrowser.Controller.Entities
private IEnumerable<Folder> 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);
+ });
+ }
return GetMediaFolders(user)
.Where(i =>
{
@@ -1839,9 +1832,19 @@ namespace MediaBrowser.Controller.Entities
{
if (parent == null || parent is UserView)
{
+ if (user == null)
+ {
+ return GetMediaFolders(null, viewTypes).SelectMany(i => i.GetRecursiveChildren());
+ }
+
return GetMediaFolders(user, viewTypes).SelectMany(i => i.GetRecursiveChildren(user));
}
+ if (user == null)
+ {
+ return parent.GetRecursiveChildren();
+ }
+
return parent.GetRecursiveChildren(user);
}
@@ -1849,9 +1852,19 @@ namespace MediaBrowser.Controller.Entities
{
if (parent == null || parent is UserView)
{
+ if (user == null)
+ {
+ return GetMediaFolders(null, viewTypes).SelectMany(i => i.GetRecursiveChildren(filter));
+ }
+
return GetMediaFolders(user, viewTypes).SelectMany(i => i.GetRecursiveChildren(user, filter));
}
+ if (user == null)
+ {
+ return parent.GetRecursiveChildren(filter);
+ }
+
return parent.GetRecursiveChildren(user, filter);
}
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 00dc5dc672..8beee79bf5 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -11,6 +11,8 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
+using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Controller.Entities
{
@@ -23,7 +25,6 @@ namespace MediaBrowser.Controller.Entities
ISupportsPlaceHolders,
IHasMediaSources,
IHasShortOverview,
- IHasPreferredMetadataLanguage,
IThemeMedia,
IArchivable
{
@@ -33,21 +34,20 @@ namespace MediaBrowser.Controller.Entities
public List<string> LocalAlternateVersions { get; set; }
public List<LinkedChild> LinkedAlternateVersions { get; set; }
- public bool IsThemeMedia { get; set; }
+ [IgnoreDataMember]
+ public bool IsThemeMedia
+ {
+ get
+ {
+ return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeVideo;
+ }
+ }
- public string FormatName { get; set; }
public long? Size { get; set; }
public string Container { get; set; }
public int? TotalBitrate { get; set; }
public string ShortOverview { get; set; }
- public ExtraType ExtraType { get; set; }
-
- /// <summary>
- /// Gets or sets the preferred metadata country code.
- /// </summary>
- /// <value>The preferred metadata country code.</value>
- public string PreferredMetadataCountryCode { get; set; }
- public string PreferredMetadataLanguage { get; set; }
+ public ExtraType? ExtraType { get; set; }
/// <summary>
/// Gets or sets the timestamp.
@@ -313,7 +313,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>List{System.String}.</returns>
public List<string> GetPlayableStreamFiles(string rootPath)
{
- var allFiles = Directory.EnumerateFiles(rootPath, "*", SearchOption.AllDirectories).ToList();
+ var allFiles = FileSystem.GetFilePaths(rootPath, true).ToList();
return PlayableStreamFileNames.Select(name => allFiles.FirstOrDefault(f => string.Equals(System.IO.Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase)))
.Where(f => !string.IsNullOrEmpty(f))
@@ -330,8 +330,6 @@ namespace MediaBrowser.Controller.Entities
get { return Video3DFormat.HasValue; }
}
- public bool IsHD { get; set; }
-
/// <summary>
/// Gets the type of the media.
/// </summary>
@@ -345,7 +343,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
+ protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
@@ -498,7 +496,6 @@ namespace MediaBrowser.Controller.Entities
VideoType = i.VideoType,
Container = i.Container,
Size = i.Size,
- Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(),
Timestamp = i.Timestamp,
Type = type,
PlayableStreamFileNames = i.PlayableStreamFileNames.ToList(),