aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs5
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs27
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs125
-rw-r--r--MediaBrowser.Controller/Entities/IHasImages.cs6
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs7
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvManager.cs2
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs26
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs52
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs (renamed from MediaBrowser.Controller/LiveTv/LiveTvRecording.cs)15
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj4
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" />