diff --git a/Emby.Common.Implementations/Emby.Common.Implementations.csproj b/Emby.Common.Implementations/Emby.Common.Implementations.csproj index 00c90d16e4..cbd077e199 100644 --- a/Emby.Common.Implementations/Emby.Common.Implementations.csproj +++ b/Emby.Common.Implementations/Emby.Common.Implementations.csproj @@ -32,8 +32,7 @@ - ..\packages\NLog.4.4.11\lib\net45\NLog.dll - True + ..\packages\NLog.4.4.12\lib\net45\NLog.dll ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll diff --git a/Emby.Common.Implementations/Logging/NlogManager.cs b/Emby.Common.Implementations/Logging/NlogManager.cs index f7b723e8bc..4446e2cdb9 100644 --- a/Emby.Common.Implementations/Logging/NlogManager.cs +++ b/Emby.Common.Implementations/Logging/NlogManager.cs @@ -152,13 +152,23 @@ namespace Emby.Common.Implementations.Logging RemoveTarget("ApplicationLogFileWrapper"); - var wrapper = new AsyncTargetWrapper(); + // https://github.com/NLog/NLog/wiki/Performance + var wrapper = new AsyncTargetWrapper + { + OverflowAction = AsyncTargetWrapperOverflowAction.Block, + QueueLimit = 10000, + BatchSize = 500, + TimeToSleepBetweenBatches = 50 + }; + wrapper.Name = "ApplicationLogFileWrapper"; var logFile = new FileTarget { FileName = path, - Layout = "${longdate} ${level} ${logger}: ${message}" + Layout = "${longdate} ${level} ${logger}: ${message}", + KeepFileOpen = true, + ConcurrentWrites = false }; logFile.Name = "ApplicationLogFile"; diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs index df1099d3df..542d16d24e 100644 --- a/Emby.Common.Implementations/Net/UdpSocket.cs +++ b/Emby.Common.Implementations/Net/UdpSocket.cs @@ -37,8 +37,6 @@ namespace Emby.Common.Implementations.Net private TaskCompletionSource _currentReceiveTaskCompletionSource; private TaskCompletionSource _currentSendTaskCompletionSource; - private readonly SemaphoreSlim _sendLock = new SemaphoreSlim(1, 1); - public UdpSocket(Socket socket, int localPort, IPAddress ip) { if (socket == null) throw new ArgumentNullException("socket"); @@ -234,8 +232,6 @@ namespace Emby.Common.Implementations.Net if (socket != null) socket.Dispose(); - _sendLock.Dispose(); - var tcs = _currentReceiveTaskCompletionSource; if (tcs != null) { diff --git a/Emby.Common.Implementations/Networking/NetworkManager.cs b/Emby.Common.Implementations/Networking/NetworkManager.cs index 2f218656c9..354107bb7a 100644 --- a/Emby.Common.Implementations/Networking/NetworkManager.cs +++ b/Emby.Common.Implementations/Networking/NetworkManager.cs @@ -506,7 +506,7 @@ namespace Emby.Common.Implementations.Networking public async Task GetHostAddressesAsync(string host) { var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); - return addresses.Select(ToIpAddressInfo).ToArray(); + return addresses.Select(ToIpAddressInfo).ToArray(addresses.Length); } /// diff --git a/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index c373ffddb9..dd840677a3 100644 --- a/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -14,6 +14,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Extensions; namespace Emby.Common.Implementations.ScheduledTasks { @@ -274,7 +275,8 @@ namespace Emby.Common.Implementations.ScheduledTasks { get { - return InternalTriggers.Select(i => i.Item1).ToArray(); + var triggers = InternalTriggers; + return triggers.Select(i => i.Item1).ToArray(triggers.Length); } set { @@ -288,7 +290,7 @@ namespace Emby.Common.Implementations.ScheduledTasks SaveTriggers(triggerList); - InternalTriggers = triggerList.Select(i => new Tuple(i, GetTrigger(i))).ToArray(); + InternalTriggers = triggerList.Select(i => new Tuple(i, GetTrigger(i))).ToArray(triggerList.Length); } } diff --git a/Emby.Common.Implementations/packages.config b/Emby.Common.Implementations/packages.config index a255465cc7..eb8fd586ef 100644 --- a/Emby.Common.Implementations/packages.config +++ b/Emby.Common.Implementations/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/Emby.Dlna/ContentDirectory/ContentDirectory.cs b/Emby.Dlna/ContentDirectory/ContentDirectory.cs index 4a36a16eb6..92d388e3b2 100644 --- a/Emby.Dlna/ContentDirectory/ContentDirectory.cs +++ b/Emby.Dlna/ContentDirectory/ContentDirectory.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Linq; using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Controller.TV; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Xml; @@ -31,6 +32,7 @@ namespace Emby.Dlna.ContentDirectory private readonly IUserViewManager _userViewManager; private readonly Func _mediaEncoder; protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory; + private readonly ITVSeriesManager _tvSeriesManager; public ContentDirectory(IDlnaManager dlna, IUserDataManager userDataManager, @@ -39,7 +41,7 @@ namespace Emby.Dlna.ContentDirectory IServerConfigurationManager config, IUserManager userManager, ILogger logger, - IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, Func mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory) + IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, Func mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory, ITVSeriesManager tvSeriesManager) : base(logger, httpClient) { _dlna = dlna; @@ -54,6 +56,7 @@ namespace Emby.Dlna.ContentDirectory _userViewManager = userViewManager; _mediaEncoder = mediaEncoder; XmlReaderSettingsFactory = xmlReaderSettingsFactory; + _tvSeriesManager = tvSeriesManager; } private int SystemUpdateId @@ -97,7 +100,8 @@ namespace Emby.Dlna.ContentDirectory _mediaSourceManager, _userViewManager, _mediaEncoder(), - XmlReaderSettingsFactory) + XmlReaderSettingsFactory, + _tvSeriesManager) .ProcessControlRequest(request); } diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 9345a1df71..96b282d04b 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -27,8 +27,10 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.TV; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Xml; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.ContentDirectory { @@ -40,6 +42,7 @@ namespace Emby.Dlna.ContentDirectory private readonly IServerConfigurationManager _config; private readonly User _user; private readonly IUserViewManager _userViewManager; + private readonly ITVSeriesManager _tvSeriesManager; private const string NS_DC = "http://purl.org/dc/elements/1.1/"; private const string NS_DIDL = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"; @@ -53,7 +56,7 @@ namespace Emby.Dlna.ContentDirectory private readonly DeviceProfile _profile; - public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory) + public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory, ITVSeriesManager tvSeriesManager) : base(config, logger, xmlReaderSettingsFactory) { _libraryManager = libraryManager; @@ -62,6 +65,7 @@ namespace Emby.Dlna.ContentDirectory _systemUpdateId = systemUpdateId; _channelManager = channelManager; _userViewManager = userViewManager; + _tvSeriesManager = tvSeriesManager; _profile = profile; _config = config; @@ -454,14 +458,14 @@ namespace Emby.Dlna.ContentDirectory { Limit = limit, StartIndex = startIndex, - SortBy = sortOrders.ToArray(), + SortBy = sortOrders.ToArray(sortOrders.Count), SortOrder = sort.SortOrder, User = user, Recursive = true, IsMissing = false, ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name }, IsFolder = isFolder, - MediaTypes = mediaTypes.ToArray(), + MediaTypes = mediaTypes.ToArray(mediaTypes.Count), DtoOptions = GetDtoOptions() }); } @@ -488,6 +492,14 @@ namespace Emby.Dlna.ContentDirectory { return GetMusicFolders(item, user, stubType, sort, startIndex, limit); } + if (collectionFolder != null && string.Equals(CollectionType.Movies, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase)) + { + return GetMovieFolders(item, user, stubType, sort, startIndex, limit); + } + if (collectionFolder != null && string.Equals(CollectionType.TvShows, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase)) + { + return GetTvFolders(item, user, stubType, sort, startIndex, limit); + } if (stubType.HasValue) { @@ -497,12 +509,12 @@ namespace Emby.Dlna.ContentDirectory { ItemId = item.Id - }).ToArray(); + }); var result = new QueryResult { - Items = items.Select(i => new ServerItem(i)).ToArray(), - TotalRecordCount = items.Length + Items = items.Select(i => new ServerItem(i)).ToArray(items.Count), + TotalRecordCount = items.Count }; return ApplyPaging(result, startIndex, limit); @@ -524,8 +536,8 @@ namespace Emby.Dlna.ContentDirectory Limit = limit, StartIndex = startIndex, User = user, - IsMissing = false, - PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows }, + IsVirtualItem = false, + PresetViews = new string[] { }, ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name }, IsPlaceHolder = false, DtoOptions = GetDtoOptions() @@ -651,11 +663,236 @@ namespace Emby.Dlna.ContentDirectory return new QueryResult { - Items = list.ToArray(), + Items = list.ToArray(list.Count), TotalRecordCount = list.Count }; } + private QueryResult GetMovieFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) + { + var query = new InternalItemsQuery(user) + { + StartIndex = startIndex, + Limit = limit + }; + SetSorting(query, sort, false); + + if (stubType.HasValue && stubType.Value == StubType.ContinueWatching) + { + return GetMovieContinueWatching(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Latest) + { + return GetMovieLatest(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Movies) + { + return GetMovieMovies(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Collections) + { + return GetMovieCollections(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Favorites) + { + return GetMovieFavorites(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Genres) + { + return GetGenres(item, user, query); + } + + var list = new List(); + + list.Add(new ServerItem(item) + { + StubType = StubType.ContinueWatching + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Latest + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Movies + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Collections + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Favorites + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Genres + }); + + return new QueryResult + { + Items = list.ToArray(list.Count), + TotalRecordCount = list.Count + }; + } + + private QueryResult GetTvFolders(BaseItem item, User user, StubType? stubType, SortCriteria sort, int? startIndex, int? limit) + { + var query = new InternalItemsQuery(user) + { + StartIndex = startIndex, + Limit = limit + }; + SetSorting(query, sort, false); + + if (stubType.HasValue && stubType.Value == StubType.ContinueWatching) + { + return GetMovieContinueWatching(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.NextUp) + { + return GetNextUp(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Latest) + { + return GetTvLatest(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Series) + { + return GetSeries(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.FavoriteSeries) + { + return GetFavoriteSeries(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.FavoriteEpisodes) + { + return GetFavoriteEpisodes(item, user, query); + } + + if (stubType.HasValue && stubType.Value == StubType.Genres) + { + return GetGenres(item, user, query); + } + + var list = new List(); + + list.Add(new ServerItem(item) + { + StubType = StubType.ContinueWatching + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.NextUp + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Latest + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Series + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.FavoriteSeries + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.FavoriteEpisodes + }); + + list.Add(new ServerItem(item) + { + StubType = StubType.Genres + }); + + return new QueryResult + { + Items = list.ToArray(list.Count), + TotalRecordCount = list.Count + }; + } + + private QueryResult GetMovieContinueWatching(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + query.Parent = parent; + query.SetUser(user); + + query.OrderBy = new List> + { + new Tuple (ItemSortBy.DatePlayed, SortOrder.Descending), + new Tuple (ItemSortBy.SortName, SortOrder.Ascending) + }; + + query.IsResumable = true; + query.Limit = 10; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + + private QueryResult GetSeries(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + query.Parent = parent; + query.SetUser(user); + + query.IncludeItemTypes = new[] { typeof(Series).Name }; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + + private QueryResult GetMovieMovies(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + query.Parent = parent; + query.SetUser(user); + + query.IncludeItemTypes = new[] { typeof(Movie).Name }; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + + private QueryResult GetMovieCollections(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + //query.Parent = parent; + query.SetUser(user); + + query.IncludeItemTypes = new[] { typeof(BoxSet).Name }; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + private QueryResult GetMusicAlbums(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -695,6 +932,45 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + private QueryResult GetFavoriteSeries(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + query.Parent = parent; + query.SetUser(user); + query.IsFavorite = true; + query.IncludeItemTypes = new[] { typeof(Series).Name }; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + + private QueryResult GetFavoriteEpisodes(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + query.Parent = parent; + query.SetUser(user); + query.IsFavorite = true; + query.IncludeItemTypes = new[] { typeof(Episode).Name }; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + + private QueryResult GetMovieFavorites(BaseItem parent, User user, InternalItemsQuery query) + { + query.Recursive = true; + query.Parent = parent; + query.SetUser(user); + query.IsFavorite = true; + query.IncludeItemTypes = new[] { typeof(Movie).Name }; + + var result = _libraryManager.GetItemsResult(query); + + return ToResult(result); + } + private QueryResult GetFavoriteAlbums(BaseItem parent, User user, InternalItemsQuery query) { query.Recursive = true; @@ -708,6 +984,24 @@ namespace Emby.Dlna.ContentDirectory return ToResult(result); } + private QueryResult GetGenres(BaseItem parent, User user, InternalItemsQuery query) + { + var genresResult = _libraryManager.GetGenres(new InternalItemsQuery(user) + { + AncestorIds = new[] { parent.Id.ToString("N") }, + StartIndex = query.StartIndex, + Limit = query.Limit + }); + + var result = new QueryResult + { + TotalRecordCount = genresResult.TotalRecordCount, + Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length) + }; + + return ToResult(result); + } + private QueryResult GetMusicGenres(BaseItem parent, User user, InternalItemsQuery query) { var genresResult = _libraryManager.GetMusicGenres(new InternalItemsQuery(user) @@ -720,7 +1014,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = genresResult.TotalRecordCount, - Items = genresResult.Items.Select(i => i.Item1).ToArray() + Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length) }; return ToResult(result); @@ -738,7 +1032,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = artists.TotalRecordCount, - Items = artists.Items.Select(i => i.Item1).ToArray() + Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length) }; return ToResult(result); @@ -756,7 +1050,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = artists.TotalRecordCount, - Items = artists.Items.Select(i => i.Item1).ToArray() + Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length) }; return ToResult(result); @@ -775,7 +1069,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = artists.TotalRecordCount, - Items = artists.Items.Select(i => i.Item1).ToArray() + Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length) }; return ToResult(result); @@ -810,6 +1104,55 @@ namespace Emby.Dlna.ContentDirectory return ToResult(items); } + private QueryResult GetNextUp(BaseItem parent, User user, InternalItemsQuery query) + { + query.SortBy = new string[] { }; + + var result = _tvSeriesManager.GetNextUp(new NextUpQuery + { + Limit = query.Limit, + StartIndex = query.StartIndex, + UserId = query.User.Id.ToString("N") + + }, new List { (Folder)parent }, query.DtoOptions); + + return ToResult(result); + } + + private QueryResult GetTvLatest(BaseItem parent, User user, InternalItemsQuery query) + { + query.SortBy = new string[] { }; + + var items = _userViewManager.GetLatestItems(new LatestItemsQuery + { + UserId = user.Id.ToString("N"), + Limit = 50, + IncludeItemTypes = new[] { typeof(Episode).Name }, + ParentId = parent == null ? null : parent.Id.ToString("N"), + GroupItems = false + + }, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToList(); + + return ToResult(items); + } + + private QueryResult GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query) + { + query.SortBy = new string[] { }; + + var items = _userViewManager.GetLatestItems(new LatestItemsQuery + { + UserId = user.Id.ToString("N"), + Limit = 50, + IncludeItemTypes = new[] { typeof(Movie).Name }, + ParentId = parent == null ? null : parent.Id.ToString("N"), + GroupItems = true + + }, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null).ToList(); + + return ToResult(items); + } + private QueryResult GetMusicArtistItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit) { var query = new InternalItemsQuery(user) @@ -854,7 +1197,7 @@ namespace Emby.Dlna.ContentDirectory { var serverItems = result .Select(i => new ServerItem(i)) - .ToArray(); + .ToArray(result.Count); return new QueryResult { @@ -868,7 +1211,7 @@ namespace Emby.Dlna.ContentDirectory var serverItems = result .Items .Select(i => new ServerItem(i)) - .ToArray(); + .ToArray(result.Items.Length); return new QueryResult { @@ -885,7 +1228,7 @@ namespace Emby.Dlna.ContentDirectory sortOrders.Add(ItemSortBy.SortName); } - query.SortBy = sortOrders.ToArray(); + query.SortBy = sortOrders.ToArray(sortOrders.Count); query.SortOrder = sort.SortOrder; } @@ -901,8 +1244,7 @@ namespace Emby.Dlna.ContentDirectory DtoOptions = GetDtoOptions() }); - var serverItems = itemsResult.Items.Select(i => new ServerItem(i)) - .ToArray(); + var serverItems = itemsResult.Items.Select(i => new ServerItem(i)).ToArray(itemsResult.Items.Length); return new QueryResult { @@ -942,65 +1284,16 @@ namespace Emby.Dlna.ContentDirectory id = parts[23]; } - if (id.StartsWith("folder_", StringComparison.OrdinalIgnoreCase)) + var enumNames = Enum.GetNames(typeof(StubType)); + foreach (var name in enumNames) { - stubType = StubType.Folder; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("people_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.People; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("latest_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.Latest; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("playlists_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.Playlists; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("Albums_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.Albums; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("AlbumArtists_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.AlbumArtists; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("Artists_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.Artists; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("Genres_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.Genres; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("Songs_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.Songs; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("FavoriteAlbums_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.FavoriteAlbums; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("FavoriteArtists_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.FavoriteArtists; - id = id.Split(new[] { '_' }, 2)[1]; - } - else if (id.StartsWith("FavoriteSongs_", StringComparison.OrdinalIgnoreCase)) - { - stubType = StubType.FavoriteSongs; - id = id.Split(new[] { '_' }, 2)[1]; + if (id.StartsWith(name + "_", StringComparison.OrdinalIgnoreCase)) + { + stubType = (StubType)Enum.Parse(typeof(StubType), name, true); + id = id.Split(new[] { '_' }, 2)[1]; + + break; + } } if (Guid.TryParse(id, out itemId)) @@ -1048,6 +1341,14 @@ namespace Emby.Dlna.ContentDirectory Genres = 8, FavoriteSongs = 9, FavoriteArtists = 10, - FavoriteAlbums = 11 + FavoriteAlbums = 11, + ContinueWatching = 12, + Movies = 13, + Collections = 14, + Favorites = 15, + NextUp = 16, + Series = 17, + FavoriteSeries = 18, + FavoriteEpisodes = 19 } } diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index d2a160cf78..71a0493948 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -193,7 +193,7 @@ namespace Emby.Dlna.Didl { if (streamInfo == null) { - var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user).ToList(); + var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user); streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions { @@ -439,6 +439,38 @@ namespace Emby.Dlna.Didl { return _localization.GetLocalizedString("ViewTypeMusicFavoriteSongs"); } + if (itemStubType.HasValue && itemStubType.Value == StubType.ContinueWatching) + { + return _localization.GetLocalizedString("ViewTypeMovieResume"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.Movies) + { + return _localization.GetLocalizedString("ViewTypeMovieMovies"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.Collections) + { + return _localization.GetLocalizedString("ViewTypeMovieCollections"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.Favorites) + { + return _localization.GetLocalizedString("ViewTypeMovieFavorites"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.NextUp) + { + return _localization.GetLocalizedString("ViewTypeTvNextUp"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteSeries) + { + return _localization.GetLocalizedString("ViewTypeTvFavoriteSeries"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteEpisodes) + { + return _localization.GetLocalizedString("ViewTypeTvFavoriteEpisodes"); + } + if (itemStubType.HasValue && itemStubType.Value == StubType.Series) + { + return _localization.GetLocalizedString("ViewTypeTvShowSeries"); + } var episode = item as Episode; var season = context as Season; @@ -476,7 +508,7 @@ namespace Emby.Dlna.Didl if (streamInfo == null) { - var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user).ToList(); + var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user); streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions { diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 82975ce22b..847f636198 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -18,6 +18,7 @@ using System.Text; using System.Text.RegularExpressions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Reflection; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna { @@ -106,7 +107,6 @@ namespace Emby.Dlna } else { - _logger.Debug("No matching device profile found. The default will need to be used."); LogUnmatchedProfile(deviceInfo); } @@ -220,12 +220,8 @@ namespace Emby.Dlna } else { - var msg = new StringBuilder(); - foreach (var header in headers) - { - msg.AppendLine(header.Key + ": " + header.Value); - } - _logger.LogMultiline("No matching device profile found. The default will need to be used.", LogSeverity.Info, msg); + var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(headers.Count)); + _logger.Debug("No matching device profile found. {0}", headerString); } return profile; diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index e222980102..213e7367f0 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using System.Xml.Linq; using Emby.Dlna.Server; using MediaBrowser.Model.Threading; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.PlayTo { @@ -112,7 +113,7 @@ namespace Emby.Dlna.PlayTo private int GetInactiveTimerIntervalMs() { - return 30000; + return Timeout.Infinite; } public void Start() @@ -160,18 +161,15 @@ namespace Emby.Dlna.PlayTo if (_disposed) return; - if (!_timerActive) + lock (_timerLock) { - lock (_timerLock) + if (!_timerActive) { - if (!_timerActive) - { - _logger.Debug("RestartTimer"); - _timer.Change(10, GetPlaybackTimerIntervalMs()); - } - - _timerActive = true; + _logger.Debug("RestartTimer"); + _timer.Change(10, GetPlaybackTimerIntervalMs()); } + + _timerActive = true; } } @@ -183,23 +181,20 @@ namespace Emby.Dlna.PlayTo if (_disposed) return; - if (_timerActive) + lock (_timerLock) { - lock (_timerLock) + if (_timerActive) { - if (_timerActive) + _logger.Debug("RestartTimerInactive"); + var interval = GetInactiveTimerIntervalMs(); + + if (_timer != null) { - _logger.Debug("RestartTimerInactive"); - var interval = GetInactiveTimerIntervalMs(); - - if (_timer != null) - { - _timer.Change(interval, interval); - } + _timer.Change(interval, interval); } - - _timerActive = false; } + + _timerActive = false; } } @@ -492,6 +487,10 @@ namespace Emby.Dlna.PlayTo RestartTimer(); } } + else + { + RestartTimerInactive(); + } } catch (HttpException ex) { @@ -890,7 +889,7 @@ namespace Emby.Dlna.PlayTo if (room != null && !string.IsNullOrWhiteSpace(room.Value)) friendlyNames.Add(room.Value); - deviceProperties.Name = string.Join(" ", friendlyNames.ToArray()); + deviceProperties.Name = string.Join(" ", friendlyNames.ToArray(friendlyNames.Count)); var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault(); if (model != null) diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 15d73e824b..7164cf5989 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -503,7 +503,7 @@ namespace Emby.Dlna.PlayTo var hasMediaSources = item as IHasMediaSources; var mediaSources = hasMediaSources != null - ? (_mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user)).ToList() + ? (_mediaSourceManager.GetStaticMediaSources(hasMediaSources, true, user)) : new List(); var playlistItem = GetPlaylistItem(item, mediaSources, profile, _session.DeviceId, mediaSourceId, audioStreamIndex, subtitleStreamIndex); diff --git a/Emby.Dlna/Profiles/DefaultProfile.cs b/Emby.Dlna/Profiles/DefaultProfile.cs index 06ce936408..46639ee424 100644 --- a/Emby.Dlna/Profiles/DefaultProfile.cs +++ b/Emby.Dlna/Profiles/DefaultProfile.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Dlna; using System.Linq; using System.Xml.Serialization; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.Profiles { @@ -172,7 +173,7 @@ namespace Emby.Dlna.Profiles Value = value }); - XmlRootAttributes = list.ToArray(); + XmlRootAttributes = list.ToArray(list.Count); } } } diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs index 2a4a5792fa..bba4adc5f4 100644 --- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs +++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs @@ -226,7 +226,7 @@ namespace Emby.Dlna.Server } } - var characters = characterList.ToArray(); + var characters = characterList.ToArray(characterList.Count); var serverName = new string(characters); diff --git a/Emby.Dlna/Service/BaseControlHandler.cs b/Emby.Dlna/Service/BaseControlHandler.cs index 3092589c12..7cd10bd019 100644 --- a/Emby.Dlna/Service/BaseControlHandler.cs +++ b/Emby.Dlna/Service/BaseControlHandler.cs @@ -11,6 +11,7 @@ using System.Xml; using Emby.Dlna.Didl; using MediaBrowser.Controller.Extensions; using MediaBrowser.Model.Xml; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.Service { @@ -235,26 +236,29 @@ namespace Emby.Dlna.Service private void LogRequest(ControlRequest request) { - var builder = new StringBuilder(); + if (!Config.GetDlnaConfiguration().EnableDebugLog) + { + return; + } - var headers = string.Join(", ", request.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray()); - builder.AppendFormat("Headers: {0}", headers); - builder.AppendLine(); - //builder.Append(request.InputXml); + var originalHeaders = request.Headers; + var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count)); - Logger.LogMultiline("Control request", LogSeverity.Debug, builder); + Logger.Debug("Control request. Headers: {0}", headers); } private void LogResponse(ControlResponse response) { - var builder = new StringBuilder(); + if (!Config.GetDlnaConfiguration().EnableDebugLog) + { + return; + } - var headers = string.Join(", ", response.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray()); - builder.AppendFormat("Headers: {0}", headers); - builder.AppendLine(); - builder.Append(response.Xml); + var originalHeaders = response.Headers; + var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count)); + //builder.Append(response.Xml); - Logger.LogMultiline("Control response", LogSeverity.Debug, builder); + Logger.Debug("Control response. Headers: {0}", headers); } } } diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index be45912235..bd23eba7aa 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -17,12 +17,10 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; using Emby.Drawing.Common; - -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; -using TagLib; +using MediaBrowser.Model.Extensions; namespace Emby.Drawing { @@ -171,6 +169,13 @@ namespace Emby.Drawing return _imageEncoder.SupportedOutputFormats; } + private static readonly string[] TransparentImageTypes = new string[] { ".png", ".webp" }; + private bool SupportsTransparency(string path) + { + return TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); + ; + } + public async Task> ProcessImage(ImageProcessingOptions options) { if (options == null) @@ -179,7 +184,7 @@ namespace Emby.Drawing } var originalImage = options.Image; - IHasImages item = options.Item; + IHasMetadata item = options.Item; if (!originalImage.IsLocalFile) { @@ -260,6 +265,11 @@ namespace Emby.Drawing item = _libraryManager().GetItemById(options.ItemId); } + if (options.CropWhiteSpace && !SupportsTransparency(originalImagePath)) + { + options.CropWhiteSpace = false; + } + var resultPath = _imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, autoOrient, orientation, quality, options, outputFormat); if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase)) @@ -594,7 +604,7 @@ namespace Emby.Drawing /// The image. /// Guid. /// item - public string GetImageCacheTag(IHasImages item, ItemImageInfo image) + public string GetImageCacheTag(IHasMetadata item, ItemImageInfo image) { if (item == null) { @@ -619,7 +629,7 @@ namespace Emby.Drawing /// The image enhancers. /// Guid. /// item - public string GetImageCacheTag(IHasImages item, ItemImageInfo image, List imageEnhancers) + public string GetImageCacheTag(IHasMetadata item, ItemImageInfo image, List imageEnhancers) { if (item == null) { @@ -650,7 +660,7 @@ namespace Emby.Drawing var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList(); cacheKeys.Add(originalImagePath + dateModified.Ticks); - return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N"); + return string.Join("|", cacheKeys.ToArray(cacheKeys.Count)).GetMD5().ToString("N"); } /// @@ -660,7 +670,7 @@ namespace Emby.Drawing /// Type of the image. /// Index of the image. /// Task{System.String}. - public async Task GetEnhancedImage(IHasImages item, ImageType imageType, int imageIndex) + public async Task GetEnhancedImage(IHasMetadata item, ImageType imageType, int imageIndex) { var enhancers = GetSupportedEnhancers(item, imageType).ToList(); @@ -672,7 +682,7 @@ namespace Emby.Drawing } private async Task> GetEnhancedImage(ItemImageInfo image, - IHasImages item, + IHasMetadata item, int imageIndex, List enhancers) { @@ -717,7 +727,7 @@ namespace Emby.Drawing /// item /// private async Task GetEnhancedImageInternal(string originalImagePath, - IHasImages item, + IHasMetadata item, ImageType imageType, int imageIndex, IEnumerable supportedEnhancers, @@ -771,7 +781,7 @@ namespace Emby.Drawing /// Type of the image. /// Index of the image. /// Task{EnhancedImage}. - private async Task ExecuteImageEnhancers(IEnumerable imageEnhancers, string inputPath, string outputPath, IHasImages item, ImageType imageType, int imageIndex) + private async Task ExecuteImageEnhancers(IEnumerable imageEnhancers, string inputPath, string outputPath, IHasMetadata item, ImageType imageType, int imageIndex) { // Run the enhancers sequentially in order of priority foreach (var enhancer in imageEnhancers) @@ -856,7 +866,7 @@ namespace Emby.Drawing _logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath); } - public IEnumerable GetSupportedEnhancers(IHasImages item, ImageType imageType) + public IEnumerable GetSupportedEnhancers(IHasMetadata item, ImageType imageType) { return ImageEnhancers.Where(i => { diff --git a/Emby.Photos/PhotoProvider.cs b/Emby.Photos/PhotoProvider.cs index 57047cf81e..c3c30ab6d1 100644 --- a/Emby.Photos/PhotoProvider.cs +++ b/Emby.Photos/PhotoProvider.cs @@ -111,7 +111,7 @@ namespace Emby.Photos } item.Genres = image.ImageTag.Genres.ToList(); - item.Tags = image.ImageTag.Keywords.ToList(); + item.Tags = image.ImageTag.Keywords; item.Software = image.ImageTag.Software; if (image.ImageTag.Orientation == TagLib.Image.ImageOrientation.None) diff --git a/Emby.Server.Core/Emby.Server.Core.csproj b/Emby.Server.Core/Emby.Server.Core.csproj deleted file mode 100644 index 063ef6eb90..0000000000 --- a/Emby.Server.Core/Emby.Server.Core.csproj +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Debug - AnyCPU - {776B9F0C-5195-45E3-9A36-1CC1F0D8E0B0} - Library - Properties - Emby.Server.Core - Emby.Server.Core - v4.6 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - - - - ..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.2\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll - True - - - ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll - True - - - ..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll - - - - - - - - - - - - - - Properties\SharedVersion.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {1e37a338-9f57-4b70-bd6d-bb9c591e319b} - Emby.Common.Implementations - - - {805844ab-e92f-45e6-9d99-4f6d48d129a5} - Emby.Dlna - - - {08fff49b-f175-4807-a2b5-73b0ebd9f716} - Emby.Drawing - - - {89ab4548-770d-41fd-a891-8daff44f452c} - Emby.Photos - - - {e383961b-9356-4d5d-8233-9a1079d03055} - Emby.Server.Implementations - - - {4fd51ac5-2c16-4308-a993-c3a84f3b4582} - MediaBrowser.Api - - - {9142eefa-7570-41e1-bfcc-468bb571af2f} - MediaBrowser.Common - - - {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} - MediaBrowser.Controller - - - {7ef9f3e0-697d-42f3-a08f-19deb5f84392} - MediaBrowser.LocalMetadata - - - {0bd82fa6-eb8a-4452-8af5-74f9c3849451} - MediaBrowser.MediaEncoding - - - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} - MediaBrowser.Model - - - {442b5058-dcaf-4263-bb6a-f21e31120a1b} - MediaBrowser.Providers - - - {2e781478-814d-4a48-9d80-bff206441a65} - MediaBrowser.Server.Implementations - - - {5624b7b5-b5a7-41d8-9f10-cc5611109619} - MediaBrowser.WebDashboard - - - {23499896-b135-4527-8574-c26e926ea99e} - MediaBrowser.XbmcMetadata - - - {cb7f2326-6497-4a3d-ba03-48513b17a7be} - Mono.Nat - - - {4a4402d4-e910-443b-b8fc-2c18286a2ca0} - OpenSubtitlesHandler - - - {1d74413b-e7cf-455b-b021-f52bdf881542} - SocketHttpListener - - - - - - - - - \ No newline at end of file diff --git a/Emby.Server.Core/Properties/AssemblyInfo.cs b/Emby.Server.Core/Properties/AssemblyInfo.cs deleted file mode 100644 index ead0429819..0000000000 --- a/Emby.Server.Core/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Emby.Server.Core")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Emby.Server.Core")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// 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("776b9f0c-5195-45e3-9a36-1cc1f0d8e0b0")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] \ No newline at end of file diff --git a/Emby.Server.Core/app.config b/Emby.Server.Core/app.config deleted file mode 100644 index 57ff623921..0000000000 --- a/Emby.Server.Core/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/Emby.Server.Core/packages.config b/Emby.Server.Core/packages.config deleted file mode 100644 index 6311b55eb2..0000000000 --- a/Emby.Server.Core/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index 567f139fd8..702917832b 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Activity { @@ -436,7 +437,7 @@ namespace Emby.Server.Implementations.Activity { Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name), Type = "ScheduledTaskFailed", - Overview = string.Join(Environment.NewLine, vals.ToArray()), + Overview = string.Join(Environment.NewLine, vals.ToArray(vals.Count)), ShortOverview = runningTime, Severity = LogSeverity.Error }); diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index e9b6f7a404..7720f8f2fd 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Activity; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using SQLitePCL.pretty; +using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Activity { @@ -94,13 +95,13 @@ namespace Emby.Server.Implementations.Activity var whereTextWithoutPaging = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); if (startIndex.HasValue && startIndex.Value > 0) { var pagingWhereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})", pagingWhereText, @@ -109,7 +110,7 @@ namespace Emby.Server.Implementations.Activity var whereText = whereClauses.Count == 0 ? string.Empty : - " where " + string.Join(" AND ", whereClauses.ToArray()); + " where " + string.Join(" AND ", whereClauses.ToArray(whereClauses.Count)); commandText += whereText; @@ -154,7 +155,7 @@ namespace Emby.Server.Implementations.Activity result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First(); } - result.Items = list.ToArray(); + result.Items = list.ToArray(list.Count); return result; }, ReadTransactionMode); diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs similarity index 88% rename from Emby.Server.Core/ApplicationHost.cs rename to Emby.Server.Implementations/ApplicationHost.cs index 04309e7f41..7f893d8f7d 100644 --- a/Emby.Server.Core/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1,11 +1,52 @@ -using MediaBrowser.Api; +using Emby.Common.Implementations; +using Emby.Common.Implementations.Archiving; +using Emby.Common.Implementations.IO; +using Emby.Common.Implementations.Reflection; +using Emby.Common.Implementations.ScheduledTasks; +using Emby.Common.Implementations.Serialization; +using Emby.Common.Implementations.TextEncoding; +using Emby.Common.Implementations.Xml; +using Emby.Dlna; +using Emby.Dlna.ConnectionManager; +using Emby.Dlna.ContentDirectory; +using Emby.Dlna.Main; +using Emby.Dlna.MediaReceiverRegistrar; +using Emby.Dlna.Ssdp; +using Emby.Drawing; +using Emby.Photos; +using Emby.Server.Implementations.Activity; +using Emby.Server.Implementations.Channels; +using Emby.Server.Implementations.Collections; +using Emby.Server.Implementations.Configuration; +using Emby.Server.Implementations.Data; +using Emby.Server.Implementations.Devices; +using Emby.Server.Implementations.Dto; +using Emby.Server.Implementations.FFMpeg; +using Emby.Server.Implementations.HttpServer; +using Emby.Server.Implementations.HttpServer.Security; +using Emby.Server.Implementations.IO; +using Emby.Server.Implementations.Library; +using Emby.Server.Implementations.LiveTv; +using Emby.Server.Implementations.Localization; +using Emby.Server.Implementations.MediaEncoder; +using Emby.Server.Implementations.Migrations; +using Emby.Server.Implementations.Notifications; +using Emby.Server.Implementations.Playlists; +using Emby.Server.Implementations.Security; +using Emby.Server.Implementations.Session; +using Emby.Server.Implementations.Social; +using Emby.Server.Implementations.TV; +using Emby.Server.Implementations.Updates; +using MediaBrowser.Api; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.Extensions; -using Emby.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Net; +using MediaBrowser.Common.Plugins; using MediaBrowser.Common.Progress; +using MediaBrowser.Common.Security; +using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Chapters; @@ -17,7 +58,9 @@ using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.FileOrganization; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; @@ -35,103 +78,47 @@ using MediaBrowser.Controller.Subtitles; using MediaBrowser.Controller.Sync; using MediaBrowser.Controller.TV; using MediaBrowser.LocalMetadata.Savers; -using MediaBrowser.MediaEncoding.BdInfo; -using MediaBrowser.MediaEncoding.Encoder; -using MediaBrowser.MediaEncoding.Subtitles; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Model.System; -using MediaBrowser.Model.Updates; -using MediaBrowser.Providers.Chapters; -using MediaBrowser.Providers.Manager; -using MediaBrowser.Providers.Subtitles; -using MediaBrowser.WebDashboard.Api; -using MediaBrowser.XbmcMetadata.Providers; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.Threading; -using System.Threading.Tasks; -using Emby.Common.Implementations; -using Emby.Common.Implementations.Archiving; -using Emby.Common.Implementations.IO; -using Emby.Common.Implementations.Reflection; -using Emby.Common.Implementations.Serialization; -using Emby.Common.Implementations.TextEncoding; -using Emby.Common.Implementations.Xml; -using Emby.Photos; -using MediaBrowser.Model.IO; -using MediaBrowser.Api.Playback; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Security; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using Emby.Dlna; -using Emby.Dlna.ConnectionManager; -using Emby.Dlna.ContentDirectory; -using Emby.Dlna.Main; -using Emby.Dlna.MediaReceiverRegistrar; -using Emby.Dlna.Ssdp; -using Emby.Server.Core; -using Emby.Server.Implementations.Activity; -using Emby.Server.Implementations.Devices; -using Emby.Server.Implementations.FFMpeg; -using Emby.Server.Core.IO; -using Emby.Server.Core.Localization; -using Emby.Server.Implementations.Migrations; -using Emby.Server.Implementations.Security; -using Emby.Server.Implementations.Social; -using Emby.Server.Implementations.Channels; -using Emby.Server.Implementations.Collections; -using Emby.Server.Implementations.Dto; -using Emby.Server.Implementations.IO; -using Emby.Server.Implementations.FileOrganization; -using Emby.Server.Implementations.HttpServer; -using Emby.Server.Implementations.HttpServer.Security; -using Emby.Server.Implementations.Library; -using Emby.Server.Implementations.LiveTv; -using Emby.Server.Implementations.Localization; -using Emby.Server.Implementations.MediaEncoder; -using Emby.Server.Implementations.Notifications; -using Emby.Server.Implementations.Data; -using Emby.Server.Implementations.Playlists; -using Emby.Server.Implementations; -using Emby.Server.Implementations.ServerManager; -using Emby.Server.Implementations.Session; -using Emby.Server.Implementations.TV; -using Emby.Server.Implementations.Updates; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Net; using MediaBrowser.Model.News; using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using MediaBrowser.Model.Social; +using MediaBrowser.Model.System; using MediaBrowser.Model.Text; +using MediaBrowser.Model.Updates; using MediaBrowser.Model.Xml; +using MediaBrowser.Providers.Chapters; +using MediaBrowser.Providers.Manager; +using MediaBrowser.Providers.Subtitles; +using MediaBrowser.WebDashboard.Api; +using MediaBrowser.XbmcMetadata.Providers; using OpenSubtitlesHandler; using ServiceStack; using SocketHttpListener.Primitives; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using Emby.Server.MediaEncoding.Subtitles; +using MediaBrowser.MediaEncoding.BdInfo; using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions; -using Emby.Drawing; -using Emby.Server.Implementations.Migrations; -using MediaBrowser.Model.Diagnostics; -using Emby.Common.Implementations.Diagnostics; -using Emby.Server.Implementations.Configuration; -namespace Emby.Server.Core +namespace Emby.Server.Implementations { /// /// Class CompositionRoot @@ -216,7 +203,6 @@ namespace Emby.Server.Core internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; } internal IItemRepository ItemRepository { get; set; } private INotificationsRepository NotificationsRepository { get; set; } - private IFileOrganizationRepository FileOrganizationRepository { get; set; } private INotificationManager NotificationManager { get; set; } private ISubtitleManager SubtitleManager { get; set; } @@ -226,7 +212,6 @@ namespace Emby.Server.Core internal IUserViewManager UserViewManager { get; set; } private IAuthenticationRepository AuthenticationRepository { get; set; } - private ISyncRepository SyncRepository { get; set; } private ITVSeriesManager TVSeriesManager { get; set; } private ICollectionManager CollectionManager { get; set; } private IMediaSourceManager MediaSourceManager { get; set; } @@ -360,13 +345,6 @@ namespace Emby.Server.Core { var builder = GetBaseExceptionMessage(ApplicationPaths); - // Skip if plugins haven't been loaded yet - //if (Plugins != null) - //{ - // var pluginString = string.Join("|", Plugins.Select(i => i.Name + "-" + i.Version.ToString()).ToArray()); - // builder.Insert(0, string.Format("Plugins: {0}{1}", pluginString, Environment.NewLine)); - //} - builder.Insert(0, string.Format("Version: {0}{1}", ApplicationVersion, Environment.NewLine)); builder.Insert(0, "*** Error Report ***" + Environment.NewLine); @@ -413,7 +391,7 @@ namespace Emby.Server.Core { Logger.ErrorException("Error in {0}", ex, name); } - Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture)); + Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture), "ImageInfos"); } Logger.Info("All entry points have started"); @@ -434,41 +412,41 @@ namespace Emby.Server.Core var result = new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer")); - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "Artists", "AlbumArtists", "ChannelMediaSources", "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds", "ImageInfos", "ProductionLocations", "ThemeSongIds", "ThemeVideoIds", "TotalBitrate", "Taglines", "Keywords", "ExtraType" }; - ServiceStack.Text.JsConfig