diff options
Diffstat (limited to 'MediaBrowser.Controller')
| -rw-r--r-- | MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/BaseItem.cs | 27 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 125 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/IHasImages.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Library/ILibraryManager.cs | 7 | ||||
| -rw-r--r-- | MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs | 26 | ||||
| -rw-r--r-- | MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs | 52 | ||||
| -rw-r--r-- | MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs (renamed from MediaBrowser.Controller/LiveTv/LiveTvRecording.cs) | 15 | ||||
| -rw-r--r-- | MediaBrowser.Controller/MediaBrowser.Controller.csproj | 4 |
10 files changed, 184 insertions, 85 deletions
diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs index 506d6fd3d..93293b34d 100644 --- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -37,8 +37,10 @@ namespace MediaBrowser.Controller.Drawing public bool AddPlayedIndicator { get; set; } - public int? PercentPlayed { get; set; } + public int? UnplayedCount { get; set; } + public double? PercentPlayed { get; set; } + public string BackgroundColor { get; set; } public bool HasDefaultOptions() @@ -56,6 +58,7 @@ namespace MediaBrowser.Controller.Drawing IsOutputFormatDefault && !AddPlayedIndicator && !PercentPlayed.HasValue && + !UnplayedCount.HasValue && string.IsNullOrEmpty(BackgroundColor); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 11562b3d7..dbda4a243 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -156,7 +156,7 @@ namespace MediaBrowser.Controller.Entities public DateTime DateModified { get; set; } public DateTime DateLastSaved { get; set; } - + /// <summary> /// The logger /// </summary> @@ -327,21 +327,18 @@ namespace MediaBrowser.Controller.Entities // When resolving the root, we need it's grandchildren (children of user views) var flattenFolderDepth = isPhysicalRoot ? 2 : 0; - args.FileSystemDictionary = FileData.GetFilteredFileSystemEntries(args.Path, FileSystem, Logger, args, flattenFolderDepth: flattenFolderDepth, resolveShortcuts: isPhysicalRoot || args.IsVf); + var fileSystemDictionary = FileData.GetFilteredFileSystemEntries(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) { - var paths = args.FileSystemDictionary.Keys.ToList(); + var paths = LibraryManager.NormalizeRootPathList(fileSystemDictionary.Keys); - foreach (var subPath in paths - .Where(subPath => !subPath.EndsWith(":\\", StringComparison.OrdinalIgnoreCase) && paths.Any(i => subPath.StartsWith(i.TrimEnd(System.IO.Path.DirectorySeparatorChar) + System.IO.Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)))) - { - Logger.Info("Ignoring duplicate path: {0}", subPath); - args.FileSystemDictionary.Remove(subPath); - } + fileSystemDictionary = paths.Select(i => (FileSystemInfo)new DirectoryInfo(i)).ToDictionary(i => i.FullName); } + + args.FileSystemDictionary = fileSystemDictionary; } //update our dates @@ -1016,14 +1013,18 @@ namespace MediaBrowser.Controller.Entities return lang; } + public virtual bool IsSaveLocalMetadataEnabled() + { + return ConfigurationManager.Configuration.SaveLocalMeta; + } + /// <summary> /// Determines if a given user has access to this item /// </summary> /// <param name="user">The user.</param> - /// <param name="localizationManager">The localization manager.</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, ILocalizationManager localizationManager) + public bool IsParentalAllowed(User user) { if (user == null) { @@ -1049,7 +1050,7 @@ namespace MediaBrowser.Controller.Entities return !GetBlockUnratedValue(user.Configuration); } - var value = localizationManager.GetRatingLevel(rating); + var value = LocalizationManager.GetRatingLevel(rating); // Could not determine the integer value if (!value.HasValue) @@ -1084,7 +1085,7 @@ namespace MediaBrowser.Controller.Entities throw new ArgumentNullException("user"); } - return IsParentalAllowed(user, LocalizationManager); + return IsParentalAllowed(user); } /// <summary> diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 912b8fa93..a85157a26 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -519,85 +519,84 @@ namespace MediaBrowser.Controller.Entities await Task.WhenAll(tasks).ConfigureAwait(false); } - Tuple<BaseItem, bool> currentTuple = tuple; - - tasks.Add(Task.Run(async () => - { - cancellationToken.ThrowIfCancellationRequested(); - - var child = currentTuple.Item1; - try - { - //refresh it - await child.RefreshMetadata(cancellationToken, forceSave: currentTuple.Item2, forceRefresh: forceRefreshMetadata, resetResolveArgs: false).ConfigureAwait(false); - } - catch (IOException ex) - { - Logger.ErrorException("Error refreshing {0}", ex, child.Path ?? child.Name); - } + tasks.Add(RefreshChild(tuple, progress, percentages, list.Count, cancellationToken, recursive, forceRefreshMetadata)); + } - // Refresh children if a folder and the item changed or recursive is set to true - var refreshChildren = child.IsFolder && (currentTuple.Item2 || (recursive.HasValue && recursive.Value)); + cancellationToken.ThrowIfCancellationRequested(); - if (refreshChildren) - { - // Don't refresh children if explicitly set to false - if (recursive.HasValue && recursive.Value == false) - { - refreshChildren = false; - } - } + await Task.WhenAll(tasks).ConfigureAwait(false); + } - if (refreshChildren) - { - cancellationToken.ThrowIfCancellationRequested(); + private async Task RefreshChild(Tuple<BaseItem, bool> currentTuple, IProgress<double> progress, Dictionary<Guid, double> percentages, int childCount, CancellationToken cancellationToken, bool? recursive, bool forceRefreshMetadata = false) + { + cancellationToken.ThrowIfCancellationRequested(); - var innerProgress = new ActionableProgress<double>(); + var child = currentTuple.Item1; + try + { + //refresh it + await child.RefreshMetadata(cancellationToken, forceSave: currentTuple.Item2, forceRefresh: forceRefreshMetadata, resetResolveArgs: false).ConfigureAwait(false); + } + catch (IOException ex) + { + Logger.ErrorException("Error refreshing {0}", ex, child.Path ?? child.Name); + } - innerProgress.RegisterAction(p => - { - lock (percentages) - { - percentages[child.Id] = p / 100; + // Refresh children if a folder and the item changed or recursive is set to true + var refreshChildren = child.IsFolder && (currentTuple.Item2 || (recursive.HasValue && recursive.Value)); - var percent = percentages.Values.Sum(); - percent /= list.Count; + if (refreshChildren) + { + // Don't refresh children if explicitly set to false + if (recursive.HasValue && recursive.Value == false) + { + refreshChildren = false; + } + } - progress.Report((90 * percent) + 10); - } - }); + if (refreshChildren) + { + cancellationToken.ThrowIfCancellationRequested(); - await ((Folder)child).ValidateChildren(innerProgress, cancellationToken, recursive, forceRefreshMetadata).ConfigureAwait(false); + var innerProgress = new ActionableProgress<double>(); - try - { - // Some folder providers are unable to refresh until children have been refreshed. - await child.RefreshMetadata(cancellationToken, resetResolveArgs: false).ConfigureAwait(false); - } - catch (IOException ex) - { - Logger.ErrorException("Error refreshing {0}", ex, child.Path ?? child.Name); - } - } - else + innerProgress.RegisterAction(p => + { + lock (percentages) { - lock (percentages) - { - percentages[child.Id] = 1; + percentages[child.Id] = p / 100; - var percent = percentages.Values.Sum(); - percent /= list.Count; + var percent = percentages.Values.Sum(); + percent /= childCount; - progress.Report((90 * percent) + 10); - } + progress.Report((90 * percent) + 10); } + }); - }, cancellationToken)); + await ((Folder)child).ValidateChildren(innerProgress, cancellationToken, recursive, forceRefreshMetadata).ConfigureAwait(false); + + try + { + // Some folder providers are unable to refresh until children have been refreshed. + await child.RefreshMetadata(cancellationToken, resetResolveArgs: false).ConfigureAwait(false); + } + catch (IOException ex) + { + Logger.ErrorException("Error refreshing {0}", ex, child.Path ?? child.Name); + } } + else + { + lock (percentages) + { + percentages[child.Id] = 1; - cancellationToken.ThrowIfCancellationRequested(); + var percent = percentages.Values.Sum(); + percent /= childCount; - await Task.WhenAll(tasks).ConfigureAwait(false); + progress.Report((90 * percent) + 10); + } + } } /// <summary> @@ -646,7 +645,7 @@ namespace MediaBrowser.Controller.Entities private bool ContainsPath(string parent, string path) { - return string.Equals(parent, path, StringComparison.OrdinalIgnoreCase) || path.IndexOf(parent.TrimEnd(System.IO.Path.DirectorySeparatorChar) + System.IO.Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) != -1; + return string.Equals(parent, path, StringComparison.OrdinalIgnoreCase) || FileSystem.ContainsSubPath(parent, path); } /// <summary> diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index d800acd9b..a7cd76a66 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -16,8 +16,8 @@ namespace MediaBrowser.Controller.Entities /// Gets the path. /// </summary> /// <value>The path.</value> - string Path { get; } - + string Path { get; set; } + /// <summary> /// Gets the identifier. /// </summary> @@ -100,7 +100,7 @@ namespace MediaBrowser.Controller.Entities { return item.HasImage(imageType, 0); } - + /// <summary> /// Sets the image path. /// </summary> diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index ae34621cb..036ac7e81 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -320,5 +320,12 @@ namespace MediaBrowser.Controller.Library /// <param name="items">The items.</param> /// <returns>IEnumerable{System.String}.</returns> IEnumerable<string> GetAllArtists(IEnumerable<BaseItem> items); + + /// <summary> + /// Normalizes the root path list. + /// </summary> + /// <param name="paths">The paths.</param> + /// <returns>IEnumerable{System.String}.</returns> + IEnumerable<string> NormalizeRootPathList(IEnumerable<string> paths); } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index c26e29d94..87ac0d4dc 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -153,7 +153,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="id">The identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>LiveTvRecording.</returns> - Task<LiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken); + Task<ILiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken); /// <summary> /// Gets the recording stream. diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs new file mode 100644 index 000000000..d9bceb6ca --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -0,0 +1,26 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface ILiveTvRecording : IHasImages, IHasMediaStreams + { + string ServiceName { get; set; } + + string MediaType { get; } + + LocationType LocationType { get; } + + RecordingInfo RecordingInfo { get; set; } + + string GetClientTypeName(); + + string GetUserDataKey(); + + bool IsParentalAllowed(User user); + + Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true); + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs new file mode 100644 index 000000000..8676540fd --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -0,0 +1,52 @@ +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Controller.LiveTv +{ + public class LiveTvAudioRecording : Audio, ILiveTvRecording + { + /// <summary> + /// Gets the user data key. + /// </summary> + /// <returns>System.String.</returns> + public override string GetUserDataKey() + { + return GetClientTypeName() + "-" + Name; + } + + public RecordingInfo RecordingInfo { get; set; } + + public string ServiceName { get; set; } + + public override string MediaType + { + get + { + return Model.Entities.MediaType.Audio; + } + } + + public override LocationType LocationType + { + get + { + if (!string.IsNullOrEmpty(Path)) + { + return base.LocationType; + } + + return LocationType.Remote; + } + } + + public override string GetClientTypeName() + { + return "Recording"; + } + + public override bool IsSaveLocalMetadataEnabled() + { + return false; + } + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 1c453ab5a..9dfc7f828 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -1,10 +1,9 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.LiveTv; namespace MediaBrowser.Controller.LiveTv { - public class LiveTvRecording : BaseItem + public class LiveTvVideoRecording : Video, ILiveTvRecording { /// <summary> /// Gets the user data key. @@ -23,7 +22,7 @@ namespace MediaBrowser.Controller.LiveTv { get { - return RecordingInfo.ChannelType == ChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video; + return Model.Entities.MediaType.Video; } } @@ -31,6 +30,11 @@ namespace MediaBrowser.Controller.LiveTv { get { + if (!string.IsNullOrEmpty(Path)) + { + return base.LocationType; + } + return LocationType.Remote; } } @@ -39,5 +43,10 @@ namespace MediaBrowser.Controller.LiveTv { return "Recording"; } + + public override bool IsSaveLocalMetadataEnabled() + { + return false; + } } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 0c5c0a5cd..25ea9979c 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -108,6 +108,8 @@ <Compile Include="Library\ItemUpdateType.cs" /> <Compile Include="Library\IUserDataManager.cs" /> <Compile Include="Library\UserDataSaveEventArgs.cs" /> + <Compile Include="LiveTv\ILiveTvRecording.cs" /> + <Compile Include="LiveTv\LiveTvAudioRecording.cs" /> <Compile Include="LiveTv\LiveTvChannel.cs" /> <Compile Include="LiveTv\ChannelInfo.cs" /> <Compile Include="LiveTv\ILiveTvManager.cs" /> @@ -115,7 +117,7 @@ <Compile Include="LiveTv\LiveTvException.cs" /> <Compile Include="LiveTv\StreamResponseInfo.cs" /> <Compile Include="LiveTv\LiveTvProgram.cs" /> - <Compile Include="LiveTv\LiveTvRecording.cs" /> + <Compile Include="LiveTv\LiveTvVideoRecording.cs" /> <Compile Include="LiveTv\ProgramInfo.cs" /> <Compile Include="LiveTv\RecordingInfo.cs" /> <Compile Include="LiveTv\SeriesTimerInfo.cs" /> |
