aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Channels/Channel.cs8
-rw-r--r--MediaBrowser.Controller/Channels/IChannelManager.cs5
-rw-r--r--MediaBrowser.Controller/Devices/IDeviceManager.cs13
-rw-r--r--MediaBrowser.Controller/Devices/IDeviceRepository.cs13
-rw-r--r--MediaBrowser.Controller/Dlna/IEventManager.cs2
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs13
-rw-r--r--MediaBrowser.Controller/Dto/IDtoService.cs4
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs6
-rw-r--r--MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs14
-rw-r--r--MediaBrowser.Controller/Entities/AudioBook.cs9
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs82
-rw-r--r--MediaBrowser.Controller/Entities/Book.cs6
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs13
-rw-r--r--MediaBrowser.Controller/Entities/Game.cs6
-rw-r--r--MediaBrowser.Controller/Entities/IHasMetadata.cs11
-rw-r--r--MediaBrowser.Controller/Entities/ItemImageInfo.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Movies/BoxSet.cs8
-rw-r--r--MediaBrowser.Controller/Entities/PhotoAlbum.cs5
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs6
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs6
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs6
-rw-r--r--MediaBrowser.Controller/Entities/User.cs3
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs106
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs47
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs14
-rw-r--r--MediaBrowser.Controller/Library/IUserViewManager.cs4
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvManager.cs30
-rw-r--r--MediaBrowser.Controller/LiveTv/ITunerHost.cs4
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs7
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvChannel.cs3
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvProgram.cs37
-rw-r--r--MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs7
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs18
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs5
-rw-r--r--MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs326
-rw-r--r--MediaBrowser.Controller/Notifications/INotificationManager.cs3
-rw-r--r--MediaBrowser.Controller/Persistence/IItemRepository.cs2
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs2
-rw-r--r--MediaBrowser.Controller/Providers/IHasChangeMonitor.cs17
-rw-r--r--MediaBrowser.Controller/Providers/IMetadataService.cs4
-rw-r--r--MediaBrowser.Controller/Providers/IProviderManager.cs8
-rw-r--r--MediaBrowser.Controller/Providers/MetadataResult.cs1
-rw-r--r--MediaBrowser.Controller/Sync/ISyncManager.cs2
-rw-r--r--MediaBrowser.Controller/Sync/ISyncProvider.cs2
45 files changed, 597 insertions, 296 deletions
diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs
index f74c01994..54faa1443 100644
--- a/MediaBrowser.Controller/Channels/Channel.cs
+++ b/MediaBrowser.Controller/Channels/Channel.cs
@@ -32,14 +32,6 @@ namespace MediaBrowser.Controller.Channels
return base.IsVisible(user);
}
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 16;
- value /= 9;
-
- return value;
- }
-
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs
index 46e55a21c..37fc892b3 100644
--- a/MediaBrowser.Controller/Channels/IChannelManager.cs
+++ b/MediaBrowser.Controller/Channels/IChannelManager.cs
@@ -117,14 +117,13 @@ namespace MediaBrowser.Controller.Channels
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>BaseItemDto.</returns>
- Task<Folder> GetInternalChannelFolder(CancellationToken cancellationToken);
+ Folder GetInternalChannelFolder(CancellationToken cancellationToken);
/// <summary>
/// Gets the channel folder.
/// </summary>
/// <param name="userId">The user identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>BaseItemDto.</returns>
- Task<BaseItemDto> GetChannelFolder(string userId, CancellationToken cancellationToken);
+ BaseItemDto GetChannelFolder(string userId, CancellationToken cancellationToken);
}
}
diff --git a/MediaBrowser.Controller/Devices/IDeviceManager.cs b/MediaBrowser.Controller/Devices/IDeviceManager.cs
index 2846bcfc6..676db09aa 100644
--- a/MediaBrowser.Controller/Devices/IDeviceManager.cs
+++ b/MediaBrowser.Controller/Devices/IDeviceManager.cs
@@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Devices
/// <param name="appVersion">The application version.</param>
/// <param name="usedByUserId">The used by user identifier.</param>
/// <returns>Task.</returns>
- Task<DeviceInfo> RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId);
+ DeviceInfo RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId);
/// <summary>
/// Saves the capabilities.
@@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Devices
/// <param name="reportedId">The reported identifier.</param>
/// <param name="capabilities">The capabilities.</param>
/// <returns>Task.</returns>
- Task SaveCapabilities(string reportedId, ClientCapabilities capabilities);
+ void SaveCapabilities(string reportedId, ClientCapabilities capabilities);
/// <summary>
/// Gets the capabilities.
@@ -58,7 +58,7 @@ namespace MediaBrowser.Controller.Devices
/// <param name="id">The identifier.</param>
/// <param name="options">The options.</param>
/// <returns>Task.</returns>
- Task UpdateDeviceInfo(string id, DeviceOptions options);
+ void UpdateDeviceInfo(string id, DeviceOptions options);
/// <summary>
/// Gets the devices.
@@ -67,12 +67,7 @@ namespace MediaBrowser.Controller.Devices
/// <returns>IEnumerable&lt;DeviceInfo&gt;.</returns>
QueryResult<DeviceInfo> GetDevices(DeviceQuery query);
- /// <summary>
- /// Deletes the device.
- /// </summary>
- /// <param name="id">The identifier.</param>
- /// <returns>Task.</returns>
- Task DeleteDevice(string id);
+ void DeleteDevice(string id);
/// <summary>
/// Gets the upload history.
diff --git a/MediaBrowser.Controller/Devices/IDeviceRepository.cs b/MediaBrowser.Controller/Devices/IDeviceRepository.cs
index 736504da3..b9ebbb6c7 100644
--- a/MediaBrowser.Controller/Devices/IDeviceRepository.cs
+++ b/MediaBrowser.Controller/Devices/IDeviceRepository.cs
@@ -1,7 +1,6 @@
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Session;
using System.Collections.Generic;
-using System.Threading.Tasks;
namespace MediaBrowser.Controller.Devices
{
@@ -12,7 +11,7 @@ namespace MediaBrowser.Controller.Devices
/// </summary>
/// <param name="device">The device.</param>
/// <returns>Task.</returns>
- Task SaveDevice(DeviceInfo device);
+ void SaveDevice(DeviceInfo device);
/// <summary>
/// Saves the capabilities.
@@ -20,7 +19,7 @@ namespace MediaBrowser.Controller.Devices
/// <param name="id">The identifier.</param>
/// <param name="capabilities">The capabilities.</param>
/// <returns>Task.</returns>
- Task SaveCapabilities(string id, ClientCapabilities capabilities);
+ void SaveCapabilities(string id, ClientCapabilities capabilities);
/// <summary>
/// Gets the capabilities.
@@ -36,18 +35,14 @@ namespace MediaBrowser.Controller.Devices
/// <returns>DeviceInfo.</returns>
DeviceInfo GetDevice(string id);
- /// <summary>
- /// Gets the devices.
- /// </summary>
- /// <returns>IEnumerable&lt;DeviceInfo&gt;.</returns>
- IEnumerable<DeviceInfo> GetDevices();
+ List<DeviceInfo> GetDevices();
/// <summary>
/// Deletes the device.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>Task.</returns>
- Task DeleteDevice(string id);
+ void DeleteDevice(string id);
/// <summary>
/// Gets the upload history.
diff --git a/MediaBrowser.Controller/Dlna/IEventManager.cs b/MediaBrowser.Controller/Dlna/IEventManager.cs
index 8c91bd889..3af357a17 100644
--- a/MediaBrowser.Controller/Dlna/IEventManager.cs
+++ b/MediaBrowser.Controller/Dlna/IEventManager.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.Dlna
/// <summary>
/// Renews the event subscription.
/// </summary>
- EventSubscriptionResponse RenewEventSubscription(string subscriptionId, string requestedTimeoutString);
+ EventSubscriptionResponse RenewEventSubscription(string subscriptionId, string notificationType, string requestedTimeoutString, string callbackUrl);
/// <summary>
/// Creates the event subscription.
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index 542fa5e08..0bc92ac7e 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -26,21 +26,16 @@ namespace MediaBrowser.Controller.Drawing
/// <value>The image enhancers.</value>
IImageEnhancer[] ImageEnhancers { get; }
+ ImageSize GetImageSize(string path);
+
/// <summary>
/// Gets the size of the image.
/// </summary>
/// <param name="info">The information.</param>
/// <returns>ImageSize.</returns>
- ImageSize GetImageSize(ItemImageInfo info);
+ ImageSize GetImageSize(BaseItem item, ItemImageInfo info);
- ImageSize GetImageSize(ItemImageInfo info, bool allowSlowMethods);
-
- /// <summary>
- /// Gets the size of the image.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>ImageSize.</returns>
- ImageSize GetImageSize(string path);
+ ImageSize GetImageSize(BaseItem item, ItemImageInfo info, bool allowSlowMethods, bool updateItem);
/// <summary>
/// Adds the parts.
diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs
index c0217330d..5ba6e036e 100644
--- a/MediaBrowser.Controller/Dto/IDtoService.cs
+++ b/MediaBrowser.Controller/Dto/IDtoService.cs
@@ -23,14 +23,14 @@ namespace MediaBrowser.Controller.Dto
/// </summary>
/// <param name="dto">The dto.</param>
/// <param name="item">The item.</param>
- void AttachPrimaryImageAspectRatio(IItemDto dto, IHasMetadata item);
+ void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item);
/// <summary>
/// Gets the primary image aspect ratio.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.Nullable&lt;System.Double&gt;.</returns>
- double? GetPrimaryImageAspectRatio(IHasMetadata item);
+ double? GetPrimaryImageAspectRatio(BaseItem item);
/// <summary>
/// Gets the base item dto.
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 02a9f15a9..16fd75d2e 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -61,6 +61,12 @@ namespace MediaBrowser.Controller.Entities.Audio
}
[IgnoreDataMember]
+ public override bool SupportsPeople
+ {
+ get { return false; }
+ }
+
+ [IgnoreDataMember]
public override bool SupportsAddingToPlaylist
{
get { return true; }
diff --git a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs
index d2b4569ba..1b717b900 100644
--- a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs
+++ b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs
@@ -1,8 +1,9 @@
-using MediaBrowser.Model.Serialization;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities.Audio
{
- public class AudioPodcast : Audio
+ public class AudioPodcast : Audio, IHasLookupInfo<SongInfo>
{
[IgnoreDataMember]
public override bool SupportsPositionTicksResume
@@ -13,6 +14,15 @@ namespace MediaBrowser.Controller.Entities.Audio
}
}
+ [IgnoreDataMember]
+ public override bool SupportsPlayedStatus
+ {
+ get
+ {
+ return true;
+ }
+ }
+
public override double? GetDefaultPrimaryImageAspectRatio()
{
return 1;
diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs
index 1bdcfb881..374bb21f7 100644
--- a/MediaBrowser.Controller/Entities/AudioBook.cs
+++ b/MediaBrowser.Controller/Entities/AudioBook.cs
@@ -1,11 +1,12 @@
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
+ public class AudioBook : Audio.Audio, IHasSeries, IHasLookupInfo<SongInfo>
{
[IgnoreDataMember]
public override bool SupportsPositionTicksResume
@@ -50,12 +51,6 @@ namespace MediaBrowser.Controller.Entities
return null;
}
- [IgnoreDataMember]
- public override bool EnableRefreshOnDateModifiedChange
- {
- get { return true; }
- }
-
public Guid? FindSeriesId()
{
return SeriesId;
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 502ba6c60..89d48ff90 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -477,14 +477,36 @@ namespace MediaBrowser.Controller.Entities
locationType != LocationType.Virtual;
}
- public virtual bool IsAuthorizedToDelete(User user)
+ public virtual bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
{
- return user.Policy.EnableContentDeletion;
+ 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)
{
- return CanDelete() && IsAuthorizedToDelete(user);
+ var allCollectionFolders = LibraryManager.GetUserRootFolder().Children.OfType<Folder>().ToList();
+ return CanDelete(user, allCollectionFolders);
}
public virtual bool CanDownload()
@@ -1142,7 +1164,7 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
public virtual bool SupportsPeople
{
- get { return true; }
+ get { return false; }
}
[IgnoreDataMember]
@@ -1281,8 +1303,8 @@ namespace MediaBrowser.Controller.Entities
{
var subOptions = new MetadataRefreshOptions(options);
- if (!i.ExtraType.HasValue ||
- i.ExtraType.Value != Model.Entities.ExtraType.ThemeSong ||
+ if (!i.ExtraType.HasValue ||
+ i.ExtraType.Value != Model.Entities.ExtraType.ThemeSong ||
i.OwnerId != ownerId ||
i.ParentId != Guid.Empty)
{
@@ -1356,14 +1378,20 @@ namespace MediaBrowser.Controller.Entities
internal virtual bool IsValidFromResolver(BaseItem newItem)
{
- var current = this;
+ return true;
+ }
- if (current.IsInMixedFolder != newItem.IsInMixedFolder)
+ internal virtual ItemUpdateType UpdateFromResolvedItem(BaseItem newItem)
+ {
+ var updateType = ItemUpdateType.None;
+
+ if (IsInMixedFolder != newItem.IsInMixedFolder)
{
- return false;
+ IsInMixedFolder = newItem.IsInMixedFolder;
+ updateType |= ItemUpdateType.MetadataImport;
}
- return true;
+ return updateType;
}
public void AfterMetadataRefresh()
@@ -1924,6 +1952,8 @@ namespace MediaBrowser.Controller.Entities
{
existingImage.Path = image.Path;
existingImage.DateModified = image.DateModified;
+ existingImage.Width = image.Width;
+ existingImage.Height = image.Height;
}
else
@@ -1966,14 +1996,14 @@ namespace MediaBrowser.Controller.Entities
/// <param name="type">The type.</param>
/// <param name="index">The index.</param>
/// <returns>Task.</returns>
- public Task DeleteImage(ImageType type, int index)
+ public void DeleteImage(ImageType type, int index)
{
var info = GetImageInfo(type, index);
if (info == null)
{
// Nothing to do
- return Task.FromResult(true);
+ return;
}
// Remove it from the item
@@ -1984,7 +2014,7 @@ namespace MediaBrowser.Controller.Entities
FileSystem.DeleteFile(info.Path);
}
- return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
}
public void RemoveImage(ItemImageInfo image)
@@ -1997,9 +2027,9 @@ namespace MediaBrowser.Controller.Entities
ImageInfos = ImageInfos.Except(deletedImages).ToArray();
}
- public virtual Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
+ public virtual void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
- return LibraryManager.UpdateItem(this, updateReason, cancellationToken);
+ LibraryManager.UpdateItem(this, updateReason, cancellationToken);
}
/// <summary>
@@ -2209,7 +2239,7 @@ namespace MediaBrowser.Controller.Entities
return type == ImageType.Backdrop || type == ImageType.Screenshot || type == ImageType.Chapter;
}
- public Task SwapImages(ImageType type, int index1, int index2)
+ public void SwapImages(ImageType type, int index1, int index2)
{
if (!AllowsMultipleImages(type))
{
@@ -2222,13 +2252,13 @@ namespace MediaBrowser.Controller.Entities
if (info1 == null || info2 == null)
{
// Nothing to do
- return Task.FromResult(true);
+ return;
}
if (!info1.IsLocalFile || !info2.IsLocalFile)
{
// TODO: Not supported yet
- return Task.FromResult(true);
+ return;
}
var path1 = info1.Path;
@@ -2240,7 +2270,12 @@ namespace MediaBrowser.Controller.Entities
info1.DateModified = FileSystem.GetLastWriteTimeUtc(info1.Path);
info2.DateModified = FileSystem.GetLastWriteTimeUtc(info2.Path);
- return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ info1.Width = 0;
+ info1.Height = 0;
+ info2.Width = 0;
+ info2.Height = 0;
+
+ UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
}
public virtual bool IsPlayed(User user)
@@ -2526,15 +2561,6 @@ namespace MediaBrowser.Controller.Entities
return LibraryManager.DeleteItem(this, options);
}
- public virtual Task OnFileDeleted()
- {
- // Remove from database
- return Delete(new DeleteOptions
- {
- DeleteFileLocation = false
- });
- }
-
public virtual List<ExternalUrl> GetRelatedUrls()
{
return new List<ExternalUrl>();
diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs
index 9b1a52f83..45e3915ce 100644
--- a/MediaBrowser.Controller/Entities/Book.cs
+++ b/MediaBrowser.Controller/Entities/Book.cs
@@ -38,12 +38,6 @@ namespace MediaBrowser.Controller.Entities
return SeriesPresentationUniqueKey;
}
- [IgnoreDataMember]
- public override bool EnableRefreshOnDateModifiedChange
- {
- get { return true; }
- }
-
public Guid? FindSeriesId()
{
return SeriesId;
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 6d88f7015..ce7145a79 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -328,11 +328,6 @@ namespace MediaBrowser.Controller.Entities
return dictionary;
}
- private bool IsValidFromResolver(BaseItem current, BaseItem newItem)
- {
- return current.IsValidFromResolver(newItem);
- }
-
protected override void TriggerOnRefreshStart()
{
}
@@ -421,10 +416,15 @@ namespace MediaBrowser.Controller.Entities
{
BaseItem currentChild;
- if (currentChildren.TryGetValue(child.Id, out currentChild) && IsValidFromResolver(currentChild, child))
+ if (currentChildren.TryGetValue(child.Id, out currentChild) && currentChild.IsValidFromResolver(child))
{
validChildren.Add(currentChild);
+ if (currentChild.UpdateFromResolvedItem(child) > ItemUpdateType.None)
+ {
+ currentChild.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken);
+ }
+
continue;
}
@@ -542,7 +542,6 @@ namespace MediaBrowser.Controller.Entities
if (validChildrenNeedGeneration)
{
validChildren = Children.ToList();
- validChildrenNeedGeneration = false;
}
await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken);
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
index a99058925..bead0ef95 100644
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ b/MediaBrowser.Controller/Entities/Game.cs
@@ -29,15 +29,15 @@ namespace MediaBrowser.Controller.Entities
}
[IgnoreDataMember]
- public override bool EnableRefreshOnDateModifiedChange
+ public override bool SupportsThemeMedia
{
get { return true; }
}
[IgnoreDataMember]
- public override bool SupportsThemeMedia
+ public override bool SupportsPeople
{
- get { return true; }
+ get { return false; }
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/IHasMetadata.cs b/MediaBrowser.Controller/Entities/IHasMetadata.cs
index 4146686b2..b7d31b4d6 100644
--- a/MediaBrowser.Controller/Entities/IHasMetadata.cs
+++ b/MediaBrowser.Controller/Entities/IHasMetadata.cs
@@ -151,11 +151,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Swaps the images.
/// </summary>
- /// <param name="type">The type.</param>
- /// <param name="index1">The index1.</param>
- /// <param name="index2">The index2.</param>
- /// <returns>Task.</returns>
- Task SwapImages(ImageType type, int index1, int index2);
+ void SwapImages(ImageType type, int index1, int index2);
/// <summary>
/// Gets or sets the primary image path.
@@ -249,10 +245,7 @@ namespace MediaBrowser.Controller.Entities
/// <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);
+ void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken);
/// <summary>
/// Sets the image.
diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
index 6b2d2392d..bd0011c4b 100644
--- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs
+++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
@@ -24,6 +24,9 @@ namespace MediaBrowser.Controller.Entities
/// <value>The date modified.</value>
public DateTime DateModified { get; set; }
+ public int Width { get; set; }
+ public int Height { get; set; }
+
[IgnoreDataMember]
public bool IsLocalFile
{
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index bd8d9024d..268860ff0 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -45,6 +45,12 @@ namespace MediaBrowser.Controller.Entities.Movies
}
}
+ [IgnoreDataMember]
+ public override bool SupportsPeople
+ {
+ get { return true; }
+ }
+
public Guid[] LocalTrailerIds { get; set; }
public Guid[] RemoteTrailerIds { get; set; }
@@ -126,7 +132,7 @@ namespace MediaBrowser.Controller.Entities.Movies
}
}
- public override bool IsAuthorizedToDelete(User user)
+ public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
{
return true;
}
diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs
index 52d743e36..af9d8c801 100644
--- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs
+++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs
@@ -30,10 +30,5 @@ namespace MediaBrowser.Controller.Entities
return false;
}
}
-
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- return 1;
- }
}
}
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index c30e0ef8e..3f52dfc93 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -79,6 +79,12 @@ namespace MediaBrowser.Controller.Entities.TV
}
[IgnoreDataMember]
+ public override bool SupportsPeople
+ {
+ get { return true; }
+ }
+
+ [IgnoreDataMember]
public int? AiredSeasonNumber
{
get
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index bf6dc5678..00bb75fa7 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -41,6 +41,12 @@ namespace MediaBrowser.Controller.Entities.TV
}
[IgnoreDataMember]
+ public override bool SupportsPeople
+ {
+ get { return true; }
+ }
+
+ [IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 5931c32e1..1d09783d1 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -64,6 +64,12 @@ namespace MediaBrowser.Controller.Entities.TV
}
}
+ [IgnoreDataMember]
+ public override bool SupportsPeople
+ {
+ get { return true; }
+ }
+
public Guid[] LocalTrailerIds { get; set; }
public Guid[] RemoteTrailerIds { get; set; }
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index 36bbf6886..821327b7f 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -235,10 +235,9 @@ namespace MediaBrowser.Controller.Entities
}, CancellationToken.None);
}
- public override Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
+ public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
UserManager.UpdateUser(this);
- return Task.FromResult(true);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 43adc4af6..97b96127a 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -78,26 +78,26 @@ namespace MediaBrowser.Controller.Entities
case SpecialFolder.LiveTvChannels:
{
- var result = await _liveTvManager.GetInternalChannels(new LiveTvChannelQuery
+ var result = _liveTvManager.GetInternalChannels(new LiveTvChannelQuery
{
UserId = query.User.Id.ToString("N"),
Limit = query.Limit,
StartIndex = query.StartIndex
- }, new DtoOptions(), CancellationToken.None).ConfigureAwait(false);
+ }, new DtoOptions(), CancellationToken.None);
return GetResult(result);
}
case SpecialFolder.LiveTvNowPlaying:
{
- var result = await _liveTvManager.GetRecommendedProgramsInternal(new RecommendedProgramQuery
+ var result = _liveTvManager.GetRecommendedProgramsInternal(new RecommendedProgramQuery
{
UserId = query.User.Id.ToString("N"),
Limit = query.Limit,
IsAiring = true
- }, new Dto.DtoOptions(), CancellationToken.None).ConfigureAwait(false);
+ }, new Dto.DtoOptions(), CancellationToken.None);
return GetResult(result);
}
@@ -142,22 +142,22 @@ namespace MediaBrowser.Controller.Entities
return GetResult(user.RootFolder.GetChildren(user, true), queryParent, query);
case CollectionType.Playlists:
- return GetPlaylistsView(queryParent, user, query);
+ return GetPlaylistsView(queryParent, user, query);
case CollectionType.BoxSets:
return GetBoxsetView(queryParent, user, query);
case CollectionType.TvShows:
- return await GetTvView(queryParent, user, query).ConfigureAwait(false);
+ return GetTvView(queryParent, user, query);
case CollectionType.Movies:
- return await GetMovieFolders(queryParent, user, query).ConfigureAwait(false);
+ return GetMovieFolders(queryParent, user, query);
case SpecialFolder.TvShowSeries:
return GetTvSeries(queryParent, user, query);
case SpecialFolder.TvGenres:
- return await GetTvGenres(queryParent, user, query).ConfigureAwait(false);
+ return GetTvGenres(queryParent, user, query);
case SpecialFolder.TvGenre:
return GetTvGenreItems(queryParent, displayParent, user, query);
@@ -178,10 +178,10 @@ namespace MediaBrowser.Controller.Entities
return GetMovieLatest(queryParent, user, query);
case SpecialFolder.MovieGenres:
- return await GetMovieGenres(queryParent, user, query).ConfigureAwait(false);
+ return GetMovieGenres(queryParent, user, query);
case SpecialFolder.MovieGenre:
- return GetMovieGenreItems(queryParent, displayParent, user, query);
+ return GetMovieGenreItems(queryParent, displayParent, user, query);
case SpecialFolder.MovieResume:
return GetMovieResume(queryParent, user, query);
@@ -199,7 +199,7 @@ namespace MediaBrowser.Controller.Entities
return GetFavoriteSeries(queryParent, user, query);
case CollectionType.Music:
- return await GetMusicFolders(queryParent, user, query).ConfigureAwait(false);
+ return GetMusicFolders(queryParent, user, query);
case SpecialFolder.MusicGenres:
return GetMusicGenres(queryParent, user, query);
@@ -223,7 +223,7 @@ namespace MediaBrowser.Controller.Entities
return GetMusicSongs(queryParent, user, query);
case SpecialFolder.MusicFavorites:
- return await GetMusicFavorites(queryParent, user, query).ConfigureAwait(false);
+ return GetMusicFavorites(queryParent, user, query);
case SpecialFolder.MusicFavoriteAlbums:
return GetFavoriteAlbums(queryParent, user, query);
@@ -245,7 +245,7 @@ namespace MediaBrowser.Controller.Entities
}
}
- private async Task<QueryResult<BaseItem>> GetMusicFolders(Folder parent, User user, InternalItemsQuery query)
+ private QueryResult<BaseItem> GetMusicFolders(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
{
@@ -262,25 +262,25 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
- list.Add(await GetUserView(SpecialFolder.MusicLatest, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicPlaylists, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicAlbums, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, "3", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicArtists, "4", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicSongs, "5", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicGenres, "6", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicFavorites, "7", parent).ConfigureAwait(false));
+ 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 async Task<QueryResult<BaseItem>> GetMusicFavorites(Folder parent, User user, InternalItemsQuery query)
+ private QueryResult<BaseItem> GetMusicFavorites(Folder parent, User user, InternalItemsQuery query)
{
var list = new List<BaseItem>();
- list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, "2", parent).ConfigureAwait(false));
+ 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);
}
@@ -426,7 +426,7 @@ namespace MediaBrowser.Controller.Entities
return 50;
}
- private async Task<QueryResult<BaseItem>> GetMovieFolders(Folder parent, User user, InternalItemsQuery query)
+ private QueryResult<BaseItem> GetMovieFolders(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
{
@@ -443,12 +443,12 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
- list.Add(await GetUserView(SpecialFolder.MovieResume, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MovieLatest, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MovieMovies, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MovieCollections, "3", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MovieFavorites, "4", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.MovieGenres, "5", parent).ConfigureAwait(false));
+ 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);
}
@@ -538,9 +538,9 @@ namespace MediaBrowser.Controller.Entities
};
}
- private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
+ private QueryResult<BaseItem> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
{
- var tasks = parent.QueryRecursive(new InternalItemsQuery(user)
+ var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Movie).Name },
Recursive = true,
@@ -564,9 +564,7 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null)
- .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, i.SortName, parent));
-
- var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+ .Select(i => GetUserViewWithName(i.Name, SpecialFolder.MovieGenre, i.SortName, parent));
return GetResult(genres, parent, query);
}
@@ -598,7 +596,7 @@ namespace MediaBrowser.Controller.Entities
return _libraryManager.GetItemsResult(query);
}
- private async Task<QueryResult<BaseItem>> GetTvView(Folder parent, User user, InternalItemsQuery query)
+ private QueryResult<BaseItem> GetTvView(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
{
@@ -615,13 +613,13 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
- list.Add(await GetUserView(SpecialFolder.TvResume, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.TvNextUp, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.TvLatest, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.TvShowSeries, "3", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, "4", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, "5", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.TvGenres, "6", parent).ConfigureAwait(false));
+ 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);
}
@@ -679,9 +677,9 @@ namespace MediaBrowser.Controller.Entities
return _libraryManager.GetItemsResult(query);
}
- private async Task<QueryResult<BaseItem>> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
+ private QueryResult<BaseItem> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
{
- var tasks = parent.QueryRecursive(new InternalItemsQuery(user)
+ var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Series).Name },
Recursive = true,
@@ -705,9 +703,7 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null)
- .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, i.SortName, parent));
-
- var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+ .Select(i => GetUserViewWithName(i.Name, SpecialFolder.TvGenre, i.SortName, parent));
return GetResult(genres, parent, query);
}
@@ -1740,20 +1736,20 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>();
//list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.LiveTvChannels, string.Empty, user.RootFolder).ConfigureAwait(false));
- list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, string.Empty, user.RootFolder).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 Task<UserView> GetUserView(string name, string type, string sortName, BaseItem parent)
+ private UserView GetUserViewWithName(string name, string type, string sortName, BaseItem parent)
{
return _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, sortName, CancellationToken.None);
}
- private Task<UserView> GetUserView(string type, string sortName, BaseItem parent)
+ private UserView GetUserView(string type, string localizationKey, string sortName, BaseItem parent)
{
- return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None);
+ return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, localizationKey, sortName, CancellationToken.None);
}
public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, string adjacentToId)
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 8693d867c..52f1dd051 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -45,6 +45,12 @@ namespace MediaBrowser.Controller.Entities
}
[IgnoreDataMember]
+ public override bool SupportsPeople
+ {
+ get { return true; }
+ }
+
+ [IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get
@@ -78,14 +84,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- public override double? GetDefaultPrimaryImageAspectRatio()
- {
- double value = 16;
- value /= 9;
-
- return value;
- }
-
public override string CreatePresentationUniqueKey()
{
if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
@@ -406,30 +404,31 @@ namespace MediaBrowser.Controller.Entities
}
}
- internal override bool IsValidFromResolver(BaseItem newItem)
+ internal override ItemUpdateType UpdateFromResolvedItem(BaseItem newItem)
{
- var current = this;
+ var updateType = base.UpdateFromResolvedItem(newItem);
- var newAsVideo = newItem as Video;
-
- if (newAsVideo != null)
+ var newVideo = newItem as Video;
+ if (newVideo != null)
{
- if (!current.AdditionalParts.SequenceEqual(newAsVideo.AdditionalParts, StringComparer.OrdinalIgnoreCase))
+ if (!AdditionalParts.SequenceEqual(newVideo.AdditionalParts, StringComparer.Ordinal))
{
- return false;
+ AdditionalParts = newVideo.AdditionalParts;
+ updateType |= ItemUpdateType.MetadataImport;
}
- if (!current.LocalAlternateVersions.SequenceEqual(newAsVideo.LocalAlternateVersions, StringComparer.OrdinalIgnoreCase))
+ if (!LocalAlternateVersions.SequenceEqual(newVideo.LocalAlternateVersions, StringComparer.Ordinal))
{
- return false;
+ LocalAlternateVersions = newVideo.LocalAlternateVersions;
+ updateType |= ItemUpdateType.MetadataImport;
}
-
- if (newAsVideo.VideoType != VideoType)
+ if (VideoType != newVideo.VideoType)
{
- return false;
+ VideoType = newVideo.VideoType;
+ updateType |= ItemUpdateType.MetadataImport;
}
}
- return base.IsValidFromResolver(newItem);
+ return updateType;
}
public static string[] QueryPlayableStreamFiles(string rootPath, VideoType videoType)
@@ -521,9 +520,9 @@ namespace MediaBrowser.Controller.Entities
}
}
- public override async Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
+ public override void UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
- await base.UpdateToRepository(updateReason, cancellationToken).ConfigureAwait(false);
+ base.UpdateToRepository(updateReason, cancellationToken);
var localAlternates = GetLocalAlternateVersionIds()
.Select(i => LibraryManager.GetItemById(i))
@@ -540,7 +539,7 @@ namespace MediaBrowser.Controller.Entities
item.Genres = Genres;
item.ProviderIds = ProviderIds;
- await item.UpdateToRepository(ItemUpdateType.MetadataDownload, cancellationToken).ConfigureAwait(false);
+ item.UpdateToRepository(ItemUpdateType.MetadataDownload, cancellationToken);
}
}
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 3001e3366..37e0d5661 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -128,6 +128,8 @@ namespace MediaBrowser.Controller.Library
/// </summary>
void QueueLibraryScan();
+ void UpdateImages(BaseItem item);
+
/// <summary>
/// Gets the default view.
/// </summary>
@@ -207,11 +209,7 @@ namespace MediaBrowser.Controller.Library
/// <summary>
/// Updates the item.
/// </summary>
- /// <param name="item">The item.</param>
- /// <param name="updateReason">The update reason.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- Task UpdateItem(BaseItem item, ItemUpdateType updateReason, CancellationToken cancellationToken);
+ void UpdateItem(BaseItem item, ItemUpdateType updateReason, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the item.
@@ -330,8 +328,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="viewType">Type of the view.</param>
/// <param name="sortName">Name of the sort.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task&lt;UserView&gt;.</returns>
- Task<UserView> GetNamedView(string name,
+ UserView GetNamedView(string name,
string viewType,
string sortName,
CancellationToken cancellationToken);
@@ -345,8 +342,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="sortName">Name of the sort.</param>
/// <param name="uniqueId">The unique identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task&lt;UserView&gt;.</returns>
- Task<UserView> GetNamedView(string name,
+ UserView GetNamedView(string name,
string parentId,
string viewType,
string sortName,
diff --git a/MediaBrowser.Controller/Library/IUserViewManager.cs b/MediaBrowser.Controller/Library/IUserViewManager.cs
index 76182c641..baecdd748 100644
--- a/MediaBrowser.Controller/Library/IUserViewManager.cs
+++ b/MediaBrowser.Controller/Library/IUserViewManager.cs
@@ -13,9 +13,9 @@ namespace MediaBrowser.Controller.Library
{
Task<Folder[]> GetUserViews(UserViewQuery query, CancellationToken cancellationToken);
- Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken);
+ UserView GetUserSubViewWithName(string name, string parentId, string type, string sortName, CancellationToken cancellationToken);
- Task<UserView> GetUserSubView(string category, string type, string sortName, CancellationToken cancellationToken);
+ UserView GetUserSubView(string category, string type, string localizationKey, string sortName, CancellationToken cancellationToken);
List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request, DtoOptions options);
}
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index be85e115c..4934cc1ca 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -76,16 +76,6 @@ namespace MediaBrowser.Controller.LiveTv
void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders);
/// <summary>
- /// Gets the recording.
- /// </summary>
- /// <param name="id">The identifier.</param>
- /// <param name="options">The options.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="user">The user.</param>
- /// <returns>Task{RecordingInfoDto}.</returns>
- Task<BaseItemDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null);
-
- /// <summary>
/// Gets the timer.
/// </summary>
/// <param name="id">The identifier.</param>
@@ -236,14 +226,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="query">The query.</param>
/// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{QueryResult{ProgramInfoDto}}.</returns>
- Task<QueryResult<BaseItemDto>> GetRecommendedPrograms(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken);
+ QueryResult<BaseItemDto> GetRecommendedPrograms(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken);
/// <summary>
/// Gets the recommended programs internal.
/// </summary>
- /// <returns>Task&lt;QueryResult&lt;LiveTvProgram&gt;&gt;.</returns>
- Task<QueryResult<BaseItem>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken);
+ QueryResult<BaseItem> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken);
/// <summary>
/// Gets the live tv information.
@@ -264,8 +252,7 @@ namespace MediaBrowser.Controller.LiveTv
/// Gets the live tv folder.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>BaseItemDto.</returns>
- Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken);
+ Folder GetInternalLiveTvFolder(CancellationToken cancellationToken);
/// <summary>
/// Gets the live tv folder.
@@ -273,7 +260,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="userId">The user identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>BaseItemDto.</returns>
- Task<BaseItemDto> GetLiveTvFolder(string userId, CancellationToken cancellationToken);
+ BaseItemDto GetLiveTvFolder(string userId, CancellationToken cancellationToken);
/// <summary>
/// Gets the enabled users.
@@ -284,7 +271,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <summary>
/// Gets the internal channels.
/// </summary>
- Task<QueryResult<BaseItem>> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken);
+ QueryResult<BaseItem> GetInternalChannels(LiveTvChannelQuery query, DtoOptions dtoOptions, CancellationToken cancellationToken);
/// <summary>
/// Gets the internal recordings.
@@ -362,13 +349,6 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="user">The user.</param>
void AddChannelInfo(List<Tuple<BaseItemDto, LiveTvChannel>> items, DtoOptions options, User user);
- /// <summary>
- /// Called when [recording file deleted].
- /// </summary>
- /// <param name="recording">The recording.</param>
- /// <returns>Task.</returns>
- Task OnRecordingFileDeleted(BaseItem recording);
-
Task<List<ChannelInfo>> GetChannelsForListingsProvider(string id, CancellationToken cancellationToken);
Task<List<ChannelInfo>> GetChannelsFromListingsProviderData(string id, CancellationToken cancellationToken);
diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
index 2019259c5..523eec24a 100644
--- a/MediaBrowser.Controller/LiveTv/ITunerHost.cs
+++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs
@@ -59,8 +59,8 @@ namespace MediaBrowser.Controller.LiveTv
public interface ILiveStream
{
- Task Open(CancellationToken cancellationToken);
- Task Close();
+ Task Open(CancellationToken openCancellationToken);
+ void Close();
int ConsumerCount { get; }
string OriginalStreamId { get; set; }
bool EnableStreamSharing { get; set; }
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
index 8fa96076b..bd84541f8 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs
@@ -132,7 +132,7 @@ namespace MediaBrowser.Controller.LiveTv
return true;
}
- public override bool IsAuthorizedToDelete(User user)
+ public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
{
return user.Policy.EnableLiveTvManagement;
}
@@ -161,10 +161,5 @@ namespace MediaBrowser.Controller.LiveTv
{
return LiveTvManager.DeleteRecording(this);
}
-
- public override Task OnFileDeleted()
- {
- return LiveTvManager.OnRecordingFileDeleted(this);
- }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
index 4a93d0399..16010b7f5 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
@@ -136,7 +136,8 @@ namespace MediaBrowser.Controller.LiveTv
Name = Name,
Path = Path,
RunTimeTicks = RunTimeTicks,
- Type = MediaSourceType.Placeholder
+ Type = MediaSourceType.Placeholder,
+ IsInfiniteStream = RunTimeTicks == null
};
list.Add(info);
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
index 1c1637330..9dff18690 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
@@ -50,21 +50,40 @@ namespace MediaBrowser.Controller.LiveTv
public static double? GetDefaultPrimaryImageAspectRatio(IHasProgramAttributes item)
{
var serviceName = item.ServiceName;
- if (!item.IsMovie
- && !string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase)
- && !string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
+
+ if (item.IsMovie)
{
- double value = 16;
- value /= 9;
+ if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
+ {
+ double value = 2;
+ value /= 3;
+
+ return value;
+ }
+ else
+ {
+ double value = 16;
+ value /= 9;
- return value;
+ return value;
+ }
}
else
{
- double value = 2;
- value /= 3;
+ if (string.Equals(serviceName, EmbyServiceName, StringComparison.OrdinalIgnoreCase) || string.Equals(serviceName, "Next Pvr", StringComparison.OrdinalIgnoreCase))
+ {
+ double value = 2;
+ value /= 3;
- return value;
+ return value;
+ }
+ else
+ {
+ double value = 16;
+ value /= 9;
+
+ return value;
+ }
}
}
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
index c5fe7b1b3..37c1faac6 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs
@@ -131,7 +131,7 @@ namespace MediaBrowser.Controller.LiveTv
return true;
}
- public override bool IsAuthorizedToDelete(User user)
+ public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
{
return user.Policy.EnableLiveTvManagement;
}
@@ -160,10 +160,5 @@ namespace MediaBrowser.Controller.LiveTv
{
return LiveTvManager.DeleteRecording(this);
}
-
- public override Task OnFileDeleted()
- {
- return LiveTvManager.OnRecordingFileDeleted(this);
- }
}
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index b33993859..dafca0598 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -176,6 +176,7 @@
<Compile Include="MediaEncoding\MediaStreamSelector.cs" />
<Compile Include="Net\AuthenticatedAttribute.cs" />
<Compile Include="Net\AuthorizationInfo.cs" />
+ <Compile Include="Net\BasePeriodicWebSocketListener.cs" />
<Compile Include="Net\IAuthorizationContext.cs" />
<Compile Include="Net\IAuthService.cs" />
<Compile Include="Net\IHasResultFactory.cs" />
@@ -219,7 +220,6 @@
<Compile Include="Providers\IExternalId.cs" />
<Compile Include="Providers\IExtrasProvider.cs" />
<Compile Include="Providers\IForcedProvider.cs" />
- <Compile Include="Providers\IHasChangeMonitor.cs" />
<Compile Include="Entities\IHasMetadata.cs" />
<Compile Include="Providers\IHasItemChangeMonitor.cs" />
<Compile Include="Providers\IHasLookupInfo.cs" />
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 8b612f809..bddafe9a6 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -794,11 +794,6 @@ namespace MediaBrowser.Controller.MediaEncoding
return false;
}
- if (state.EnableMpDecimate)
- {
- return false;
- }
-
if (videoStream.IsInterlaced)
{
if (state.DeInterlace(videoStream.Codec, false))
@@ -1515,11 +1510,6 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
- if (state.EnableMpDecimate)
- {
- filters.Add("mpdecimate,setpts=N/FRAME_RATE/TB");
- }
-
if (filters.Count > 0)
{
output += string.Format(" -vf \"{0}\"", string.Join(",", filters.ToArray()));
@@ -1638,7 +1628,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (state.InputProtocol == MediaProtocol.Rtsp)
{
- inputModifier += " -rtsp_transport tcp";
+ inputModifier += " -rtsp_transport tcp -rtsp_transport udp -rtsp_flags prefer_tcp";
}
if (!string.IsNullOrEmpty(state.InputAudioSync))
@@ -1960,6 +1950,12 @@ namespace MediaBrowser.Controller.MediaEncoding
return "-c:v h264_mmal";
}
break;
+ case "mpeg2video":
+ if (_mediaEncoder.SupportsDecoder("mpeg2_mmal") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg2video", StringComparer.OrdinalIgnoreCase))
+ {
+ return "-c:v mpeg2_mmal";
+ }
+ break;
}
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index 506fce3ca..ad131064c 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -127,11 +127,6 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
- public bool EnableMpDecimate
- {
- get { return MediaSource.EnableMpDecimate; }
- }
-
public string AlbumCoverPath { get; set; }
public string InputAudioSync { get; set; }
diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
new file mode 100644
index 000000000..6be94e7e6
--- /dev/null
+++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
@@ -0,0 +1,326 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using MediaBrowser.Model.Threading;
+
+namespace MediaBrowser.Controller.Net
+{
+ /// <summary>
+ /// Starts sending data over a web socket periodically when a message is received, and then stops when a corresponding stop message is received
+ /// </summary>
+ /// <typeparam name="TReturnDataType">The type of the T return data type.</typeparam>
+ /// <typeparam name="TStateType">The type of the T state type.</typeparam>
+ public abstract class BasePeriodicWebSocketListener<TReturnDataType, TStateType> : IWebSocketListener, IDisposable
+ where TStateType : WebSocketListenerState, new()
+ where TReturnDataType : class
+ {
+ /// <summary>
+ /// The _active connections
+ /// </summary>
+ protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>> ActiveConnections =
+ new List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>>();
+
+ /// <summary>
+ /// Gets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ protected abstract string Name { get; }
+
+ /// <summary>
+ /// Gets the data to send.
+ /// </summary>
+ /// <param name="state">The state.</param>
+ /// <returns>Task{`1}.</returns>
+ protected abstract Task<TReturnDataType> GetDataToSend(TStateType state);
+
+ /// <summary>
+ /// The logger
+ /// </summary>
+ protected ILogger Logger;
+
+ protected ITimerFactory TimerFactory { get; private set; }
+
+ protected BasePeriodicWebSocketListener(ILogger logger, ITimerFactory timerFactory)
+ {
+ if (logger == null)
+ {
+ throw new ArgumentNullException("logger");
+ }
+
+ Logger = logger;
+ TimerFactory = timerFactory;
+ }
+
+ /// <summary>
+ /// The null task result
+ /// </summary>
+ protected Task NullTaskResult = Task.FromResult(true);
+
+ /// <summary>
+ /// Processes the message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <returns>Task.</returns>
+ public Task ProcessMessage(WebSocketMessageInfo message)
+ {
+ if (message == null)
+ {
+ throw new ArgumentNullException("message");
+ }
+
+ if (string.Equals(message.MessageType, Name + "Start", StringComparison.OrdinalIgnoreCase))
+ {
+ Start(message);
+ }
+
+ if (string.Equals(message.MessageType, Name + "Stop", StringComparison.OrdinalIgnoreCase))
+ {
+ Stop(message);
+ }
+
+ return NullTaskResult;
+ }
+
+ protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ protected virtual bool SendOnTimer
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ protected virtual void ParseMessageParams(string[] values)
+ {
+
+ }
+
+ /// <summary>
+ /// Starts sending messages over a web socket
+ /// </summary>
+ /// <param name="message">The message.</param>
+ private void Start(WebSocketMessageInfo message)
+ {
+ var vals = message.Data.Split(',');
+
+ var dueTimeMs = long.Parse(vals[0], UsCulture);
+ var periodMs = long.Parse(vals[1], UsCulture);
+
+ if (vals.Length > 2)
+ {
+ ParseMessageParams(vals.Skip(2).ToArray());
+ }
+
+ var cancellationTokenSource = new CancellationTokenSource();
+
+ Logger.Debug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name);
+
+ var timer = SendOnTimer ?
+ TimerFactory.Create(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) :
+ null;
+
+ var state = new TStateType
+ {
+ IntervalMs = periodMs,
+ InitialDelayMs = dueTimeMs
+ };
+
+ lock (ActiveConnections)
+ {
+ ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>(message.Connection, cancellationTokenSource, timer, state));
+ }
+
+ if (timer != null)
+ {
+ timer.Change(TimeSpan.FromMilliseconds(dueTimeMs), TimeSpan.FromMilliseconds(periodMs));
+ }
+ }
+
+ /// <summary>
+ /// Timers the callback.
+ /// </summary>
+ /// <param name="state">The state.</param>
+ private void TimerCallback(object state)
+ {
+ var connection = (IWebSocketConnection)state;
+
+ Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> tuple;
+
+ lock (ActiveConnections)
+ {
+ tuple = ActiveConnections.FirstOrDefault(c => c.Item1 == connection);
+ }
+
+ if (tuple == null)
+ {
+ return;
+ }
+
+ if (connection.State != WebSocketState.Open || tuple.Item2.IsCancellationRequested)
+ {
+ DisposeConnection(tuple);
+ return;
+ }
+
+ SendData(tuple);
+ }
+
+ protected void SendData(bool force)
+ {
+ List<Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType>> tuples;
+
+ lock (ActiveConnections)
+ {
+ tuples = ActiveConnections
+ .Where(c =>
+ {
+ if (c.Item1.State == WebSocketState.Open && !c.Item2.IsCancellationRequested)
+ {
+ var state = c.Item4;
+
+ if (force || (DateTime.UtcNow - state.DateLastSendUtc).TotalMilliseconds >= state.IntervalMs)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ })
+ .ToList();
+ }
+
+ foreach (var tuple in tuples)
+ {
+ SendData(tuple);
+ }
+ }
+
+ private async void SendData(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> tuple)
+ {
+ var connection = tuple.Item1;
+
+ try
+ {
+ var state = tuple.Item4;
+
+ var data = await GetDataToSend(state).ConfigureAwait(false);
+
+ if (data != null)
+ {
+ await connection.SendAsync(new WebSocketMessage<TReturnDataType>
+ {
+ MessageType = Name,
+ Data = data
+
+ }, tuple.Item2.Token).ConfigureAwait(false);
+
+ state.DateLastSendUtc = DateTime.UtcNow;
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ if (tuple.Item2.IsCancellationRequested)
+ {
+ DisposeConnection(tuple);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error sending web socket message {0}", ex, Name);
+ DisposeConnection(tuple);
+ }
+ }
+
+ /// <summary>
+ /// Stops sending messages over a web socket
+ /// </summary>
+ /// <param name="message">The message.</param>
+ private void Stop(WebSocketMessageInfo message)
+ {
+ lock (ActiveConnections)
+ {
+ var connection = ActiveConnections.FirstOrDefault(c => c.Item1 == message.Connection);
+
+ if (connection != null)
+ {
+ DisposeConnection(connection);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Disposes the connection.
+ /// </summary>
+ /// <param name="connection">The connection.</param>
+ private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, ITimer, TStateType> connection)
+ {
+ Logger.Debug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name);
+
+ var timer = connection.Item3;
+
+ if (timer != null)
+ {
+ try
+ {
+ timer.Dispose();
+ }
+ catch (ObjectDisposedException)
+ {
+
+ }
+ }
+
+ try
+ {
+ connection.Item2.Cancel();
+ connection.Item2.Dispose();
+ }
+ catch (ObjectDisposedException)
+ {
+
+ }
+
+ ActiveConnections.Remove(connection);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool dispose)
+ {
+ if (dispose)
+ {
+ lock (ActiveConnections)
+ {
+ foreach (var connection in ActiveConnections.ToList())
+ {
+ DisposeConnection(connection);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ public class WebSocketListenerState
+ {
+ public DateTime DateLastSendUtc { get; set; }
+ public long InitialDelayMs { get; set; }
+ public long IntervalMs { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Notifications/INotificationManager.cs b/MediaBrowser.Controller/Notifications/INotificationManager.cs
index f9d264314..68cfd6ff1 100644
--- a/MediaBrowser.Controller/Notifications/INotificationManager.cs
+++ b/MediaBrowser.Controller/Notifications/INotificationManager.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Notifications
{
@@ -15,6 +16,8 @@ namespace MediaBrowser.Controller.Notifications
/// <returns>Task.</returns>
Task SendNotification(NotificationRequest request, CancellationToken cancellationToken);
+ Task SendNotification(NotificationRequest request, BaseItem relatedItem, CancellationToken cancellationToken);
+
/// <summary>
/// Adds the parts.
/// </summary>
diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs
index 3d05d2fca..4cb3e2bb6 100644
--- a/MediaBrowser.Controller/Persistence/IItemRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs
@@ -48,6 +48,8 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="cancellationToken">The cancellation token.</param>
void SaveItems(List<BaseItem> items, CancellationToken cancellationToken);
+ void SaveImages(BaseItem item);
+
/// <summary>
/// Retrieves the item.
/// </summary>
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index ee96a8c3b..071f8a096 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -73,7 +73,7 @@ namespace MediaBrowser.Controller.Playlists
return 1;
}
- public override bool IsAuthorizedToDelete(User user)
+ public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
{
return true;
}
diff --git a/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs b/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs
deleted file mode 100644
index aa0b0e3c9..000000000
--- a/MediaBrowser.Controller/Providers/IHasChangeMonitor.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using MediaBrowser.Controller.Entities;
-using System;
-
-namespace MediaBrowser.Controller.Providers
-{
- public interface IHasChangeMonitor
- {
- /// <summary>
- /// Determines whether the specified item has changed.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="directoryService">The directory service.</param>
- /// <param name="date">The date.</param>
- /// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns>
- bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date);
- }
-}
diff --git a/MediaBrowser.Controller/Providers/IMetadataService.cs b/MediaBrowser.Controller/Providers/IMetadataService.cs
index 2d4873f7e..7b7bf166b 100644
--- a/MediaBrowser.Controller/Providers/IMetadataService.cs
+++ b/MediaBrowser.Controller/Providers/IMetadataService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Entities;
+using System;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using System.Threading;
using System.Threading.Tasks;
@@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Providers
/// <param name="item">The item.</param>
/// <returns><c>true</c> if this instance can refresh the specified item; otherwise, <c>false</c>.</returns>
bool CanRefresh(IHasMetadata item);
+ bool CanRefreshPrimary(Type type);
/// <summary>
/// Refreshes the metadata.
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 77e6a7e40..c2cbda11d 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -119,16 +119,12 @@ namespace MediaBrowser.Controller.Providers
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns>Task.</returns>
- Task SaveMetadata(IHasMetadata item, ItemUpdateType updateType);
+ void SaveMetadata(IHasMetadata item, ItemUpdateType updateType);
/// <summary>
/// Saves the metadata.
/// </summary>
- /// <param name="item">The item.</param>
- /// <param name="updateType">Type of the update.</param>
- /// <param name="savers">The savers.</param>
- /// <returns>Task.</returns>
- Task SaveMetadata(IHasMetadata item, ItemUpdateType updateType, IEnumerable<string> savers);
+ void SaveMetadata(IHasMetadata item, ItemUpdateType updateType, IEnumerable<string> savers);
/// <summary>
/// Gets the metadata options.
diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs
index 5ed55ea16..f35d41ca4 100644
--- a/MediaBrowser.Controller/Providers/MetadataResult.cs
+++ b/MediaBrowser.Controller/Providers/MetadataResult.cs
@@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.Providers
public bool HasMetadata { get; set; }
public T Item { get; set; }
public string ResultLanguage { get; set; }
+ public string Provider { get; set; }
public bool QueriedById { get; set; }
public void AddPerson(PersonInfo p)
{
diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs
index 910d697ec..0bf4b914f 100644
--- a/MediaBrowser.Controller/Sync/ISyncManager.cs
+++ b/MediaBrowser.Controller/Sync/ISyncManager.cs
@@ -91,8 +91,6 @@ namespace MediaBrowser.Controller.Sync
/// </summary>
List<SyncTarget> GetSyncTargets(string userId);
- List<SyncTarget> GetSyncTargets(string userId, bool? supportsRemoteSync);
-
/// <summary>
/// Supportses the synchronize.
/// </summary>
diff --git a/MediaBrowser.Controller/Sync/ISyncProvider.cs b/MediaBrowser.Controller/Sync/ISyncProvider.cs
index 2f60e124e..baee1a52f 100644
--- a/MediaBrowser.Controller/Sync/ISyncProvider.cs
+++ b/MediaBrowser.Controller/Sync/ISyncProvider.cs
@@ -11,8 +11,6 @@ namespace MediaBrowser.Controller.Sync
/// <value>The name.</value>
string Name { get; }
- bool SupportsRemoteSync { get; }
-
/// <summary>
/// Gets the synchronize targets.
/// </summary>