Merge pull request #2350 from MediaBrowser/beta

Beta
This commit is contained in:
Luke
2016-12-18 00:44:33 -05:00
committed by GitHub
1520 changed files with 60595 additions and 28065 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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; }
}
}

View File

@@ -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);
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
}

View File

@@ -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
{

View File

@@ -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>
@@ -38,15 +34,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
{
@@ -74,6 +61,12 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return true; }
}
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
}
[IgnoreDataMember]
protected override bool SupportsOwnedItems
{

View File

@@ -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;
}
}
}
}

View File

@@ -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;
@@ -32,6 +32,12 @@ namespace MediaBrowser.Controller.Entities.Audio
get { return true; }
}
[IgnoreDataMember]
public override bool SupportsInheritedParentImages
{
get { return true; }
}
[IgnoreDataMember]
public MusicArtist MusicArtist
{

View File

@@ -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
{

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@

using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
{

View File

@@ -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
@@ -18,6 +18,8 @@ namespace MediaBrowser.Controller.Entities
}
}
[IgnoreDataMember]
public string SeriesPresentationUniqueKey { get; set; }
[IgnoreDataMember]
public string SeriesName { get; set; }
[IgnoreDataMember]
@@ -33,6 +35,10 @@ namespace MediaBrowser.Controller.Entities
{
return SeriesName;
}
public string FindSeriesPresentationUniqueKey()
{
return SeriesPresentationUniqueKey;
}
[IgnoreDataMember]
public override bool EnableRefreshOnDateModifiedChange

View File

@@ -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;
@@ -260,25 +307,6 @@ namespace MediaBrowser.Controller.Entities
return Task.FromResult(true);
}
/// <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>
@@ -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();

View File

@@ -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)
{
Recursive = true,
IsFolder = false,
IsVirtualItem = false,
EnableTotalRecordCount = true,
Limit = 0,
IsPlayed = false
}).ConfigureAwait(false);
var allItemsQueryResult = await GetItems(new InternalItemsQuery(user)
{
Recursive = true,
IsFolder = false,
IsVirtualItem = false,
EnableTotalRecordCount = true,
Limit = 0
}).ConfigureAwait(false);
if (itemDto != null)
{
itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount;
}
var recursiveItemCount = allItemsQueryResult.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 (itemFields.Contains(ItemFields.RecursiveItemCount))
{
itemDto.ChildCount = recursiveItemCount;
itemDto.RecursiveItemCount = GetRecursiveChildCount(user);
}
}
if (SupportsPlayedStatus)
{
var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
{
Recursive = true,
IsFolder = false,
IsVirtualItem = false,
EnableTotalRecordCount = true,
Limit = 0,
IsPlayed = false
}).ConfigureAwait(false);
double unplayedCount = unplayedQueryResult.TotalRecordCount;
dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
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
{
dto.Played = (dto.UnplayedItemCount ?? 0) == 0;
}
}
}

View File

@@ -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
{

View File

@@ -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>

View File

@@ -1,4 +1,4 @@
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using System;

View File

@@ -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;

View File

@@ -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
{

View File

@@ -1,8 +0,0 @@

namespace MediaBrowser.Controller.Entities
{
public interface IHasOriginalTitle
{
string OriginalTitle { get; set; }
}
}

View File

@@ -15,5 +15,7 @@ namespace MediaBrowser.Controller.Entities
string FindSeriesSortName();
Guid? SeriesId { get; set; }
Guid? FindSeriesId();
string SeriesPresentationUniqueKey { get; set; }
string FindSeriesPresentationUniqueKey();
}
}

View File

@@ -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; }

View File

@@ -1,8 +0,0 @@

namespace MediaBrowser.Controller.Entities
{
public interface IThemeMedia
{
bool IsThemeMedia { get; }
}
}

View File

@@ -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; }

View File

@@ -1,6 +1,6 @@
using MediaBrowser.Model.Entities;
using System;
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
{

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
{

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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));

View File

@@ -1,6 +1,6 @@
using MediaBrowser.Model.Drawing;
using System.Linq;
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
{

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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()

View File

@@ -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
{
@@ -40,14 +39,16 @@ 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]
@@ -202,12 +203,21 @@ namespace MediaBrowser.Controller.Entities.TV
return UnratedItem.Series;
}
[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;

View File

@@ -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 }
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,5 +1,5 @@
using System;
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities
{

View File

@@ -1,4 +1,4 @@
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Querying;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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>
@@ -111,12 +109,6 @@ namespace MediaBrowser.Controller.Entities
public bool IsShortcut { get; set; }
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>

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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
{

View File

@@ -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
}
}

View File

@@ -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);

View File

@@ -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&lt;BaseItem&gt;.</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);
}
}

View File

@@ -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

View File

@@ -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
{
@@ -96,18 +98,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>

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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
{
@@ -38,6 +38,15 @@ namespace MediaBrowser.Controller.LiveTv
}
}
[IgnoreDataMember]
public override bool SupportsPositionTicksResume
{
get
{
return false;
}
}
[IgnoreDataMember]
public override SourceType SourceType
{

View File

@@ -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();

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
using System.Runtime.Serialization;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Users;

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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
{

View File

@@ -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)

View File

@@ -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,20 +35,11 @@ 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.
/// &lt;0 Executed before global request filters
@@ -60,7 +51,6 @@ namespace MediaBrowser.Controller.Net
get { return 0; }
}
public IEnumerable<string> GetRoles()
{
return (Roles ?? string.Empty).Split(',')

View File

@@ -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; }
}
}

View File

@@ -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);
}
}

View File

@@ -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; }
}
}

View File

@@ -1,4 +1,4 @@
using ServiceStack.Web;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net
{

View File

@@ -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; }
}
}

View File

@@ -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.

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net
{
@@ -14,19 +15,11 @@ namespace MediaBrowser.Controller.Net
/// <value>The URL prefix.</value>
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

View File

@@ -1,12 +0,0 @@
using ServiceStack;
namespace MediaBrowser.Controller.Net
{
/// <summary>
/// Interface IRestfulService
/// </summary>
[Logged]
public interface IRestfulService : IService
{
}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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.

View File

@@ -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.
/// &lt;0 Executed before global request filters
/// &gt;0 Executed after global request filters
/// </summary>
/// <value>The priority.</value>
public int Priority
{
get { return 0; }
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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&lt;Tuple&lt;Guid, System.String&gt;&gt;.</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);

View File

@@ -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;

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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)
{
}

View File

@@ -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
{

View File

@@ -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)
{

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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
{

Some files were not shown because too many files have changed in this diff Show More