diff options
Diffstat (limited to 'MediaBrowser.Controller')
107 files changed, 878 insertions, 2889 deletions
diff --git a/MediaBrowser.Controller/Activity/IActivityManager.cs b/MediaBrowser.Controller/Activity/IActivityManager.cs deleted file mode 100644 index 7285489112..0000000000 --- a/MediaBrowser.Controller/Activity/IActivityManager.cs +++ /dev/null @@ -1,17 +0,0 @@ -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Querying; -using System; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Activity -{ - public interface IActivityManager - { - event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated; - - Task Create(ActivityLogEntry entry); - - QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit); - } -} diff --git a/MediaBrowser.Controller/Activity/IActivityRepository.cs b/MediaBrowser.Controller/Activity/IActivityRepository.cs deleted file mode 100644 index 7ccbc2e99b..0000000000 --- a/MediaBrowser.Controller/Activity/IActivityRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Querying; -using System; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Activity -{ - public interface IActivityRepository - { - Task Create(ActivityLogEntry entry); - - QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit); - } -} diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index e0b7204b87..a2590dec72 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -3,7 +3,7 @@ using MediaBrowser.Model.Channels; using MediaBrowser.Model.Querying; using System; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Controller/Dlna/ControlRequest.cs b/MediaBrowser.Controller/Dlna/ControlRequest.cs index 7020cc0d9f..ff951ec9eb 100644 --- a/MediaBrowser.Controller/Dlna/ControlRequest.cs +++ b/MediaBrowser.Controller/Dlna/ControlRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; namespace MediaBrowser.Controller.Dlna { @@ -6,7 +7,7 @@ namespace MediaBrowser.Controller.Dlna { public IDictionary<string, string> Headers { get; set; } - public string InputXml { get; set; } + public Stream InputXml { get; set; } public string TargetServerUuId { get; set; } diff --git a/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs b/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs deleted file mode 100644 index d2c5b9e4e8..0000000000 --- a/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using MediaBrowser.Model.Events; - -namespace MediaBrowser.Controller.Dlna -{ - public interface IDeviceDiscovery - { - event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered; - event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft; - } - - public class UpnpDeviceInfo - { - public Uri Location { get; set; } - public Dictionary<string, string> Headers { get; set; } - public IPEndPoint LocalEndPoint { get; set; } - } -} diff --git a/MediaBrowser.Controller/Dlna/SsdpMessageEventArgs.cs b/MediaBrowser.Controller/Dlna/SsdpMessageEventArgs.cs deleted file mode 100644 index 804f34311a..0000000000 --- a/MediaBrowser.Controller/Dlna/SsdpMessageEventArgs.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; - -namespace MediaBrowser.Controller.Dlna -{ - public class SsdpMessageEventArgs - { - public string Method { get; set; } - - public EndPoint EndPoint { get; set; } - - public Dictionary<string, string> Headers { get; set; } - - public IPEndPoint LocalEndPoint { get; set; } - public byte[] Message { get; set; } - - public SsdpMessageEventArgs() - { - Headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - } - } -} diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs new file mode 100644 index 0000000000..de1909e542 --- /dev/null +++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs @@ -0,0 +1,60 @@ +using System; +using MediaBrowser.Model.Drawing; + +namespace MediaBrowser.Controller.Drawing +{ + public interface IImageEncoder : IDisposable + { + /// <summary> + /// Gets the supported input formats. + /// </summary> + /// <value>The supported input formats.</value> + string[] SupportedInputFormats { get; } + /// <summary> + /// Gets the supported output formats. + /// </summary> + /// <value>The supported output formats.</value> + ImageFormat[] SupportedOutputFormats { get; } + /// <summary> + /// Crops the white space. + /// </summary> + /// <param name="inputPath">The input path.</param> + /// <param name="outputPath">The output path.</param> + void CropWhiteSpace(string inputPath, string outputPath); + /// <summary> + /// Encodes the image. + /// </summary> + /// <param name="inputPath">The input path.</param> + /// <param name="outputPath">The output path.</param> + /// <param name="autoOrient">if set to <c>true</c> [automatic orient].</param> + /// <param name="width">The width.</param> + /// <param name="height">The height.</param> + /// <param name="quality">The quality.</param> + /// <param name="options">The options.</param> + /// <param name="outputFormat">The output format.</param> + void EncodeImage(string inputPath, string outputPath, bool autoOrient, int width, int height, int quality, ImageProcessingOptions options, ImageFormat outputFormat); + + /// <summary> + /// Creates the image collage. + /// </summary> + /// <param name="options">The options.</param> + void CreateImageCollage(ImageCollageOptions options); + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + + /// <summary> + /// Gets a value indicating whether [supports image collage creation]. + /// </summary> + /// <value><c>true</c> if [supports image collage creation]; otherwise, <c>false</c>.</value> + bool SupportsImageCollageCreation { get; } + + /// <summary> + /// Gets a value indicating whether [supports image encoding]. + /// </summary> + /// <value><c>true</c> if [supports image encoding]; otherwise, <c>false</c>.</value> + bool SupportsImageEncoding { get; } + } +} diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs index 3fd8d84dd5..f4b3d94554 100644 --- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -35,6 +35,7 @@ namespace MediaBrowser.Controller.Drawing public bool AddPlayedIndicator { get; set; } public int? UnplayedCount { get; set; } + public int? Blur { get; set; } public double PercentPlayed { get; set; } @@ -84,6 +85,7 @@ namespace MediaBrowser.Controller.Drawing !AddPlayedIndicator && PercentPlayed.Equals(0) && !UnplayedCount.HasValue && + !Blur.HasValue && string.IsNullOrEmpty(BackgroundColor) && string.IsNullOrEmpty(ForegroundLayer); } diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 7b769deb3e..a6b9d860a0 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -4,11 +4,12 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 56c3248f33..e4f638cb6f 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -7,10 +7,10 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Channels; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities.Audio { @@ -22,14 +22,10 @@ namespace MediaBrowser.Controller.Entities.Audio IHasArtist, IHasMusicGenres, IHasLookupInfo<SongInfo>, - IHasMediaSources, - IThemeMedia + IHasMediaSources { public List<ChannelMediaInfo> ChannelMediaSources { get; set; } - public int? TotalBitrate { get; set; } - public ExtraType? ExtraType { get; set; } - /// <summary> /// Gets or sets the artist. /// </summary> @@ -39,15 +35,6 @@ namespace MediaBrowser.Controller.Entities.Audio public List<string> AlbumArtists { get; set; } [IgnoreDataMember] - public bool IsThemeMedia - { - get - { - return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeSong; - } - } - - [IgnoreDataMember] public override bool EnableRefreshOnDateModifiedChange { get { return true; } @@ -75,6 +62,12 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get { return true; } + } + + [IgnoreDataMember] protected override bool SupportsOwnedItems { get diff --git a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs index 9072e10947..8c820d3677 100644 --- a/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs +++ b/MediaBrowser.Controller/Entities/Audio/AudioPodcast.cs @@ -1,6 +1,16 @@ -namespace MediaBrowser.Controller.Entities.Audio +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Controller.Entities.Audio { public class AudioPodcast : Audio { + [IgnoreDataMember] + public override bool SupportsPositionTicksResume + { + get + { + return true; + } + } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 3f457d89a9..ffdbba6f2e 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -5,7 +5,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Users; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Library; @@ -33,6 +33,12 @@ namespace MediaBrowser.Controller.Entities.Audio } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get { return true; } + } + + [IgnoreDataMember] public MusicArtist MusicArtist { get diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index a31f04fc4f..fd20f2ab44 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -6,10 +6,12 @@ using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities.Audio { diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index bd991d9f47..d75b31f6ae 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities.Audio { @@ -29,6 +31,15 @@ namespace MediaBrowser.Controller.Entities.Audio get { return true; } } + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } + /// <summary> /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself diff --git a/MediaBrowser.Controller/Entities/AudioBook.cs b/MediaBrowser.Controller/Entities/AudioBook.cs new file mode 100644 index 0000000000..efeb9b497d --- /dev/null +++ b/MediaBrowser.Controller/Entities/AudioBook.cs @@ -0,0 +1,64 @@ +using System; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Controller.Entities +{ + public class AudioBook : Audio.Audio, IHasSeries + { + [IgnoreDataMember] + public override bool SupportsPositionTicksResume + { + get + { + return true; + } + } + + [IgnoreDataMember] + public string SeriesPresentationUniqueKey { get; set; } + [IgnoreDataMember] + public string SeriesName { get; set; } + [IgnoreDataMember] + public Guid? SeriesId { get; set; } + [IgnoreDataMember] + public string SeriesSortName { get; set; } + + public string FindSeriesSortName() + { + return SeriesSortName; + } + public string FindSeriesName() + { + return SeriesName; + } + public string FindSeriesPresentationUniqueKey() + { + return SeriesPresentationUniqueKey; + } + + [IgnoreDataMember] + public override bool EnableRefreshOnDateModifiedChange + { + get { return true; } + } + + public Guid? FindSeriesId() + { + return SeriesId; + } + + public override bool CanDownload() + { + var locationType = LocationType; + return locationType != LocationType.Remote && + locationType != LocationType.Virtual; + } + + public override UnratedItem GetBlockUnratedType() + { + return UnratedItem.Book; + } + } +} diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index e1a7741c94..2aa53d6515 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -5,7 +5,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; @@ -19,14 +18,20 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Runtime.Serialization; using System.Text; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.IO; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { @@ -138,6 +143,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public virtual bool SupportsPositionTicksResume + { + get + { + return false; + } + } + public bool DetectIsInMixedFolder() { if (SupportsIsInMixedFolderDetection) @@ -199,6 +213,19 @@ namespace MediaBrowser.Controller.Entities get { return PremiereDate.HasValue && PremiereDate.Value.ToLocalTime().Date >= DateTime.Now.Date; } } + public int? TotalBitrate { get; set; } + public ExtraType? ExtraType { get; set; } + + [IgnoreDataMember] + public bool IsThemeMedia + { + get + { + return ExtraType.HasValue && (ExtraType.Value == Model.Entities.ExtraType.ThemeSong || ExtraType.Value == Model.Entities.ExtraType.ThemeVideo); + } + } + + [IgnoreDataMember] public string OriginalTitle { get; set; } /// <summary> @@ -279,28 +306,11 @@ namespace MediaBrowser.Controller.Entities /// If this content came from an external service, the id of the content on that service /// </summary> [IgnoreDataMember] - public string ExternalId - { - get { return this.GetProviderId("ProviderExternalId"); } - set - { - this.SetProviderId("ProviderExternalId", value); - } - } + public string ExternalId { get; set; } [IgnoreDataMember] public string ExternalSeriesId { get; set; } - [IgnoreDataMember] - public string ExternalSeriesIdLegacy - { - get { return this.GetProviderId("ProviderExternalSeriesId"); } - set - { - this.SetProviderId("ProviderExternalSeriesId", value); - } - } - /// <summary> /// Gets or sets the etag. /// </summary> @@ -1031,7 +1041,7 @@ namespace MediaBrowser.Controller.Entities audio = dbItem; } - audio.ExtraType = ExtraType.ThemeSong; + audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong; return audio; @@ -1061,7 +1071,7 @@ namespace MediaBrowser.Controller.Entities item = dbItem; } - item.ExtraType = ExtraType.ThemeVideo; + item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo; return item; @@ -1211,7 +1221,7 @@ namespace MediaBrowser.Controller.Entities if (!i.IsThemeMedia) { - i.ExtraType = ExtraType.ThemeVideo; + i.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo; subOptions.ForceSave = true; } @@ -1241,7 +1251,7 @@ namespace MediaBrowser.Controller.Entities if (!i.IsThemeMedia) { - i.ExtraType = ExtraType.ThemeSong; + i.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong; subOptions.ForceSave = true; } @@ -1569,6 +1579,12 @@ namespace MediaBrowser.Controller.Entities return IsVisibleStandaloneInternal(user, true); } + [IgnoreDataMember] + public virtual bool SupportsInheritedParentImages + { + get { return false; } + } + protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) { if (!IsVisible(user)) @@ -1875,19 +1891,7 @@ namespace MediaBrowser.Controller.Entities if (info.IsLocalFile) { - // Delete the source file - var currentFile = new FileInfo(info.Path); - - // Deletion will fail if the file is hidden so remove the attribute first - if (currentFile.Exists) - { - if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) - { - currentFile.Attributes &= ~FileAttributes.Hidden; - } - - FileSystem.DeleteFile(currentFile.FullName); - } + FileSystem.DeleteFile(info.Path); } return UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None); @@ -2146,7 +2150,7 @@ namespace MediaBrowser.Controller.Entities { MetadataCountryCode = GetPreferredMetadataCountryCode(), MetadataLanguage = GetPreferredMetadataLanguage(), - Name = Name, + Name = GetNameForMetadataLookup(), ProviderIds = ProviderIds, IndexNumber = IndexNumber, ParentIndexNumber = ParentIndexNumber, @@ -2155,6 +2159,11 @@ namespace MediaBrowser.Controller.Entities }; } + protected virtual string GetNameForMetadataLookup() + { + return Name; + } + /// <summary> /// This is called before any metadata refresh and returns true or false indicating if changes were made /// </summary> @@ -2183,7 +2192,7 @@ namespace MediaBrowser.Controller.Entities return path; } - public virtual Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user) + public virtual Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> itemFields) { if (RunTimeTicks.HasValue) { @@ -2336,17 +2345,25 @@ namespace MediaBrowser.Controller.Entities { get { - if (GetParent() is AggregateFolder || this is BasePluginFolder || this is Channel) + if (this is BasePluginFolder || this is Channel) { return true; } var view = this as UserView; - if (view != null && string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + if (view != null) { - return true; + if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + if (string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase)) + { + return true; + } } - if (view != null && string.Equals(view.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase)) + + if (GetParent() is AggregateFolder) { return true; } diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs index bd109af7a7..7dbea317c8 100644 --- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs +++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs @@ -1,5 +1,5 @@ -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index 56f9fa784a..a6da389f05 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -2,7 +2,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Entities @@ -19,6 +19,8 @@ namespace MediaBrowser.Controller.Entities } [IgnoreDataMember] + public string SeriesPresentationUniqueKey { get; set; } + [IgnoreDataMember] public string SeriesName { get; set; } [IgnoreDataMember] public Guid? SeriesId { get; set; } @@ -33,6 +35,10 @@ namespace MediaBrowser.Controller.Entities { return SeriesName; } + public string FindSeriesPresentationUniqueKey() + { + return SeriesPresentationUniqueKey; + } [IgnoreDataMember] public override bool EnableRefreshOnDateModifiedChange diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 41e277b7ca..681f16f07c 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -5,14 +5,14 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; -using MoreLinq; namespace MediaBrowser.Controller.Entities { @@ -27,6 +27,7 @@ namespace MediaBrowser.Controller.Entities public CollectionFolder() { PhysicalLocationsList = new List<string>(); + PhysicalFolderIds = new List<Guid>(); } [IgnoreDataMember] @@ -77,7 +78,7 @@ namespace MediaBrowser.Controller.Entities { return new LibraryOptions(); } - catch (DirectoryNotFoundException) + catch (IOException) { return new LibraryOptions(); } @@ -153,6 +154,7 @@ namespace MediaBrowser.Controller.Entities } public List<string> PhysicalLocationsList { get; set; } + public List<Guid> PhysicalFolderIds { get; set; } protected override IEnumerable<FileSystemMetadata> GetFileSystemChildren(IDirectoryService directoryService) { @@ -176,6 +178,18 @@ namespace MediaBrowser.Controller.Entities } } + if (!changed) + { + var folderIds = PhysicalFolderIds.ToList(); + + var newFolderIds = GetPhysicalFolders(false).Select(i => i.Id).ToList(); + + if (!folderIds.SequenceEqual(newFolderIds)) + { + changed = true; + } + } + return changed; } @@ -186,6 +200,39 @@ namespace MediaBrowser.Controller.Entities return changed; } + protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren) + { + return RefreshLinkedChildrenInternal(true); + } + + private bool RefreshLinkedChildrenInternal(bool setFolders) + { + var physicalFolders = GetPhysicalFolders(false) + .ToList(); + + var linkedChildren = physicalFolders + .SelectMany(c => c.LinkedChildren) + .ToList(); + + var changed = !linkedChildren.SequenceEqual(LinkedChildren, new LinkedChildComparer()); + + LinkedChildren = linkedChildren; + + var folderIds = PhysicalFolderIds.ToList(); + var newFolderIds = physicalFolders.Select(i => i.Id).ToList(); + + if (!folderIds.SequenceEqual(newFolderIds)) + { + changed = true; + if (setFolders) + { + PhysicalFolderIds = newFolderIds.ToList(); + } + } + + return changed; + } + internal override bool IsValidFromResolver(BaseItem newItem) { var newCollectionFolder = newItem as CollectionFolder; @@ -263,25 +310,6 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Our children are actually just references to the ones in the physical root... /// </summary> - /// <value>The linked children.</value> - public override List<LinkedChild> LinkedChildren - { - get { return GetLinkedChildrenInternal(); } - set - { - base.LinkedChildren = value; - } - } - private List<LinkedChild> GetLinkedChildrenInternal() - { - return GetPhysicalParents() - .SelectMany(c => c.LinkedChildren) - .ToList(); - } - - /// <summary> - /// Our children are actually just references to the ones in the physical root... - /// </summary> /// <value>The actual children.</value> [IgnoreDataMember] protected override IEnumerable<BaseItem> ActualChildren @@ -291,11 +319,16 @@ namespace MediaBrowser.Controller.Entities private IEnumerable<BaseItem> GetActualChildren() { - return GetPhysicalParents().SelectMany(c => c.Children); + return GetPhysicalFolders(true).SelectMany(c => c.Children); } - public IEnumerable<Folder> GetPhysicalParents() + private IEnumerable<Folder> GetPhysicalFolders(bool enableCache) { + if (enableCache) + { + return PhysicalFolderIds.Select(i => LibraryManager.GetItemById(i)).OfType<Folder>(); + } + var rootChildren = LibraryManager.RootFolder.Children .OfType<Folder>() .ToList(); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index cc71ab43e3..943c9d8822 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -8,14 +8,16 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Channels; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { @@ -101,6 +103,16 @@ namespace MediaBrowser.Controller.Entities } } + public override bool CanDelete() + { + if (IsRoot) + { + return false; + } + + return base.CanDelete(); + } + public override bool RequiresRefresh() { var baseResult = base.RequiresRefresh(); @@ -679,6 +691,19 @@ namespace MediaBrowser.Controller.Entities return result.TotalRecordCount; } + public virtual int GetRecursiveChildCount(User user) + { + return GetItems(new InternalItemsQuery(user) + { + Recursive = true, + IsFolder = false, + IsVirtualItem = false, + EnableTotalRecordCount = true, + Limit = 0 + + }).Result.TotalRecordCount; + } + public QueryResult<BaseItem> QueryRecursive(InternalItemsQuery query) { var user = query.User; @@ -1207,7 +1232,7 @@ namespace MediaBrowser.Controller.Entities /// Refreshes the linked children. /// </summary> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren) + protected virtual bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren) { var currentManualLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Manual).ToList(); var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList(); @@ -1217,7 +1242,7 @@ namespace MediaBrowser.Controller.Entities if (SupportsShortcutChildren) { newShortcutLinks = fileSystemChildren - .Where(i => (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory && FileSystem.IsShortcut(i.FullName)) + .Where(i => !i.IsDirectory && FileSystem.IsShortcut(i.FullName)) .Select(i => { try @@ -1381,60 +1406,64 @@ namespace MediaBrowser.Controller.Entities { return false; } + var iItemByName = this as IItemByName; + if (iItemByName != null) + { + var hasDualAccess = this as IHasDualAccess; + if (hasDualAccess == null || hasDualAccess.IsAccessedByName) + { + return false; + } + } return true; } } - public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user) + public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> itemFields) { if (!SupportsUserDataFromChildren) { return; } - var unplayedQueryResult = await GetItems(new InternalItemsQuery(user) + if (itemDto != null) { - Recursive = true, - IsFolder = false, - IsVirtualItem = false, - EnableTotalRecordCount = true, - Limit = 0, - IsPlayed = false - - }).ConfigureAwait(false); + if (itemFields.Contains(ItemFields.RecursiveItemCount)) + { + itemDto.RecursiveItemCount = GetRecursiveChildCount(user); + } + } - var allItemsQueryResult = await GetItems(new InternalItemsQuery(user) + if (SupportsPlayedStatus) { - Recursive = true, - IsFolder = false, - IsVirtualItem = false, - EnableTotalRecordCount = true, - Limit = 0 - - }).ConfigureAwait(false); + var unplayedQueryResult = await GetItems(new InternalItemsQuery(user) + { + Recursive = true, + IsFolder = false, + IsVirtualItem = false, + EnableTotalRecordCount = true, + Limit = 0, + IsPlayed = false - if (itemDto != null) - { - itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount; - } + }).ConfigureAwait(false); - var recursiveItemCount = allItemsQueryResult.TotalRecordCount; - double unplayedCount = unplayedQueryResult.TotalRecordCount; + double unplayedCount = unplayedQueryResult.TotalRecordCount; - if (recursiveItemCount > 0) - { - var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100; - dto.PlayedPercentage = 100 - unplayedPercentage; - dto.Played = dto.PlayedPercentage.Value >= 100; dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount; - } - if (itemDto != null) - { - if (this is Season || this is MusicAlbum) + if (itemDto != null && itemDto.RecursiveItemCount.HasValue) + { + if (itemDto.RecursiveItemCount.Value > 0) + { + var unplayedPercentage = (unplayedCount/itemDto.RecursiveItemCount.Value)*100; + dto.PlayedPercentage = 100 - unplayedPercentage; + dto.Played = dto.PlayedPercentage.Value >= 100; + } + } + else { - itemDto.ChildCount = recursiveItemCount; + dto.Played = (dto.UnplayedItemCount ?? 0) == 0; } } } diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index aa2ccf4bc0..8bfb8be99d 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -4,7 +4,7 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 6448828fb3..22a8675c5e 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { @@ -35,6 +37,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } + /// <summary> /// Gets a value indicating whether this instance is owned item. /// </summary> diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index 9e00ab260d..d8879155af 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -1,4 +1,4 @@ -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using System; diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index 1736ba8c76..da4ee352fa 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -1,9 +1,11 @@ -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Controller.Entities.Audio; using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { @@ -38,6 +40,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } + public override bool IsSaveLocalMetadataEnabled() { return true; diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs index 1ab0566e0e..888e2080de 100644 --- a/MediaBrowser.Controller/Entities/IHasImages.cs +++ b/MediaBrowser.Controller/Entities/IHasImages.cs @@ -3,8 +3,10 @@ using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/IHasOriginalTitle.cs b/MediaBrowser.Controller/Entities/IHasOriginalTitle.cs deleted file mode 100644 index 6f5cb59bc0..0000000000 --- a/MediaBrowser.Controller/Entities/IHasOriginalTitle.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace MediaBrowser.Controller.Entities -{ - public interface IHasOriginalTitle - { - string OriginalTitle { get; set; } - } -} diff --git a/MediaBrowser.Controller/Entities/IHasSeries.cs b/MediaBrowser.Controller/Entities/IHasSeries.cs index 531f587881..203be93e88 100644 --- a/MediaBrowser.Controller/Entities/IHasSeries.cs +++ b/MediaBrowser.Controller/Entities/IHasSeries.cs @@ -15,5 +15,7 @@ namespace MediaBrowser.Controller.Entities string FindSeriesSortName(); Guid? SeriesId { get; set; } Guid? FindSeriesId(); + string SeriesPresentationUniqueKey { get; set; } + string FindSeriesPresentationUniqueKey(); } } diff --git a/MediaBrowser.Controller/Entities/IHasUserData.cs b/MediaBrowser.Controller/Entities/IHasUserData.cs index c21e170ae7..0b3b7dc8d9 100644 --- a/MediaBrowser.Controller/Entities/IHasUserData.cs +++ b/MediaBrowser.Controller/Entities/IHasUserData.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Entities { @@ -14,10 +15,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Fills the user data dto values. /// </summary> - /// <param name="dto">The dto.</param> - /// <param name="userData">The user data.</param> - /// <param name="user">The user.</param> - Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user); + Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> fields); bool EnableRememberingTrackSelections { get; } diff --git a/MediaBrowser.Controller/Entities/IThemeMedia.cs b/MediaBrowser.Controller/Entities/IThemeMedia.cs deleted file mode 100644 index b2eff230ff..0000000000 --- a/MediaBrowser.Controller/Entities/IThemeMedia.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace MediaBrowser.Controller.Entities -{ - public interface IThemeMedia - { - bool IsThemeMedia { get; } - } -} diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 3fb118a9cf..a2d278a71c 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -123,9 +123,7 @@ namespace MediaBrowser.Controller.Entities public int? MinParentalRating { get; set; } public int? MaxParentalRating { get; set; } - public bool? IsCurrentSchema { get; set; } public bool? HasDeadParentId { get; set; } - public bool? IsOffline { get; set; } public bool? IsVirtualItem { get; set; } public Guid? ParentId { get; set; } @@ -143,11 +141,13 @@ namespace MediaBrowser.Controller.Entities public SeriesStatus[] SeriesStatuses { get; set; } public string AlbumArtistStartsWithOrGreater { get; set; } public string ExternalSeriesId { get; set; } + public string ExternalId { get; set; } public string[] AlbumNames { get; set; } public string[] ArtistNames { get; set; } public string[] ExcludeArtistIds { get; set; } public string AncestorWithPresentationUniqueKey { get; set; } + public string SeriesPresentationUniqueKey { get; set; } public bool GroupByPresentationUniqueKey { get; set; } public bool EnableTotalRecordCount { get; set; } diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs index aa3917c15f..672595db84 100644 --- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs +++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs @@ -1,6 +1,6 @@ using MediaBrowser.Model.Entities; using System; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/LinkedChild.cs b/MediaBrowser.Controller/Entities/LinkedChild.cs index ac13657b94..4d3c13c6e3 100644 --- a/MediaBrowser.Controller/Entities/LinkedChild.cs +++ b/MediaBrowser.Controller/Entities/LinkedChild.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 6d5278f1fe..3e6c88a85d 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -7,7 +7,7 @@ using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Controller.Entities.Audio; namespace MediaBrowser.Controller.Entities.Movies @@ -202,5 +202,10 @@ namespace MediaBrowser.Controller.Entities.Movies return false; } + + public override bool IsVisibleStandalone(User user) + { + return IsVisible(user); + } } } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index f13adb21c7..ec04879b54 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -4,18 +4,20 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities.Movies { /// <summary> /// Class Movie /// </summary> - public class Movie : Video, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle + public class Movie : Video, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping { public List<Guid> SpecialFeatureIds { get; set; } @@ -123,7 +125,18 @@ namespace MediaBrowser.Controller.Entities.Movies if (!DetectIsInMixedFolder()) { - info.Name = System.IO.Path.GetFileName(ContainingFolderPath); + var name = System.IO.Path.GetFileName(ContainingFolderPath); + + if (VideoType == VideoType.VideoFile || VideoType == VideoType.Iso) + { + if (string.Equals(name, System.IO.Path.GetFileName(Path), StringComparison.OrdinalIgnoreCase)) + { + // if the folder has the file extension, strip it + name = System.IO.Path.GetFileNameWithoutExtension(name); + } + } + + info.Name = name; } return info; diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index 6e632a26cf..e3fc4259ae 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -2,7 +2,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using System.Collections.Generic; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index f21bc0a71e..0c36442af3 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -2,9 +2,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { @@ -38,7 +40,7 @@ namespace MediaBrowser.Controller.Entities public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query) { - query.Person = Name; + query.PersonIds = new[] { Id.ToString("N") }; return LibraryManager.GetItemList(query); } @@ -93,7 +95,7 @@ namespace MediaBrowser.Controller.Entities { var itemsWithPerson = LibraryManager.GetItemIds(new InternalItemsQuery { - Person = Name + PersonIds = new[] { Id.ToString("N") } }); return inputItems.Where(i => itemsWithPerson.Contains(i.Id)); diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index a42fce8bbd..e95ceee52c 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -1,6 +1,6 @@ using MediaBrowser.Model.Drawing; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index cb5c5c4539..c902ac8cda 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -1,7 +1,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Users; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 04b09b7442..ec623eedac 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { @@ -37,6 +39,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } + public override bool CanDelete() { return false; diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 1a02043d6f..e6ebcb7fd9 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -3,8 +3,9 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities.TV { @@ -71,6 +72,12 @@ namespace MediaBrowser.Controller.Entities.TV { return IsStacked || MediaSourceCount > 1; } + }
+
+ [IgnoreDataMember]
+ public override bool SupportsInheritedParentImages
+ {
+ get { return true; }
} [IgnoreDataMember] @@ -159,18 +166,37 @@ namespace MediaBrowser.Controller.Entities.TV { return FindParent<Season>() != null; } - } + }
+
+ [IgnoreDataMember]
+ public string SeriesPresentationUniqueKey { get; set; }
[IgnoreDataMember] public string SeriesName { get; set; }
[IgnoreDataMember]
- public string SeasonName { get; set; } + public string SeasonName { get; set; }
+
+ public string FindSeriesPresentationUniqueKey()
+ {
+ var series = Series;
+ return series == null ? null : series.PresentationUniqueKey;
+ } public string FindSeasonName() {
- var season = Season;
- return season == null ? SeasonName : season.Name;
+ var season = Season; + + if (season == null) + { + if (ParentIndexNumber.HasValue) + { + return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture); + }
+ return "Season Unknown";
+ }
+
+ return season.Name;
}
public string FindSeriesName()
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ce13f5fc5f..f2a6586e2f 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -2,12 +2,11 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Users; -using MoreLinq; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using System.Threading.Tasks; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities.TV { @@ -41,13 +40,15 @@ namespace MediaBrowser.Controller.Entities.TV } [IgnoreDataMember] + public override bool SupportsInheritedParentImages + { + get { return true; } + } + + [IgnoreDataMember] public override Guid? DisplayParentId { - get - { - var series = Series; - return series == null ? ParentId : series.Id; - } + get { return SeriesId; } } [IgnoreDataMember] @@ -203,11 +204,20 @@ namespace MediaBrowser.Controller.Entities.TV } [IgnoreDataMember] + public string SeriesPresentationUniqueKey { get; set; } + + [IgnoreDataMember] public string SeriesName { get; set; } [IgnoreDataMember] public Guid? SeriesId { get; set; } + public string FindSeriesPresentationUniqueKey() + { + var series = Series; + return series == null ? null : series.PresentationUniqueKey; + } + public string FindSeriesName() { var series = Series; diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 39703f67ac..872011ce8d 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -6,18 +6,18 @@ using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Providers; -using MoreLinq; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities.TV { /// <summary> /// Class Series /// </summary> - public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer, IHasOriginalTitle + public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IMetadataContainer { public int? AnimeSeriesIndex { get; set; } @@ -95,17 +95,27 @@ namespace MediaBrowser.Controller.Entities.TV public override string CreatePresentationUniqueKey() { - var userdatakeys = GetUserDataKeys(); - - if (userdatakeys.Count > 1) + if (LibraryManager.GetLibraryOptions(this).EnableAutomaticSeriesGrouping) { - return AddLibrariesToPresentationUniqueKey(userdatakeys[0]); + var userdatakeys = GetUserDataKeys(); + + if (userdatakeys.Count > 1) + { + return AddLibrariesToPresentationUniqueKey(userdatakeys[0]); + } } + return base.CreatePresentationUniqueKey(); } private string AddLibrariesToPresentationUniqueKey(string key) { + var lang = GetPreferredMetadataLanguage(); + if (!string.IsNullOrWhiteSpace(lang)) + { + key += "-" + lang; + } + var folders = LibraryManager.GetCollectionFolders(this) .Select(i => i.Id.ToString("N")) .ToArray(); @@ -120,25 +130,62 @@ namespace MediaBrowser.Controller.Entities.TV private static string GetUniqueSeriesKey(BaseItem series) { - if (ConfigurationManager.Configuration.SchemaVersion < 97) - { - return series.Id.ToString("N"); - } return series.GetPresentationUniqueKey(); } public override int GetChildCount(User user) { - var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user) + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(this); + + var result = LibraryManager.GetCount(new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this), + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Season).Name }, - SortBy = new[] { ItemSortBy.SortName }, IsVirtualItem = false, - Limit = 0 + Limit = 0, + DtoOptions = new Dto.DtoOptions + { + Fields = new List<ItemFields> + { + + }, + EnableImages = false + } }); - return result.TotalRecordCount; + return result; + } + + public override int GetRecursiveChildCount(User user) + { + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(this); + + var query = new InternalItemsQuery(user) + { + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, + DtoOptions = new Dto.DtoOptions + { + Fields = new List<ItemFields> + { + + }, + EnableImages = false + } + }; + + if (query.IncludeItemTypes.Length == 0) + { + query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name }; + } + query.IsVirtualItem = false; + query.Limit = 0; + var totalRecordCount = LibraryManager.GetCount(query); + + return totalRecordCount; } /// <summary> @@ -204,13 +251,15 @@ namespace MediaBrowser.Controller.Entities.TV { var config = user.Configuration; + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; var seriesKey = GetUniqueSeriesKey(this); var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = seriesKey, - IncludeItemTypes = new[] {typeof (Season).Name}, - SortBy = new[] {ItemSortBy.SortName} + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, + IncludeItemTypes = new[] { typeof(Season).Name }, + SortBy = new[] { ItemSortBy.SortName } }; if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) @@ -240,7 +289,11 @@ namespace MediaBrowser.Controller.Entities.TV if (query.Recursive) { - query.AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(this); + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + var seriesKey = GetUniqueSeriesKey(this); + + query.AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey; + query.SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null; if (query.SortBy.Length == 0) { query.SortBy = new[] { ItemSortBy.SortName }; @@ -262,13 +315,15 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable<Episode> GetEpisodes(User user) { + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; var seriesKey = GetUniqueSeriesKey(this); var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = seriesKey, - IncludeItemTypes = new[] {typeof (Episode).Name, typeof (Season).Name}, - SortBy = new[] {ItemSortBy.SortName} + AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null, + IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name }, + SortBy = new[] { ItemSortBy.SortName } }; var config = user.Configuration; if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes) @@ -368,11 +423,19 @@ namespace MediaBrowser.Controller.Entities.TV public IEnumerable<Episode> GetSeasonEpisodes(Season parentSeason, User user) { - var seriesKey = GetUniqueSeriesKey(this); + var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey; + + var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons; + + // add optimization when this setting is not enabled + var seriesKey = queryFromSeries ? + GetUniqueSeriesKey(this) : + GetUniqueSeriesKey(parentSeason); var query = new InternalItemsQuery(user) { - AncestorWithPresentationUniqueKey = seriesKey, + AncestorWithPresentationUniqueKey = queryFromSeries && enableSeriesPresentationKey ? null : seriesKey, + SeriesPresentationUniqueKey = queryFromSeries && enableSeriesPresentationKey ? seriesKey : null, IncludeItemTypes = new[] { typeof(Episode).Name }, SortBy = new[] { ItemSortBy.SortName } }; diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index 0780cfec5e..dd6d8a999f 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -2,15 +2,15 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System.Collections.Generic; -using System.Runtime.Serialization; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { /// <summary> /// Class Trailer /// </summary> - public class Trailer : Video, IHasBudget, IHasMetascore, IHasOriginalTitle, IHasLookupInfo<TrailerInfo> + public class Trailer : Video, IHasLookupInfo<TrailerInfo> { public Trailer() { @@ -21,8 +21,6 @@ namespace MediaBrowser.Controller.Entities public List<TrailerType> TrailerTypes { get; set; } - public float? Metascore { get; set; } - public List<MediaUrl> RemoteTrailers { get; set; } [IgnoreDataMember] @@ -31,18 +29,6 @@ namespace MediaBrowser.Controller.Entities get { return TrailerTypes.Contains(TrailerType.LocalTrailer); } } - /// <summary> - /// Gets or sets the budget. - /// </summary> - /// <value>The budget.</value> - public double? Budget { get; set; } - - /// <summary> - /// Gets or sets the revenue. - /// </summary> - /// <value>The revenue.</value> - public double? Revenue { get; set; } - public override UnratedItem GetBlockUnratedType() { return UnratedItem.Trailer; diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 46da469fa5..d5d229bb35 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -6,7 +6,6 @@ using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Users; using System; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Controller/Entities/UserItemData.cs b/MediaBrowser.Controller/Entities/UserItemData.cs index f95fd70364..0e13269499 100644 --- a/MediaBrowser.Controller/Entities/UserItemData.cs +++ b/MediaBrowser.Controller/Entities/UserItemData.cs @@ -1,5 +1,5 @@ using System; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index b67817846f..b602990ac8 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -1,4 +1,4 @@ -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index a689e0d091..5ac5843d70 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -4,7 +4,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading.Tasks; using System.Linq; diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 390d1bf025..bc806e76e2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -17,7 +17,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Configuration; -using MoreLinq; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Entities { @@ -1778,7 +1778,7 @@ namespace MediaBrowser.Controller.Entities .Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i)); } - private IEnumerable<Folder> GetMediaFolders(User user, IEnumerable<string> viewTypes) + private List<Folder> GetMediaFolders(User user, IEnumerable<string> viewTypes) { if (user == null) { @@ -1788,7 +1788,7 @@ namespace MediaBrowser.Controller.Entities var folder = i as ICollectionFolder; return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - }); + }).ToList(); } return GetMediaFolders(user) .Where(i => @@ -1796,17 +1796,17 @@ namespace MediaBrowser.Controller.Entities var folder = i as ICollectionFolder; return folder != null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - }); + }).ToList(); } - private IEnumerable<Folder> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes) + private List<Folder> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes) { if (parent == null || parent is UserView) { return GetMediaFolders(user, viewTypes); } - return new[] { parent }; + return new List<Folder> { parent }; } private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, IEnumerable<string> viewTypes) diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 78d7a7fdd9..7ba59df4f3 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -8,12 +8,14 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using CommonIO; using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { @@ -23,8 +25,7 @@ namespace MediaBrowser.Controller.Entities public class Video : BaseItem, IHasAspectRatio, ISupportsPlaceHolders, - IHasMediaSources, - IThemeMedia + IHasMediaSources { [IgnoreDataMember] public string PrimaryVersionId { get; set; } @@ -35,16 +36,16 @@ namespace MediaBrowser.Controller.Entities public List<ChannelMediaInfo> ChannelMediaSources { get; set; } [IgnoreDataMember] - public bool IsThemeMedia + public override bool SupportsPlayedStatus { get { - return ExtraType.HasValue && ExtraType.Value == Model.Entities.ExtraType.ThemeVideo; + return true; } } [IgnoreDataMember] - public override bool SupportsPlayedStatus + public override bool SupportsPositionTicksResume { get { @@ -86,9 +87,6 @@ namespace MediaBrowser.Controller.Entities get { return true; } } - public int? TotalBitrate { get; set; } - public ExtraType? ExtraType { get; set; } - /// <summary> /// Gets or sets the timestamp. /// </summary> @@ -112,12 +110,6 @@ namespace MediaBrowser.Controller.Entities public string ShortcutPath { get; set; } /// <summary> - /// Gets or sets the video bit rate. - /// </summary> - /// <value>The video bit rate.</value> - public int? VideoBitRate { get; set; } - - /// <summary> /// Gets or sets the default index of the video stream. /// </summary> /// <value>The default index of the video stream.</value> diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 4197ea93e5..75fb694353 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.Entities { @@ -33,6 +33,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsAncestors + { + get + { + return false; + } + } + public override bool CanDelete() { return false; diff --git a/MediaBrowser.Controller/Extensions/StringExtensions.cs b/MediaBrowser.Controller/Extensions/StringExtensions.cs new file mode 100644 index 0000000000..60e7815dbe --- /dev/null +++ b/MediaBrowser.Controller/Extensions/StringExtensions.cs @@ -0,0 +1,17 @@ +using MediaBrowser.Model.Globalization; + +namespace MediaBrowser.Controller.Extensions +{ + /// <summary> + /// Class BaseExtensions + /// </summary> + public static class StringExtensions + { + public static ILocalizationManager LocalizationManager { get; set; } + + public static string RemoveDiacritics(this string text) + { + return LocalizationManager.RemoveDiacritics(text); + } + } +} diff --git a/MediaBrowser.Controller/Health/IHealthMonitor.cs b/MediaBrowser.Controller/Health/IHealthMonitor.cs deleted file mode 100644 index b8ad98fc14..0000000000 --- a/MediaBrowser.Controller/Health/IHealthMonitor.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Notifications; - -namespace MediaBrowser.Controller.Health -{ - public interface IHealthMonitor - { - Task<List<Notification>> GetNotifications(CancellationToken cancellationToken); - } -} diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs index 6e7e60f88c..d40829d44b 100644 --- a/MediaBrowser.Controller/IO/FileData.cs +++ b/MediaBrowser.Controller/IO/FileData.cs @@ -3,7 +3,8 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.IO { diff --git a/MediaBrowser.Controller/IO/ThrottledStream.cs b/MediaBrowser.Controller/IO/ThrottledStream.cs deleted file mode 100644 index 1df00b45a2..0000000000 --- a/MediaBrowser.Controller/IO/ThrottledStream.cs +++ /dev/null @@ -1,393 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.IO -{ - /// <summary> - /// Class for streaming data with throttling support. - /// </summary> - public class ThrottledStream : Stream - { - /// <summary> - /// A constant used to specify an infinite number of bytes that can be transferred per second. - /// </summary> - public const long Infinite = 0; - - #region Private members - /// <summary> - /// The base stream. - /// </summary> - private readonly Stream _baseStream; - - /// <summary> - /// The maximum bytes per second that can be transferred through the base stream. - /// </summary> - private long _maximumBytesPerSecond; - - /// <summary> - /// The number of bytes that has been transferred since the last throttle. - /// </summary> - private long _byteCount; - - /// <summary> - /// The start time in milliseconds of the last throttle. - /// </summary> - private long _start; - #endregion - - #region Properties - /// <summary> - /// Gets the current milliseconds. - /// </summary> - /// <value>The current milliseconds.</value> - protected long CurrentMilliseconds - { - get - { - return Environment.TickCount; - } - } - - /// <summary> - /// Gets or sets the maximum bytes per second that can be transferred through the base stream. - /// </summary> - /// <value>The maximum bytes per second.</value> - public long MaximumBytesPerSecond - { - get - { - return _maximumBytesPerSecond; - } - set - { - if (MaximumBytesPerSecond != value) - { - _maximumBytesPerSecond = value; - Reset(); - } - } - } - - /// <summary> - /// Gets a value indicating whether the current stream supports reading. - /// </summary> - /// <returns>true if the stream supports reading; otherwise, false.</returns> - public override bool CanRead - { - get - { - return _baseStream.CanRead; - } - } - - /// <summary> - /// Gets a value indicating whether the current stream supports seeking. - /// </summary> - /// <value></value> - /// <returns>true if the stream supports seeking; otherwise, false.</returns> - public override bool CanSeek - { - get - { - return _baseStream.CanSeek; - } - } - - /// <summary> - /// Gets a value indicating whether the current stream supports writing. - /// </summary> - /// <value></value> - /// <returns>true if the stream supports writing; otherwise, false.</returns> - public override bool CanWrite - { - get - { - return _baseStream.CanWrite; - } - } - - /// <summary> - /// Gets the length in bytes of the stream. - /// </summary> - /// <value></value> - /// <returns>A long value representing the length of the stream in bytes.</returns> - /// <exception cref="T:System.NotSupportedException">The base stream does not support seeking. </exception> - /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> - public override long Length - { - get - { - return _baseStream.Length; - } - } - - /// <summary> - /// Gets or sets the position within the current stream. - /// </summary> - /// <value></value> - /// <returns>The current position within the stream.</returns> - /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> - /// <exception cref="T:System.NotSupportedException">The base stream does not support seeking. </exception> - /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> - public override long Position - { - get - { - return _baseStream.Position; - } - set - { - _baseStream.Position = value; - } - } - #endregion - - public long MinThrottlePosition; - - #region Ctor - /// <summary> - /// Initializes a new instance of the <see cref="T:ThrottledStream"/> class. - /// </summary> - /// <param name="baseStream">The base stream.</param> - /// <param name="maximumBytesPerSecond">The maximum bytes per second that can be transferred through the base stream.</param> - /// <exception cref="ArgumentNullException">Thrown when <see cref="baseStream"/> is a null reference.</exception> - /// <exception cref="ArgumentOutOfRangeException">Thrown when <see cref="maximumBytesPerSecond"/> is a negative value.</exception> - public ThrottledStream(Stream baseStream, long maximumBytesPerSecond) - { - if (baseStream == null) - { - throw new ArgumentNullException("baseStream"); - } - - if (maximumBytesPerSecond < 0) - { - throw new ArgumentOutOfRangeException("maximumBytesPerSecond", - maximumBytesPerSecond, "The maximum number of bytes per second can't be negative."); - } - - _baseStream = baseStream; - _maximumBytesPerSecond = maximumBytesPerSecond; - _start = CurrentMilliseconds; - _byteCount = 0; - } - #endregion - - #region Public methods - /// <summary> - /// Clears all buffers for this stream and causes any buffered data to be written to the underlying device. - /// </summary> - /// <exception cref="T:System.IO.IOException">An I/O error occurs.</exception> - public override void Flush() - { - _baseStream.Flush(); - } - - /// <summary> - /// Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. - /// </summary> - /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source.</param> - /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param> - /// <param name="count">The maximum number of bytes to be read from the current stream.</param> - /// <returns> - /// The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached. - /// </returns> - /// <exception cref="T:System.ArgumentException">The sum of offset and count is larger than the buffer length. </exception> - /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> - /// <exception cref="T:System.NotSupportedException">The base stream does not support reading. </exception> - /// <exception cref="T:System.ArgumentNullException">buffer is null. </exception> - /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> - /// <exception cref="T:System.ArgumentOutOfRangeException">offset or count is negative. </exception> - public override int Read(byte[] buffer, int offset, int count) - { - Throttle(count); - - return _baseStream.Read(buffer, offset, count); - } - - /// <summary> - /// Sets the position within the current stream. - /// </summary> - /// <param name="offset">A byte offset relative to the origin parameter.</param> - /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin"></see> indicating the reference point used to obtain the new position.</param> - /// <returns> - /// The new position within the current stream. - /// </returns> - /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> - /// <exception cref="T:System.NotSupportedException">The base stream does not support seeking, such as if the stream is constructed from a pipe or console output. </exception> - /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> - public override long Seek(long offset, SeekOrigin origin) - { - return _baseStream.Seek(offset, origin); - } - - /// <summary> - /// Sets the length of the current stream. - /// </summary> - /// <param name="value">The desired length of the current stream in bytes.</param> - /// <exception cref="T:System.NotSupportedException">The base stream does not support both writing and seeking, such as if the stream is constructed from a pipe or console output. </exception> - /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> - /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> - public override void SetLength(long value) - { - _baseStream.SetLength(value); - } - - private long _bytesWritten; - - /// <summary> - /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. - /// </summary> - /// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param> - /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param> - /// <param name="count">The number of bytes to be written to the current stream.</param> - /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception> - /// <exception cref="T:System.NotSupportedException">The base stream does not support writing. </exception> - /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception> - /// <exception cref="T:System.ArgumentNullException">buffer is null. </exception> - /// <exception cref="T:System.ArgumentException">The sum of offset and count is greater than the buffer length. </exception> - /// <exception cref="T:System.ArgumentOutOfRangeException">offset or count is negative. </exception> - public override void Write(byte[] buffer, int offset, int count) - { - Throttle(count); - - _baseStream.Write(buffer, offset, count); - - _bytesWritten += count; - } - - public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - await ThrottleAsync(count, cancellationToken).ConfigureAwait(false); - - await _baseStream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); - - _bytesWritten += count; - } - - /// <summary> - /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>. - /// </summary> - /// <returns> - /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>. - /// </returns> - public override string ToString() - { - return _baseStream.ToString(); - } - #endregion - - private bool ThrottleCheck(int bufferSizeInBytes) - { - if (_bytesWritten < MinThrottlePosition) - { - return false; - } - - // Make sure the buffer isn't empty. - if (_maximumBytesPerSecond <= 0 || bufferSizeInBytes <= 0) - { - return false; - } - - return true; - } - - #region Protected methods - /// <summary> - /// Throttles for the specified buffer size in bytes. - /// </summary> - /// <param name="bufferSizeInBytes">The buffer size in bytes.</param> - protected void Throttle(int bufferSizeInBytes) - { - if (!ThrottleCheck(bufferSizeInBytes)) - { - return ; - } - - _byteCount += bufferSizeInBytes; - long elapsedMilliseconds = CurrentMilliseconds - _start; - - if (elapsedMilliseconds > 0) - { - // Calculate the current bps. - long bps = _byteCount * 1000L / elapsedMilliseconds; - - // If the bps are more then the maximum bps, try to throttle. - if (bps > _maximumBytesPerSecond) - { - // Calculate the time to sleep. - long wakeElapsed = _byteCount * 1000L / _maximumBytesPerSecond; - int toSleep = (int)(wakeElapsed - elapsedMilliseconds); - - if (toSleep > 1) - { - try - { - // The time to sleep is more then a millisecond, so sleep. - Thread.Sleep(toSleep); - } - catch (ThreadAbortException) - { - // Eatup ThreadAbortException. - } - - // A sleep has been done, reset. - Reset(); - } - } - } - } - - protected async Task ThrottleAsync(int bufferSizeInBytes, CancellationToken cancellationToken) - { - if (!ThrottleCheck(bufferSizeInBytes)) - { - return; - } - - _byteCount += bufferSizeInBytes; - long elapsedMilliseconds = CurrentMilliseconds - _start; - - if (elapsedMilliseconds > 0) - { - // Calculate the current bps. - long bps = _byteCount * 1000L / elapsedMilliseconds; - - // If the bps are more then the maximum bps, try to throttle. - if (bps > _maximumBytesPerSecond) - { - // Calculate the time to sleep. - long wakeElapsed = _byteCount * 1000L / _maximumBytesPerSecond; - int toSleep = (int)(wakeElapsed - elapsedMilliseconds); - - if (toSleep > 1) - { - // The time to sleep is more then a millisecond, so sleep. - await Task.Delay(toSleep, cancellationToken).ConfigureAwait(false); - - // A sleep has been done, reset. - Reset(); - } - } - } - } - - /// <summary> - /// Will reset the bytecount to 0 and reset the start time to the current time. - /// </summary> - protected void Reset() - { - long difference = CurrentMilliseconds - _start; - - // Only reset counters when a known history is available of more then 1 second. - if (difference > 1000) - { - _byteCount = 0; - _start = CurrentMilliseconds; - } - } - #endregion - } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index d6744e8043..44c0031974 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; +using MediaBrowser.Model.Net; namespace MediaBrowser.Controller { @@ -25,12 +26,6 @@ namespace MediaBrowser.Controller /// </summary> /// <value><c>true</c> if [supports automatic run at startup]; otherwise, <c>false</c>.</value> bool SupportsAutoRunAtStartup { get; } - - /// <summary> - /// Gets a value indicating whether [supports library monitor]. - /// </summary> - /// <value><c>true</c> if [supports library monitor]; otherwise, <c>false</c>.</value> - bool SupportsLibraryMonitor { get; } /// <summary> /// Gets the HTTP server port. @@ -66,7 +61,7 @@ namespace MediaBrowser.Controller /// Gets the local ip address. /// </summary> /// <value>The local ip address.</value> - Task<List<IPAddress>> GetLocalIpAddresses(); + Task<List<IpAddressInfo>> GetLocalIpAddresses(); /// <summary> /// Gets the local API URL. @@ -84,9 +79,7 @@ namespace MediaBrowser.Controller /// <summary> /// Gets the local API URL. /// </summary> - /// <param name="ipAddress">The ip address.</param> - /// <returns>System.String.</returns> - string GetLocalApiUrl(IPAddress ipAddress); + string GetLocalApiUrl(IpAddressInfo address); void LaunchUrl(string url); diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 975c596594..bf9a076264 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -10,10 +10,12 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using CommonIO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Library { @@ -60,6 +62,8 @@ namespace MediaBrowser.Controller.Library /// <returns>BaseItem.</returns> BaseItem FindByPath(string path, bool? isFolder); + Guid? FindIdByPath(string path, bool? isFolder); + /// <summary> /// Gets the artist. /// </summary> @@ -536,10 +540,7 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Gets the items. /// </summary> - /// <param name="query">The query.</param> - /// <param name="parentIds">The parent ids.</param> - /// <returns>List<BaseItem>.</returns> - IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, IEnumerable<string> parentIds); + IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents); /// <summary> /// Gets the items result. @@ -572,5 +573,6 @@ namespace MediaBrowser.Controller.Library void RegisterIgnoredPath(string path); void UnRegisterIgnoredPath(string path); + int GetCount(InternalItemsQuery query); } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs index 86c52c4c31..5940c7e292 100644 --- a/MediaBrowser.Controller/Library/IUserDataManager.cs +++ b/MediaBrowser.Controller/Library/IUserDataManager.cs @@ -5,6 +5,7 @@ using MediaBrowser.Model.Entities; using System; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Library { @@ -37,12 +38,9 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Gets the user data dto. /// </summary> - /// <param name="item">The item.</param> - /// <param name="user">The user.</param> - /// <returns>UserItemDataDto.</returns> Task<UserItemDataDto> GetUserDataDto(IHasUserData item, User user); - Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user); + Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields); /// <summary> /// Get all user data for the given user diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index ec0ac325bc..763d27ebaf 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -4,9 +4,11 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using CommonIO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Library { @@ -97,18 +99,6 @@ namespace MediaBrowser.Controller.Library } /// <summary> - /// Gets a value indicating whether this instance is hidden. - /// </summary> - /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value> - public bool IsHidden - { - get - { - return (FileInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; - } - } - - /// <summary> /// Gets a value indicating whether this instance is vf. /// </summary> /// <value><c>true</c> if this instance is vf; otherwise, <c>false</c>.</value> diff --git a/MediaBrowser.Controller/Library/NameExtensions.cs b/MediaBrowser.Controller/Library/NameExtensions.cs index 72f036b0a5..693b7b2217 100644 --- a/MediaBrowser.Controller/Library/NameExtensions.cs +++ b/MediaBrowser.Controller/Library/NameExtensions.cs @@ -1,29 +1,20 @@ -using MediaBrowser.Common.Extensions; -using MoreLinq; -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.Library { public static class NameExtensions { - public static bool AreEqual(string x, string y) - { - if (string.IsNullOrWhiteSpace(x) && string.IsNullOrWhiteSpace(y)) - { - return true; - } - - return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) == 0; - } - public static bool EqualsAny(IEnumerable<string> names, string x) { x = NormalizeForComparison(x); - return names.Any(y => string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) == 0); + return names.Any(y => string.Compare(x, y, StringComparison.OrdinalIgnoreCase) == 0); + //return names.Any(y => string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) == 0); } private static string NormalizeForComparison(string name) diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 8e3c1931b1..08e4956adc 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -393,5 +393,8 @@ namespace MediaBrowser.Controller.LiveTv event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCancelled; event EventHandler<GenericEventArgs<TimerEventInfo>> TimerCreated; event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCreated; + + string GetEmbyTvActiveRecordingPath(string id); + Task<LiveStream> GetEmbyTvLiveStream(string id); } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index de5ffcd588..e67fc57594 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -7,7 +7,7 @@ using MediaBrowser.Model.LiveTv; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading.Tasks; using MediaBrowser.Controller.Library; @@ -46,6 +46,15 @@ namespace MediaBrowser.Controller.LiveTv set { } } + [IgnoreDataMember] + public override bool SupportsPositionTicksResume + { + get + { + return true; + } + } + /// <summary> /// Gets a value indicating whether this instance is owned item. /// </summary> diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 5e99d6fa3f..d164b5e0d9 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -6,7 +6,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using System.Collections.Generic; using System.Globalization; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; namespace MediaBrowser.Controller.LiveTv { @@ -39,6 +39,15 @@ namespace MediaBrowser.Controller.LiveTv } [IgnoreDataMember] + public override bool SupportsPositionTicksResume + { + get + { + return false; + } + } + + [IgnoreDataMember] public override SourceType SourceType { get { return SourceType.LiveTV; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index c7f47b825b..ffb6a75556 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -4,9 +4,12 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; using System; using System.Collections.Generic; -using System.Runtime.Serialization; +using System.Linq; +using MediaBrowser.Common.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.LiveTv { @@ -236,6 +239,40 @@ namespace MediaBrowser.Controller.LiveTv } } + private LiveTvOptions GetConfiguration() + { + return ConfigurationManager.GetConfiguration<LiveTvOptions>("livetv"); + } + + private ListingsProviderInfo GetListingsProviderInfo() + { + if (string.Equals(ServiceName, "Emby", StringComparison.OrdinalIgnoreCase)) + { + var config = GetConfiguration(); + + return config.ListingProviders.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i.MoviePrefix)); + } + + return null; + } + + protected override string GetNameForMetadataLookup() + { + var name = base.GetNameForMetadataLookup(); + + var listings = GetListingsProviderInfo(); + + if (listings != null) + { + if (!string.IsNullOrWhiteSpace(listings.MoviePrefix) && name.StartsWith(listings.MoviePrefix, StringComparison.OrdinalIgnoreCase)) + { + name = name.Substring(listings.MoviePrefix.Length).Trim(); + } + } + + return name; + } + public override List<ExternalUrl> GetRelatedUrls() { var list = base.GetRelatedUrls(); diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 2c0ced0e6c..18894120a8 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -6,7 +6,7 @@ using MediaBrowser.Model.LiveTv; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading.Tasks; using MediaBrowser.Controller.Library; diff --git a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs index 5c86de08b8..8093b5a768 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs @@ -1,4 +1,4 @@ -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Users; diff --git a/MediaBrowser.Controller/LiveTv/TimerInfo.cs b/MediaBrowser.Controller/LiveTv/TimerInfo.cs index fd614253ae..10ed95fe5e 100644 --- a/MediaBrowser.Controller/LiveTv/TimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerInfo.cs @@ -34,6 +34,8 @@ namespace MediaBrowser.Controller.LiveTv /// <value>The program identifier.</value> public string ProgramId { get; set; } + public string ShowId { get; set; } + /// <summary> /// Name of the recording. /// </summary> @@ -44,6 +46,8 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> public string Overview { get; set; } + public string SeriesId { get; set; } + /// <summary> /// The start date of the recording, in UTC. /// </summary> diff --git a/MediaBrowser.Controller/Localization/ILocalizationManager.cs b/MediaBrowser.Controller/Localization/ILocalizationManager.cs deleted file mode 100644 index 5742d235cd..0000000000 --- a/MediaBrowser.Controller/Localization/ILocalizationManager.cs +++ /dev/null @@ -1,55 +0,0 @@ -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Globalization; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Localization -{ - /// <summary> - /// Interface ILocalizationManager - /// </summary> - public interface ILocalizationManager - { - /// <summary> - /// Gets the cultures. - /// </summary> - /// <returns>IEnumerable{CultureDto}.</returns> - IEnumerable<CultureDto> GetCultures(); - /// <summary> - /// Gets the countries. - /// </summary> - /// <returns>IEnumerable{CountryInfo}.</returns> - IEnumerable<CountryInfo> GetCountries(); - /// <summary> - /// Gets the parental ratings. - /// </summary> - /// <returns>IEnumerable{ParentalRating}.</returns> - IEnumerable<ParentalRating> GetParentalRatings(); - /// <summary> - /// Gets the rating level. - /// </summary> - /// <param name="rating">The rating.</param> - /// <returns>System.Int32.</returns> - int? GetRatingLevel(string rating); - - /// <summary> - /// Gets the localized string. - /// </summary> - /// <param name="phrase">The phrase.</param> - /// <param name="culture">The culture.</param> - /// <returns>System.String.</returns> - string GetLocalizedString(string phrase, string culture); - - /// <summary> - /// Gets the localized string. - /// </summary> - /// <param name="phrase">The phrase.</param> - /// <returns>System.String.</returns> - string GetLocalizedString(string phrase); - - /// <summary> - /// Gets the localization options. - /// </summary> - /// <returns>IEnumerable{LocalizatonOption}.</returns> - IEnumerable<LocalizatonOption> GetLocalizationOptions(); - } -} diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 36d59d3e44..28229f8a7e 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -11,9 +11,10 @@ <AssemblyName>MediaBrowser.Controller</AssemblyName> <FileAlignment>512</FileAlignment> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <TargetFrameworkProfile>Profile7</TargetFrameworkProfile> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> - <ReleaseVersion> - </ReleaseVersion> + <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -44,37 +45,13 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath> - </Reference> - <Reference Include="Interfaces.IO"> - <HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath> - </Reference> - <Reference Include="MoreLinq"> - <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath> - </Reference> - <Reference Include="Patterns.Logging"> - <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> - </Reference> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Data" /> - <Reference Include="System.Net" /> - <Reference Include="System.Runtime.Serialization" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Xml" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="ServiceStack.Interfaces"> - <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath> - </Reference> + <None Include="project.json" /> + <!-- A reference to the entire .NET Framework is automatically included --> </ItemGroup> <ItemGroup> <Compile Include="..\SharedVersion.cs"> <Link>Properties\SharedVersion.cs</Link> </Compile> - <Compile Include="Activity\IActivityManager.cs" /> - <Compile Include="Activity\IActivityRepository.cs" /> <Compile Include="Channels\ChannelItemInfo.cs" /> <Compile Include="Channels\ChannelItemResult.cs" /> <Compile Include="Channels\ChannelItemType.cs" /> @@ -107,12 +84,11 @@ <Compile Include="Dlna\EventSubscriptionResponse.cs" /> <Compile Include="Dlna\IConnectionManager.cs" /> <Compile Include="Dlna\IContentDirectory.cs" /> - <Compile Include="Dlna\IDeviceDiscovery.cs" /> <Compile Include="Dlna\IDlnaManager.cs" /> <Compile Include="Dlna\IEventManager.cs" /> <Compile Include="Dlna\IMediaReceiverRegistrar.cs" /> <Compile Include="Dlna\IUpnpService.cs" /> - <Compile Include="Dlna\SsdpMessageEventArgs.cs" /> + <Compile Include="Drawing\IImageEncoder.cs" /> <Compile Include="Drawing\IImageProcessor.cs" /> <Compile Include="Drawing\ImageCollageOptions.cs" /> <Compile Include="Drawing\ImageProcessingOptions.cs" /> @@ -120,6 +96,7 @@ <Compile Include="Drawing\ImageStream.cs" /> <Compile Include="Dto\DtoOptions.cs" /> <Compile Include="Dto\IDtoService.cs" /> + <Compile Include="Entities\AudioBook.cs" /> <Compile Include="Entities\Audio\AudioPodcast.cs" /> <Compile Include="Entities\Audio\IHasAlbumArtist.cs" /> <Compile Include="Entities\Audio\IHasMusicGenres.cs" /> @@ -139,7 +116,6 @@ <Compile Include="Entities\KeywordExtensions.cs" /> <Compile Include="Entities\IHasMediaSources.cs" /> <Compile Include="Entities\IHasMetascore.cs" /> - <Compile Include="Entities\IHasOriginalTitle.cs" /> <Compile Include="Entities\IHasProgramAttributes.cs" /> <Compile Include="Entities\IHasScreenshots.cs" /> <Compile Include="Entities\IHasSeries.cs" /> @@ -155,7 +131,6 @@ <Compile Include="Entities\ISupportsBoxSetGrouping.cs" /> <Compile Include="Entities\ISupportsPlaceHolders.cs" /> <Compile Include="Entities\ItemImageInfo.cs" /> - <Compile Include="Entities\IThemeMedia.cs" /> <Compile Include="Entities\LinkedChild.cs" /> <Compile Include="Entities\MusicVideo.cs" /> <Compile Include="Entities\IHasAwards.cs" /> @@ -167,9 +142,8 @@ <Compile Include="Entities\TagExtensions.cs" /> <Compile Include="Entities\UserView.cs" /> <Compile Include="Entities\UserViewBuilder.cs" /> + <Compile Include="Extensions\StringExtensions.cs" /> <Compile Include="FileOrganization\IFileOrganizationService.cs" /> - <Compile Include="Health\IHealthMonitor.cs" /> - <Compile Include="IO\ThrottledStream.cs" /> <Compile Include="Library\DeleteOptions.cs" /> <Compile Include="Library\ILibraryPostScanTask.cs" /> <Compile Include="Library\IMediaSourceManager.cs" /> @@ -209,7 +183,6 @@ <Compile Include="LiveTv\TimerEventInfo.cs" /> <Compile Include="LiveTv\TimerInfo.cs" /> <Compile Include="LiveTv\TunerChannelMapping.cs" /> - <Compile Include="Localization\ILocalizationManager.cs" /> <Compile Include="MediaEncoding\ChapterImageRefreshOptions.cs" /> <Compile Include="MediaEncoding\EncodingJobOptions.cs" /> <Compile Include="MediaEncoding\IEncodingManager.cs" /> @@ -220,16 +193,11 @@ <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\IHasAuthorization.cs" /> - <Compile Include="Net\IAsyncStreamSource.cs" /> <Compile Include="Net\IHasResultFactory.cs" /> - <Compile Include="Net\IHasSession.cs" /> <Compile Include="Net\IHttpResultFactory.cs" /> <Compile Include="Net\IHttpServer.cs" /> - <Compile Include="Net\IRestfulService.cs" /> <Compile Include="Net\IServerManager.cs" /> <Compile Include="Net\IServiceRequest.cs" /> <Compile Include="Net\ISessionContext.cs" /> @@ -238,11 +206,10 @@ <Compile Include="Net\IWebSocketListener.cs" /> <Compile Include="Net\LoggedAttribute.cs" /> <Compile Include="Net\SecurityException.cs" /> - <Compile Include="Net\ServiceStackServiceRequest.cs" /> + <Compile Include="Net\ServiceRequest.cs" /> <Compile Include="Net\StaticResultOptions.cs" /> <Compile Include="Net\WebSocketConnectEventArgs.cs" /> <Compile Include="Net\WebSocketMessageInfo.cs" /> - <Compile Include="News\INewsService.cs" /> <Compile Include="Notifications\INotificationManager.cs" /> <Compile Include="Notifications\INotificationService.cs" /> <Compile Include="Notifications\INotificationsRepository.cs" /> @@ -309,7 +276,6 @@ <Compile Include="Security\IAuthenticationRepository.cs" /> <Compile Include="Security\IEncryptionManager.cs" /> <Compile Include="Session\AuthenticationRequest.cs" /> - <Compile Include="Social\ISharingManager.cs" /> <Compile Include="Sorting\SortHelper.cs" /> <Compile Include="Subtitles\ISubtitleManager.cs" /> <Compile Include="Subtitles\ISubtitleProvider.cs" /> @@ -377,7 +343,6 @@ <Compile Include="Session\SessionInfo.cs" /> <Compile Include="Sorting\IBaseItemComparer.cs" /> <Compile Include="Sorting\IUserBaseItemComparer.cs" /> - <Compile Include="Providers\BaseItemXmlParser.cs" /> <Compile Include="Sorting\SortExtensions.cs" /> <Compile Include="Subtitles\SubtitleDownloadEventArgs.cs" /> <Compile Include="Subtitles\SubtitleResponse.cs" /> @@ -403,10 +368,7 @@ <Name>MediaBrowser.Model</Name> </ProjectReference> </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <PropertyGroup> <PostBuildEvent /> </PropertyGroup> diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.nuget.targets b/MediaBrowser.Controller/MediaBrowser.Controller.nuget.targets new file mode 100644 index 0000000000..e69ce0e64f --- /dev/null +++ b/MediaBrowser.Controller/MediaBrowser.Controller.nuget.targets @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Target Name="EmitMSBuildWarning" BeforeTargets="Build"> + <Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." /> + </Target> +</Project>
\ No newline at end of file diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 866a08aa1f..45aaa8e8e6 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -135,5 +135,8 @@ namespace MediaBrowser.Controller.MediaEncoding Task UpdateEncoderPath(string path, string pathType); bool SupportsEncoder(string encoder); bool IsDefaultEncoderPath { get; } + + void SetLogFilename(string name); + void ClearLogFilename(); } } diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs index 96a3753e19..0b1ca08e51 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs @@ -4,7 +4,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; namespace MediaBrowser.Controller.MediaEncoding { diff --git a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs index 52199c5a21..8169cc7d9f 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaStreamSelector.cs @@ -69,7 +69,8 @@ namespace MediaBrowser.Controller.MediaEncoding // if the audio language is not understood by the user, load their preferred subs, if there are any if (!ContainsOrdinal(preferredLanguages, audioTrackLanguage)) { - stream = streams.Where(s => !s.IsForced).FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)); + stream = streams.Where(s => !s.IsForced).FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)) ?? + streams.FirstOrDefault(s => ContainsOrdinal(preferredLanguages, s.Language)); } } else if (mode == SubtitlePlaybackMode.Always) diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs index b1bab79c5c..b025011d7e 100644 --- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs +++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs @@ -1,13 +1,13 @@ -using ServiceStack.Web; -using System; +using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { public class AuthenticatedAttribute : Attribute, IHasRequestFilter, IAuthenticationAttributes { - public IAuthService AuthService { get; set; } + public static IAuthService AuthService { get; set; } /// <summary> /// Gets or sets the roles. @@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Net /// </summary> /// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value> public bool AllowBeforeStartupWizard { get; set; } - + /// <summary> /// The request filter is executed before the service. /// </summary> @@ -35,21 +35,12 @@ namespace MediaBrowser.Controller.Net /// <param name="requestDto">The request DTO</param> public void RequestFilter(IRequest request, IResponse response, object requestDto) { - var serviceRequest = new ServiceStackServiceRequest(request); + var serviceRequest = new ServiceRequest(request); AuthService.Authenticate(serviceRequest, this); } /// <summary> - /// A new shallow copy of this filter is used on every request. - /// </summary> - /// <returns>IHasRequestFilter.</returns> - public IHasRequestFilter Copy() - { - return this; - } - - /// <summary> /// Order in which Request Filters are executed. /// <0 Executed before global request filters /// >0 Executed after global request filters @@ -60,7 +51,6 @@ namespace MediaBrowser.Controller.Net get { return 0; } } - public IEnumerable<string> GetRoles() { return (Roles ?? string.Empty).Split(',') diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs deleted file mode 100644 index be177cb02c..0000000000 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ /dev/null @@ -1,341 +0,0 @@ -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -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, Timer, TStateType, SemaphoreSlim>> ActiveConnections = - new List<Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>>(); - - /// <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; - - /// <summary> - /// Initializes a new instance of the <see cref="BasePeriodicWebSocketListener{TStateType}" /> class. - /// </summary> - /// <param name="logger">The logger.</param> - /// <exception cref="System.ArgumentNullException">logger</exception> - protected BasePeriodicWebSocketListener(ILogger logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - Logger = logger; - } - - /// <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 true; - } - } - - 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 ? - new Timer(TimerCallback, message.Connection, Timeout.Infinite, Timeout.Infinite) : - null; - - var state = new TStateType - { - IntervalMs = periodMs, - InitialDelayMs = dueTimeMs - }; - - var semaphore = new SemaphoreSlim(1, 1); - - lock (ActiveConnections) - { - ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, Timer, TStateType, SemaphoreSlim>(message.Connection, cancellationTokenSource, timer, state, semaphore)); - } - - 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, Timer, TStateType, SemaphoreSlim> 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, Timer, TStateType, SemaphoreSlim>> 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, Timer, TStateType, SemaphoreSlim> tuple) - { - var connection = tuple.Item1; - - try - { - await tuple.Item5.WaitAsync(tuple.Item2.Token).ConfigureAwait(false); - - 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; - } - - tuple.Item5.Release(); - } - 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, Timer, TStateType, SemaphoreSlim> 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) - { - - } - - try - { - connection.Item5.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); - } - } - - public class WebSocketListenerState - { - public DateTime DateLastSendUtc { get; set; } - public long InitialDelayMs { get; set; } - public long IntervalMs { get; set; } - } -} diff --git a/MediaBrowser.Controller/Net/IAsyncStreamSource.cs b/MediaBrowser.Controller/Net/IAsyncStreamSource.cs deleted file mode 100644 index 0f41f60a55..0000000000 --- a/MediaBrowser.Controller/Net/IAsyncStreamSource.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ServiceStack.Web; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Net -{ - /// <summary> - /// Interface IAsyncStreamSource - /// Enables asynchronous writing to http resonse streams - /// </summary> - public interface IAsyncStreamSource - { - /// <summary> - /// Asynchronously write to the response stream. - /// </summary> - Task WriteToAsync(Stream responseStream); - } -} diff --git a/MediaBrowser.Controller/Net/IHasAuthorization.cs b/MediaBrowser.Controller/Net/IHasAuthorization.cs deleted file mode 100644 index 6fc70159dd..0000000000 --- a/MediaBrowser.Controller/Net/IHasAuthorization.cs +++ /dev/null @@ -1,12 +0,0 @@ - -namespace MediaBrowser.Controller.Net -{ - public interface IHasAuthorization - { - /// <summary> - /// Gets or sets the authorization context. - /// </summary> - /// <value>The authorization context.</value> - IAuthorizationContext AuthorizationContext { get; set; } - } -} diff --git a/MediaBrowser.Controller/Net/IHasResultFactory.cs b/MediaBrowser.Controller/Net/IHasResultFactory.cs index 3988b8d615..03144e4b88 100644 --- a/MediaBrowser.Controller/Net/IHasResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHasResultFactory.cs @@ -1,4 +1,4 @@ -using ServiceStack.Web; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { diff --git a/MediaBrowser.Controller/Net/IHasSession.cs b/MediaBrowser.Controller/Net/IHasSession.cs deleted file mode 100644 index e762c1e844..0000000000 --- a/MediaBrowser.Controller/Net/IHasSession.cs +++ /dev/null @@ -1,12 +0,0 @@ - -namespace MediaBrowser.Controller.Net -{ - public interface IHasSession - { - /// <summary> - /// Gets or sets the session context. - /// </summary> - /// <value>The session context.</value> - ISessionContext SessionContext { get; set; } - } -} diff --git a/MediaBrowser.Controller/Net/IHttpResultFactory.cs b/MediaBrowser.Controller/Net/IHttpResultFactory.cs index ca453840fe..9f295c71d8 100644 --- a/MediaBrowser.Controller/Net/IHttpResultFactory.cs +++ b/MediaBrowser.Controller/Net/IHttpResultFactory.cs @@ -1,8 +1,10 @@ -using ServiceStack.Web; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -20,8 +22,6 @@ namespace MediaBrowser.Controller.Net /// <returns>System.Object.</returns> object GetResult(object content, string contentType, IDictionary<string,string> responseHeaders = null); - object GetAsyncStreamWriter(IAsyncStreamSource streamSource); - /// <summary> /// Gets the optimized result. /// </summary> @@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Net /// <param name="path">The path.</param> /// <param name="fileShare">The file share.</param> /// <returns>System.Object.</returns> - Task<object> GetStaticFileResult(IRequest requestContext, string path, FileShare fileShare = FileShare.Read); + Task<object> GetStaticFileResult(IRequest requestContext, string path, FileShareMode fileShare = FileShareMode.Read); /// <summary> /// Gets the static file result. diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 97c5dd31b6..f319244dae 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -15,18 +16,10 @@ namespace MediaBrowser.Controller.Net IEnumerable<string> UrlPrefixes { get; } /// <summary> - /// Gets the certificate path. - /// </summary> - /// <value>The certificate path.</value> - string CertificatePath { get; } - - /// <summary> /// Starts the specified server name. /// </summary> /// <param name="urlPrefixes">The URL prefixes.</param> - /// <param name="certificatePath">If an https prefix is specified, - /// the ssl certificate localtion on the file system.</param> - void StartServer(IEnumerable<string> urlPrefixes, string certificatePath); + void StartServer(IEnumerable<string> urlPrefixes); /// <summary> /// Stops this instance. @@ -46,7 +39,7 @@ namespace MediaBrowser.Controller.Net /// <summary> /// Inits this instance. /// </summary> - void Init(IEnumerable<IRestfulService> services); + void Init(IEnumerable<IService> services); /// <summary> /// If set, all requests will respond with this message diff --git a/MediaBrowser.Controller/Net/IRestfulService.cs b/MediaBrowser.Controller/Net/IRestfulService.cs deleted file mode 100644 index 7d07bb0941..0000000000 --- a/MediaBrowser.Controller/Net/IRestfulService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using ServiceStack; - -namespace MediaBrowser.Controller.Net -{ - /// <summary> - /// Interface IRestfulService - /// </summary> - [Logged] - public interface IRestfulService : IService - { - } -} diff --git a/MediaBrowser.Controller/Net/IServerManager.cs b/MediaBrowser.Controller/Net/IServerManager.cs index 5191a62e31..202df29824 100644 --- a/MediaBrowser.Controller/Net/IServerManager.cs +++ b/MediaBrowser.Controller/Net/IServerManager.cs @@ -15,9 +15,7 @@ namespace MediaBrowser.Controller.Net /// Starts this instance. /// </summary> /// <param name="urlPrefixes">The URL prefixes.</param> - /// <param name="certificatePath">If an https prefix is specified, - /// the ssl certificate localtion on the file system.</param> - void Start(IEnumerable<string> urlPrefixes, string certificatePath); + void Start(IEnumerable<string> urlPrefixes); /// <summary> /// Sends a message to all clients currently connected via a web socket diff --git a/MediaBrowser.Controller/Net/IServiceRequest.cs b/MediaBrowser.Controller/Net/IServiceRequest.cs index e48247362b..ebc7e8d65d 100644 --- a/MediaBrowser.Controller/Net/IServiceRequest.cs +++ b/MediaBrowser.Controller/Net/IServiceRequest.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; -using System.Collections.Specialized; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { public interface IServiceRequest { - object OriginalRequest { get; } string RemoteIp { get; } - NameValueCollection Headers { get; } - NameValueCollection QueryString { get; } + QueryParamCollection Headers { get; } + QueryParamCollection QueryString { get; } IDictionary<string,object> Items { get; } void AddResponseHeader(string name, string value); } diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index e21df3c395..dad2388914 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -1,8 +1,8 @@ using MediaBrowser.Model.Net; using System; -using System.Collections.Specialized; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Net /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - NameValueCollection QueryString { get; set; } + QueryParamCollection QueryString { get; set; } /// <summary> /// Gets or sets the receive action. diff --git a/MediaBrowser.Controller/Net/LoggedAttribute.cs b/MediaBrowser.Controller/Net/LoggedAttribute.cs index d56a015a86..6a2a5e2e3b 100644 --- a/MediaBrowser.Controller/Net/LoggedAttribute.cs +++ b/MediaBrowser.Controller/Net/LoggedAttribute.cs @@ -2,17 +2,25 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; -using ServiceStack.Web; using System; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { - public class LoggedAttribute : Attribute, IHasRequestFilter + public class LoggedAttribute : IRequestFilter { - public ILogger Logger { get; set; } - public IUserManager UserManager { get; set; } - public ISessionManager SessionManager { get; set; } - public IAuthorizationContext AuthorizationContext { get; set; } + public LoggedAttribute(ILogger logger, IUserManager userManager, ISessionManager sessionManager, IAuthorizationContext authorizationContext) + { + Logger = logger; + UserManager = userManager; + SessionManager = sessionManager; + AuthorizationContext = authorizationContext; + } + + public ILogger Logger { get; private set; } + public IUserManager UserManager { get; private set; } + public ISessionManager SessionManager { get; private set; } + public IAuthorizationContext AuthorizationContext { get; private set; } /// <summary> /// The request filter is executed before the service. @@ -20,9 +28,9 @@ namespace MediaBrowser.Controller.Net /// <param name="request">The http request wrapper</param> /// <param name="response">The http response wrapper</param> /// <param name="requestDto">The request DTO</param> - public void RequestFilter(IRequest request, IResponse response, object requestDto) + public void Filter(IRequest request, IResponse response, object requestDto) { - var serviceRequest = new ServiceStackServiceRequest(request); + var serviceRequest = new ServiceRequest(request); //This code is executed before the service var auth = AuthorizationContext.GetAuthorizationInfo(serviceRequest); @@ -51,25 +59,5 @@ namespace MediaBrowser.Controller.Net } } } - - /// <summary> - /// A new shallow copy of this filter is used on every request. - /// </summary> - /// <returns>IHasRequestFilter.</returns> - public IHasRequestFilter Copy() - { - return this; - } - - /// <summary> - /// Order in which Request Filters are executed. - /// <0 Executed before global request filters - /// >0 Executed after global request filters - /// </summary> - /// <value>The priority.</value> - public int Priority - { - get { return 0; } - } } } diff --git a/MediaBrowser.Controller/Net/ServiceRequest.cs b/MediaBrowser.Controller/Net/ServiceRequest.cs new file mode 100644 index 0000000000..1f72d0eb29 --- /dev/null +++ b/MediaBrowser.Controller/Net/ServiceRequest.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using MediaBrowser.Model.Services; + +namespace MediaBrowser.Controller.Net +{ + public class ServiceRequest : IServiceRequest + { + private readonly IRequest _request; + + public ServiceRequest(IRequest request) + { + _request = request; + } + + public string RemoteIp + { + get { return _request.RemoteIp; } + } + + public QueryParamCollection Headers + { + get { return _request.Headers; } + } + + public QueryParamCollection QueryString + { + get { return _request.QueryString; } + } + + public IDictionary<string, object> Items + { + get { return _request.Items; } + } + + public void AddResponseHeader(string name, string value) + { + _request.Response.AddHeader(name, value); + } + } +} diff --git a/MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs b/MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs deleted file mode 100644 index a33e9c1c6e..0000000000 --- a/MediaBrowser.Controller/Net/ServiceStackServiceRequest.cs +++ /dev/null @@ -1,62 +0,0 @@ -using ServiceStack.Web; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace MediaBrowser.Controller.Net -{ - public class ServiceStackServiceRequest : IServiceRequest - { - private readonly IRequest _request; - - public ServiceStackServiceRequest(IRequest request) - { - _request = request; - } - - public object OriginalRequest - { - get { return _request; } - } - - public string RemoteIp - { - get { return _request.RemoteIp; } - } - - private NameValueCollection _headers; - public NameValueCollection Headers - { - get { return _headers ?? (_headers = Get(_request.Headers)); } - } - - private NameValueCollection _query; - public NameValueCollection QueryString - { - get { return _query ?? (_query = Get(_request.QueryString)); } - } - - private NameValueCollection Get(INameValueCollection coll) - { - var nv = new NameValueCollection(StringComparer.OrdinalIgnoreCase); - - foreach (var key in coll.AllKeys) - { - nv[key] = coll[key]; - } - - return nv; - //return coll.ToNameValueCollection(); - } - - public IDictionary<string, object> Items - { - get { return _request.Items; } - } - - public void AddResponseHeader(string name, string value) - { - _request.Response.AddHeader(name, value); - } - } -} diff --git a/MediaBrowser.Controller/Net/StaticResultOptions.cs b/MediaBrowser.Controller/Net/StaticResultOptions.cs index b5efc1b8fb..272fa8b3ba 100644 --- a/MediaBrowser.Controller/Net/StaticResultOptions.cs +++ b/MediaBrowser.Controller/Net/StaticResultOptions.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Net { @@ -31,11 +33,11 @@ namespace MediaBrowser.Controller.Net { public string Path { get; set; } - public FileShare FileShare { get; set; } + public FileShareMode FileShare { get; set; } public StaticFileResultOptions() { - FileShare = FileShare.Read; + FileShare = FileShareMode.Read; } } } diff --git a/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs index ffeaf286e2..0ad80d3748 100644 --- a/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs +++ b/MediaBrowser.Controller/Net/WebSocketConnectEventArgs.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Specialized; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -17,7 +18,7 @@ namespace MediaBrowser.Controller.Net /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - public NameValueCollection QueryString { get; set; } + public QueryParamCollection QueryString { get; set; } /// <summary> /// Gets or sets the web socket. /// </summary> @@ -46,7 +47,7 @@ namespace MediaBrowser.Controller.Net /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - public NameValueCollection QueryString { get; set; } + public QueryParamCollection QueryString { get; set; } /// <summary> /// Gets or sets a value indicating whether [allow connection]. /// </summary> @@ -55,7 +56,7 @@ namespace MediaBrowser.Controller.Net public WebSocketConnectingEventArgs() { - QueryString = new NameValueCollection(); + QueryString = new QueryParamCollection(); AllowConnection = true; } } diff --git a/MediaBrowser.Controller/News/INewsService.cs b/MediaBrowser.Controller/News/INewsService.cs deleted file mode 100644 index 8237764df4..0000000000 --- a/MediaBrowser.Controller/News/INewsService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using MediaBrowser.Model.News; -using MediaBrowser.Model.Querying; - -namespace MediaBrowser.Controller.News -{ - /// <summary> - /// Interface INewsFeed - /// </summary> - public interface INewsService - { - /// <summary> - /// Gets the product news. - /// </summary> - /// <param name="query">The query.</param> - /// <returns>QueryResult{NewsItem}.</returns> - QueryResult<NewsItem> GetProductNews(NewsQuery query); - } -} diff --git a/MediaBrowser.Controller/Persistence/IItemRepository.cs b/MediaBrowser.Controller/Persistence/IItemRepository.cs index 87937869d5..58ae1f3b0e 100644 --- a/MediaBrowser.Controller/Persistence/IItemRepository.cs +++ b/MediaBrowser.Controller/Persistence/IItemRepository.cs @@ -51,7 +51,7 @@ namespace MediaBrowser.Controller.Persistence /// <param name="items">The items.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task SaveItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken); + Task SaveItems(List<BaseItem> items, CancellationToken cancellationToken); /// <summary> /// Retrieves the item. @@ -147,7 +147,7 @@ namespace MediaBrowser.Controller.Persistence /// </summary> /// <param name="query">The query.</param> /// <returns>QueryResult<Tuple<Guid, System.String>>.</returns> - QueryResult<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query); + List<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query); /// <summary> /// Gets the item list. @@ -163,6 +163,8 @@ namespace MediaBrowser.Controller.Persistence /// <returns>Task.</returns> Task UpdateInheritedValues(CancellationToken cancellationToken); + int GetCount(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query); QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query); QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query); diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 6ab85f079c..02e736d999 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -5,7 +5,7 @@ using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; +using MediaBrowser.Model.Serialization; using System.Threading.Tasks; using MediaBrowser.Controller.Providers; diff --git a/MediaBrowser.Controller/Properties/AssemblyInfo.cs b/MediaBrowser.Controller/Properties/AssemblyInfo.cs index a5abf79ee1..844b93f37d 100644 --- a/MediaBrowser.Controller/Properties/AssemblyInfo.cs +++ b/MediaBrowser.Controller/Properties/AssemblyInfo.cs @@ -18,9 +18,6 @@ using System.Runtime.InteropServices; // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("bc09905a-04ed-497d-b39b-27593401e715")] - // Version information for an assembly consists of the following four values: // // Major Version diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs deleted file mode 100644 index 931af293cc..0000000000 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ /dev/null @@ -1,1392 +0,0 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Xml; - -namespace MediaBrowser.Controller.Providers -{ - /// <summary> - /// Provides a base class for parsing metadata xml - /// </summary> - /// <typeparam name="T"></typeparam> - public class BaseItemXmlParser<T> - where T : BaseItem - { - /// <summary> - /// The logger - /// </summary> - protected ILogger Logger { get; private set; } - protected IProviderManager ProviderManager { get; private set; } - - private Dictionary<string, string> _validProviderIds; - - /// <summary> - /// Initializes a new instance of the <see cref="BaseItemXmlParser{T}" /> class. - /// </summary> - /// <param name="logger">The logger.</param> - public BaseItemXmlParser(ILogger logger, IProviderManager providerManager) - { - Logger = logger; - ProviderManager = providerManager; - } - - /// <summary> - /// Fetches metadata for an item from one xml file - /// </summary> - /// <param name="item">The item.</param> - /// <param name="metadataFile">The metadata file.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <exception cref="System.ArgumentNullException"></exception> - public void Fetch(MetadataResult<T> item, string metadataFile, CancellationToken cancellationToken) - { - if (item == null) - { - throw new ArgumentNullException(); - } - - if (string.IsNullOrEmpty(metadataFile)) - { - throw new ArgumentNullException(); - } - - var settings = new XmlReaderSettings - { - CheckCharacters = false, - IgnoreProcessingInstructions = true, - IgnoreComments = true, - ValidationType = ValidationType.None - }; - - _validProviderIds = _validProviderIds = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); - - var idInfos = ProviderManager.GetExternalIdInfos(item.Item); - - foreach (var info in idInfos) - { - var id = info.Key + "Id"; - if (!_validProviderIds.ContainsKey(id)) - { - _validProviderIds.Add(id, info.Key); - } - } - - //Additional Mappings - _validProviderIds.Add("IMDB", "Imdb"); - - //Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken); - Fetch(item, metadataFile, settings, Encoding.UTF8, cancellationToken); - } - - /// <summary> - /// Fetches the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="metadataFile">The metadata file.</param> - /// <param name="settings">The settings.</param> - /// <param name="encoding">The encoding.</param> - /// <param name="cancellationToken">The cancellation token.</param> - private void Fetch(MetadataResult<T> item, string metadataFile, XmlReaderSettings settings, Encoding encoding, CancellationToken cancellationToken) - { - item.ResetPeople(); - - using (var streamReader = new StreamReader(metadataFile, encoding)) - { - // Use XmlReader for best performance - using (var reader = XmlReader.Create(streamReader, settings)) - { - reader.MoveToContent(); - - // Loop through each element - while (reader.Read()) - { - cancellationToken.ThrowIfCancellationRequested(); - - if (reader.NodeType == XmlNodeType.Element) - { - FetchDataFromXmlNode(reader, item); - } - } - } - } - } - - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - - /// <summary> - /// Fetches metadata from one Xml Element - /// </summary> - /// <param name="reader">The reader.</param> - /// <param name="itemResult">The item result.</param> - protected virtual void FetchDataFromXmlNode(XmlReader reader, MetadataResult<T> itemResult) - { - var item = itemResult.Item; - - switch (reader.Name) - { - // DateCreated - case "Added": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - DateTime added; - if (DateTime.TryParse(val, out added)) - { - item.DateCreated = added.ToUniversalTime(); - } - else - { - Logger.Warn("Invalid Added value found: " + val); - } - } - break; - } - - case "OriginalTitle": - { - var val = reader.ReadElementContentAsString(); - - var hasOriginalTitle = item as IHasOriginalTitle; - if (hasOriginalTitle != null) - { - if (!string.IsNullOrEmpty(hasOriginalTitle.OriginalTitle)) - { - hasOriginalTitle.OriginalTitle = val; - } - } - break; - } - - case "LocalTitle": - item.Name = reader.ReadElementContentAsString(); - break; - - case "Type": - { - var type = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(type) && !type.Equals("none", StringComparison.OrdinalIgnoreCase)) - { - item.DisplayMediaType = type; - } - - break; - } - - case "CriticRating": - { - var text = reader.ReadElementContentAsString(); - - if (!string.IsNullOrEmpty(text)) - { - float value; - if (float.TryParse(text, NumberStyles.Any, _usCulture, out value)) - { - item.CriticRating = value; - } - } - - break; - } - - case "Budget": - { - var text = reader.ReadElementContentAsString(); - var hasBudget = item as IHasBudget; - if (hasBudget != null) - { - double value; - if (double.TryParse(text, NumberStyles.Any, _usCulture, out value)) - { - hasBudget.Budget = value; - } - } - - break; - } - - case "Revenue": - { - var text = reader.ReadElementContentAsString(); - var hasBudget = item as IHasBudget; - if (hasBudget != null) - { - double value; - if (double.TryParse(text, NumberStyles.Any, _usCulture, out value)) - { - hasBudget.Revenue = value; - } - } - - break; - } - - case "Metascore": - { - var text = reader.ReadElementContentAsString(); - var hasMetascore = item as IHasMetascore; - if (hasMetascore != null) - { - float value; - if (float.TryParse(text, NumberStyles.Any, _usCulture, out value)) - { - hasMetascore.Metascore = value; - } - } - - break; - } - - case "AwardSummary": - { - var text = reader.ReadElementContentAsString(); - var hasAwards = item as IHasAwards; - if (hasAwards != null) - { - if (!string.IsNullOrWhiteSpace(text)) - { - hasAwards.AwardSummary = text; - } - } - - break; - } - - case "SortTitle": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.ForcedSortName = val; - } - break; - } - - case "Overview": - case "Description": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.Overview = val; - } - - break; - } - - case "ShortOverview": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.ShortOverview = val; - } - - break; - } - - case "CriticRatingSummary": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.CriticRatingSummary = val; - } - - break; - } - - case "Language": - { - var val = reader.ReadElementContentAsString(); - - item.PreferredMetadataLanguage = val; - - break; - } - - case "CountryCode": - { - var val = reader.ReadElementContentAsString(); - - item.PreferredMetadataCountryCode = val; - - break; - } - - case "PlaceOfBirth": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - var person = item as Person; - if (person != null) - { - person.ProductionLocations = new List<string> { val }; - } - } - - break; - } - - case "Website": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.HomePageUrl = val; - } - - break; - } - - case "LockedFields": - { - var fields = new List<MetadataFields>(); - - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - var list = val.Split('|').Select(i => - { - MetadataFields field; - - if (Enum.TryParse<MetadataFields>(i, true, out field)) - { - return (MetadataFields?)field; - } - - return null; - - }).Where(i => i.HasValue).Select(i => i.Value); - - fields.AddRange(list); - } - - item.LockedFields = fields; - - break; - } - - case "TagLines": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromTaglinesNode(subtree, item); - } - break; - } - - case "Countries": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromCountriesNode(subtree, item); - } - break; - } - - case "ContentRating": - case "MPAARating": - { - var rating = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(rating)) - { - item.OfficialRating = rating; - } - break; - } - - case "MPAADescription": - { - var rating = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(rating)) - { - item.OfficialRatingDescription = rating; - } - break; - } - - case "CustomRating": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.CustomRating = val; - } - break; - } - - case "RunningTime": - { - var text = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(text)) - { - int runtime; - if (int.TryParse(text.Split(' ')[0], NumberStyles.Integer, _usCulture, out runtime)) - { - item.RunTimeTicks = TimeSpan.FromMinutes(runtime).Ticks; - } - } - break; - } - - case "AspectRatio": - { - var val = reader.ReadElementContentAsString(); - - var hasAspectRatio = item as IHasAspectRatio; - if (!string.IsNullOrWhiteSpace(val) && hasAspectRatio != null) - { - hasAspectRatio.AspectRatio = val; - } - break; - } - - case "LockData": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.IsLocked = string.Equals("true", val, StringComparison.OrdinalIgnoreCase); - } - break; - } - - case "Network": - { - foreach (var name in SplitNames(reader.ReadElementContentAsString())) - { - if (string.IsNullOrWhiteSpace(name)) - { - continue; - } - item.AddStudio(name); - } - break; - } - - case "Director": - { - foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new Entities.PersonInfo { Name = v.Trim(), Type = PersonType.Director })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - itemResult.AddPerson(p); - } - break; - } - case "Writer": - { - foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new Entities.PersonInfo { Name = v.Trim(), Type = PersonType.Writer })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - itemResult.AddPerson(p); - } - break; - } - - case "Actors": - { - - var actors = reader.ReadInnerXml(); - - if (actors.Contains("<")) - { - // This is one of the mis-named "Actors" full nodes created by MB2 - // Create a reader and pass it to the persons node processor - FetchDataFromPersonsNode(new XmlTextReader(new StringReader("<Persons>" + actors + "</Persons>")), itemResult); - } - else - { - // Old-style piped string - foreach (var p in SplitNames(actors).Select(v => new Entities.PersonInfo { Name = v.Trim(), Type = PersonType.Actor })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - itemResult.AddPerson(p); - } - } - break; - } - - case "GuestStars": - { - foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new Entities.PersonInfo { Name = v.Trim(), Type = PersonType.GuestStar })) - { - if (string.IsNullOrWhiteSpace(p.Name)) - { - continue; - } - itemResult.AddPerson(p); - } - break; - } - - case "Trailer": - { - var val = reader.ReadElementContentAsString(); - - var hasTrailers = item as IHasTrailers; - if (hasTrailers != null) - { - if (!string.IsNullOrWhiteSpace(val)) - { - hasTrailers.AddTrailerUrl(val, false); - } - } - break; - } - - case "DisplayOrder": - { - var val = reader.ReadElementContentAsString(); - - var hasDisplayOrder = item as IHasDisplayOrder; - if (hasDisplayOrder != null) - { - if (!string.IsNullOrWhiteSpace(val)) - { - hasDisplayOrder.DisplayOrder = val; - } - } - break; - } - - case "Trailers": - { - using (var subtree = reader.ReadSubtree()) - { - var hasTrailers = item as IHasTrailers; - if (hasTrailers != null) - { - FetchDataFromTrailersNode(subtree, hasTrailers); - } - } - break; - } - - case "ProductionYear": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - int productionYear; - if (int.TryParse(val, out productionYear) && productionYear > 1850) - { - item.ProductionYear = productionYear; - } - } - - break; - } - - case "Rating": - case "IMDBrating": - { - - var rating = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(rating)) - { - float val; - // All external meta is saving this as '.' for decimal I believe...but just to be sure - if (float.TryParse(rating.Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out val)) - { - item.CommunityRating = val; - } - } - break; - } - - case "BirthDate": - case "PremiereDate": - case "FirstAired": - { - var firstAired = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(firstAired)) - { - DateTime airDate; - - if (DateTime.TryParseExact(firstAired, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out airDate) && airDate.Year > 1850) - { - item.PremiereDate = airDate.ToUniversalTime(); - item.ProductionYear = airDate.Year; - } - } - - break; - } - - case "DeathDate": - case "EndDate": - { - var firstAired = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(firstAired)) - { - DateTime airDate; - - if (DateTime.TryParseExact(firstAired, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out airDate) && airDate.Year > 1850) - { - item.EndDate = airDate.ToUniversalTime(); - } - } - - break; - } - - case "VoteCount": - { - var val = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(val)) - { - int num; - - if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num)) - { - item.VoteCount = num; - } - } - break; - } - case "CollectionNumber": - var tmdbCollection = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(tmdbCollection)) - { - item.SetProviderId(MetadataProviders.TmdbCollection, tmdbCollection); - } - break; - - case "Genres": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromGenresNode(subtree, item); - } - break; - } - - case "Tags": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromTagsNode(subtree, item); - } - break; - } - - case "PlotKeywords": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromKeywordsNode(subtree, item); - } - break; - } - - case "Persons": - { - using (var subtree = reader.ReadSubtree()) - { - FetchDataFromPersonsNode(subtree, itemResult); - } - break; - } - - case "Studios": - { - using (var subtree = reader.ReadSubtree()) - { - FetchFromStudiosNode(subtree, item); - } - break; - } - - case "Shares": - { - using (var subtree = reader.ReadSubtree()) - { - var hasShares = item as IHasShares; - if (hasShares != null) - { - FetchFromSharesNode(subtree, hasShares); - } - } - break; - } - - case "Format3D": - { - var video = item as Video; - - if (video != null) - { - var val = reader.ReadElementContentAsString(); - - if (string.Equals("HSBS", val, StringComparison.OrdinalIgnoreCase)) - { - video.Video3DFormat = Video3DFormat.HalfSideBySide; - } - else if (string.Equals("HTAB", val, StringComparison.OrdinalIgnoreCase)) - { - video.Video3DFormat = Video3DFormat.HalfTopAndBottom; - } - else if (string.Equals("FTAB", val, StringComparison.OrdinalIgnoreCase)) - { - video.Video3DFormat = Video3DFormat.FullTopAndBottom; - } - else if (string.Equals("FSBS", val, StringComparison.OrdinalIgnoreCase)) - { - video.Video3DFormat = Video3DFormat.FullSideBySide; - } - else if (string.Equals("MVC", val, StringComparison.OrdinalIgnoreCase)) - { - video.Video3DFormat = Video3DFormat.MVC; - } - } - break; - } - - default: - { - string readerName = reader.Name; - string providerIdValue; - if (_validProviderIds.TryGetValue(readerName, out providerIdValue)) - { - var id = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(id)) - { - item.SetProviderId(providerIdValue, id); - } - } - else - { - reader.Skip(); - } - - break; - - } - } - } - - private void FetchFromSharesNode(XmlReader reader, IHasShares item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Share": - { - using (var subtree = reader.ReadSubtree()) - { - var share = GetShareFromNode(subtree); - if (share != null) - { - item.Shares.Add(share); - } - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - private Share GetShareFromNode(XmlReader reader) - { - var share = new Share(); - - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "UserId": - { - share.UserId = reader.ReadElementContentAsString(); - break; - } - - case "CanEdit": - { - share.CanEdit = string.Equals(reader.ReadElementContentAsString(), true.ToString(), StringComparison.OrdinalIgnoreCase); - break; - } - - default: - reader.Skip(); - break; - } - } - } - - return share; - } - - private void FetchFromCountriesNode(XmlReader reader, T item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Country": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - /// <summary> - /// Fetches from taglines node. - /// </summary> - /// <param name="reader">The reader.</param> - /// <param name="item">The item.</param> - private void FetchFromTaglinesNode(XmlReader reader, T item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Tagline": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.Tagline = val; - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - /// <summary> - /// Fetches from genres node. - /// </summary> - /// <param name="reader">The reader.</param> - /// <param name="item">The item.</param> - private void FetchFromGenresNode(XmlReader reader, T item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Genre": - { - var genre = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(genre)) - { - item.AddGenre(genre); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - private void FetchFromTagsNode(XmlReader reader, BaseItem item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Tag": - { - var tag = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(tag)) - { - item.AddTag(tag); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - private void FetchFromKeywordsNode(XmlReader reader, BaseItem item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "PlotKeyword": - { - var tag = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(tag)) - { - item.AddKeyword(tag); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - /// <summary> - /// Fetches the data from persons node. - /// </summary> - /// <param name="reader">The reader.</param> - /// <param name="item">The item.</param> - private void FetchDataFromPersonsNode(XmlReader reader, MetadataResult<T> item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Person": - case "Actor": - { - using (var subtree = reader.ReadSubtree()) - { - foreach (var person in GetPersonsFromXmlNode(subtree)) - { - if (string.IsNullOrWhiteSpace(person.Name)) - { - continue; - } - item.AddPerson(person); - } - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - private void FetchDataFromTrailersNode(XmlReader reader, IHasTrailers item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Trailer": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - item.AddTrailerUrl(val, false); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - protected List<ChapterInfo> FetchChaptersFromXmlNode(BaseItem item, XmlReader reader) - { - using (reader) - { - return GetChaptersFromXmlNode(reader) - .Where(i => i.StartPositionTicks >= 0) - .ToList(); - } - } - - private IEnumerable<ChapterInfo> GetChaptersFromXmlNode(XmlReader reader) - { - var chapters = new List<ChapterInfo>(); - - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Chapter": - { - using (var subtree = reader.ReadSubtree()) - { - chapters.Add(GetChapterInfoFromXmlNode(subtree)); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - - return chapters; - } - - private ChapterInfo GetChapterInfoFromXmlNode(XmlReader reader) - { - var chapter = new ChapterInfo(); - - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "StartPositionMs": - { - var val = reader.ReadElementContentAsString(); - - var ms = long.Parse(val, _usCulture); - - chapter.StartPositionTicks = TimeSpan.FromMilliseconds(ms).Ticks; - - break; - } - - case "Name": - { - chapter.Name = reader.ReadElementContentAsString(); - break; - } - - default: - reader.Skip(); - break; - } - } - } - - return chapter; - } - - /// <summary> - /// Fetches from studios node. - /// </summary> - /// <param name="reader">The reader.</param> - /// <param name="item">The item.</param> - private void FetchFromStudiosNode(XmlReader reader, T item) - { - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Studio": - { - var studio = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(studio)) - { - item.AddStudio(studio); - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - } - - /// <summary> - /// Gets the persons from XML node. - /// </summary> - /// <param name="reader">The reader.</param> - /// <returns>IEnumerable{PersonInfo}.</returns> - private IEnumerable<PersonInfo> GetPersonsFromXmlNode(XmlReader reader) - { - var name = string.Empty; - var type = PersonType.Actor; // If type is not specified assume actor - var role = string.Empty; - int? sortOrder = null; - - reader.MoveToContent(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Name": - name = reader.ReadElementContentAsString() ?? string.Empty; - break; - - case "Type": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - type = val; - } - break; - } - - case "Role": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - role = val; - } - break; - } - case "SortOrder": - { - var val = reader.ReadElementContentAsString(); - - if (!string.IsNullOrWhiteSpace(val)) - { - int intVal; - if (int.TryParse(val, NumberStyles.Integer, _usCulture, out intVal)) - { - sortOrder = intVal; - } - } - break; - } - - default: - reader.Skip(); - break; - } - } - } - - var personInfo = new PersonInfo - { - Name = name.Trim(), - Role = role, - Type = type, - SortOrder = sortOrder - }; - - return new[] { personInfo }; - } - - protected LinkedChild GetLinkedChild(XmlReader reader) - { - reader.MoveToContent(); - - var linkedItem = new LinkedChild - { - Type = LinkedChildType.Manual - }; - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "Path": - { - linkedItem.Path = reader.ReadElementContentAsString(); - break; - } - - default: - reader.Skip(); - break; - } - } - } - - // This is valid - if (!string.IsNullOrWhiteSpace(linkedItem.Path)) - { - return linkedItem; - } - - return null; - } - - protected Share GetShare(XmlReader reader) - { - reader.MoveToContent(); - - var item = new Share(); - - while (reader.Read()) - { - if (reader.NodeType == XmlNodeType.Element) - { - switch (reader.Name) - { - case "UserId": - { - item.UserId = reader.ReadElementContentAsString(); - break; - } - - case "CanEdit": - { - item.CanEdit = string.Equals(reader.ReadElementContentAsString(), "true", StringComparison.OrdinalIgnoreCase); - break; - } - - default: - reader.Skip(); - break; - } - } - } - - // This is valid - if (!string.IsNullOrWhiteSpace(item.UserId)) - { - return item; - } - - return null; - } - - - /// <summary> - /// Used to split names of comma or pipe delimeted genres and people - /// </summary> - /// <param name="value">The value.</param> - /// <returns>IEnumerable{System.String}.</returns> - private IEnumerable<string> SplitNames(string value) - { - value = value ?? string.Empty; - - // Only split by comma if there is no pipe in the string - // We have to be careful to not split names like Matthew, Jr. - var separator = value.IndexOf('|') == -1 && value.IndexOf(';') == -1 ? new[] { ',' } : new[] { '|', ';' }; - - value = value.Trim().Trim(separator); - - return string.IsNullOrWhiteSpace(value) ? new string[] { } : Split(value, separator, StringSplitOptions.RemoveEmptyEntries); - } - - /// <summary> - /// Provides an additional overload for string.split - /// </summary> - /// <param name="val">The val.</param> - /// <param name="separators">The separators.</param> - /// <param name="options">The options.</param> - /// <returns>System.String[][].</returns> - private static string[] Split(string val, char[] separators, StringSplitOptions options) - { - return val.Split(separators, options); - } - - } -} diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index ee2b28c60a..01218c293a 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -4,7 +4,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Providers { @@ -74,7 +76,7 @@ namespace MediaBrowser.Controller.Providers entries[item.FullName] = item; } } - catch (DirectoryNotFoundException) + catch (IOException) { } diff --git a/MediaBrowser.Controller/Providers/IDirectoryService.cs b/MediaBrowser.Controller/Providers/IDirectoryService.cs index 09f9ba8c02..54ae7e12be 100644 --- a/MediaBrowser.Controller/Providers/IDirectoryService.cs +++ b/MediaBrowser.Controller/Providers/IDirectoryService.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Providers { diff --git a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs index 9b21a29724..691ce1ab07 100644 --- a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs @@ -12,6 +12,7 @@ namespace MediaBrowser.Controller.Providers public List<ImageType> ReplaceImages { get; set; } public bool IsAutomated { get; set; } + public bool ForceEnableInternetMetadata { get; set; } public ImageRefreshOptions(IDirectoryService directoryService) { diff --git a/MediaBrowser.Controller/Providers/LocalImageInfo.cs b/MediaBrowser.Controller/Providers/LocalImageInfo.cs index 14f292bece..63651fce85 100644 --- a/MediaBrowser.Controller/Providers/LocalImageInfo.cs +++ b/MediaBrowser.Controller/Providers/LocalImageInfo.cs @@ -1,5 +1,7 @@ -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Providers { diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs index 87c3b36a27..7d9dab92b2 100644 --- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs @@ -1,5 +1,7 @@ using System.Linq; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; diff --git a/MediaBrowser.Controller/Resolvers/IItemResolver.cs b/MediaBrowser.Controller/Resolvers/IItemResolver.cs index bdff5fffad..fcb162b9e6 100644 --- a/MediaBrowser.Controller/Resolvers/IItemResolver.cs +++ b/MediaBrowser.Controller/Resolvers/IItemResolver.cs @@ -2,7 +2,9 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using System.Collections.Generic; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Resolvers { diff --git a/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs b/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs index 2c82882c68..06372395ec 100644 --- a/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs +++ b/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs @@ -1,5 +1,7 @@ -using CommonIO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Resolvers { diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index b3e82f9258..343b15a04f 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Session; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.Session { @@ -106,7 +107,9 @@ namespace MediaBrowser.Controller.Session /// </summary> /// <value>The now playing item.</value> public BaseItemInfo NowPlayingItem { get; set; } - + + public BaseItem FullNowPlayingItem { get; set; } + /// <summary> /// Gets or sets the device id. /// </summary> diff --git a/MediaBrowser.Controller/Social/ISharingManager.cs b/MediaBrowser.Controller/Social/ISharingManager.cs deleted file mode 100644 index ded37771af..0000000000 --- a/MediaBrowser.Controller/Social/ISharingManager.cs +++ /dev/null @@ -1,28 +0,0 @@ -using MediaBrowser.Model.Social; -using System.Threading.Tasks; - -namespace MediaBrowser.Controller.Social -{ - public interface ISharingManager - { - /// <summary> - /// Creates the share. - /// </summary> - /// <param name="itemId">The item identifier.</param> - /// <param name="userId">The user identifier.</param> - /// <returns>Task<SocialShareInfo>.</returns> - Task<SocialShareInfo> CreateShare(string itemId, string userId); - /// <summary> - /// Gets the share information. - /// </summary> - /// <param name="id">The identifier.</param> - /// <returns>SocialShareInfo.</returns> - SocialShareInfo GetShareInfo(string id); - /// <summary> - /// Deletes the share. - /// </summary> - /// <param name="id">The identifier.</param> - /// <returns>Task.</returns> - Task DeleteShare(string id); - } -} diff --git a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs index 36ad27290d..3913e86f03 100644 --- a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs +++ b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs @@ -1,10 +1,10 @@ using MediaBrowser.Model.Querying; using MediaBrowser.Model.Sync; -using Interfaces.IO; using System; using System.IO; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.IO; namespace MediaBrowser.Controller.Sync { @@ -40,14 +40,8 @@ namespace MediaBrowser.Controller.Sync /// <returns>Task<Stream>.</returns> Task<Stream> GetFile(string id, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken); - /// <summary> - /// Gets the files. - /// </summary> - /// <param name="query">The query.</param> - /// <param name="target">The target.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task<QueryResult<FileMetadata>>.</returns> - Task<QueryResult<FileMetadata>> GetFiles(FileQuery query, SyncTarget target, CancellationToken cancellationToken); + Task<QueryResult<FileSystemMetadata>> GetFiles(string[] pathParts, SyncTarget target, CancellationToken cancellationToken); + Task<QueryResult<FileSystemMetadata>> GetFiles(SyncTarget target, CancellationToken cancellationToken); } public interface ISupportsDirectCopy diff --git a/MediaBrowser.Controller/TV/ITVSeriesManager.cs b/MediaBrowser.Controller/TV/ITVSeriesManager.cs index 3d6e87474c..771fa602a0 100644 --- a/MediaBrowser.Controller/TV/ITVSeriesManager.cs +++ b/MediaBrowser.Controller/TV/ITVSeriesManager.cs @@ -19,6 +19,6 @@ namespace MediaBrowser.Controller.TV /// <param name="request">The request.</param> /// <param name="parentsFolders">The parents folders.</param> /// <returns>QueryResult<BaseItem>.</returns> - QueryResult<BaseItem> GetNextUp(NextUpQuery request, IEnumerable<Folder> parentsFolders); + QueryResult<BaseItem> GetNextUp(NextUpQuery request, List<Folder> parentsFolders); } } diff --git a/MediaBrowser.Controller/packages.config b/MediaBrowser.Controller/packages.config deleted file mode 100644 index 84422d9da9..0000000000 --- a/MediaBrowser.Controller/packages.config +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="CommonIO" version="1.0.0.9" targetFramework="net45" /> - <package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" /> - <package id="morelinq" version="1.4.0" targetFramework="net45" /> - <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> -</packages>
\ No newline at end of file diff --git a/MediaBrowser.Controller/project.json b/MediaBrowser.Controller/project.json new file mode 100644 index 0000000000..fbbe9eaf32 --- /dev/null +++ b/MediaBrowser.Controller/project.json @@ -0,0 +1,17 @@ +{ + "frameworks":{ + "netstandard1.6":{ + "dependencies":{ + "NETStandard.Library":"1.6.0", + } + }, + ".NETPortable,Version=v4.5,Profile=Profile7":{ + "buildOptions": { + "define": [ ] + }, + "frameworkAssemblies":{ + + } + } + } +}
\ No newline at end of file |
