update live tv data transfer

pull/1154/head
Luke Pulverenti 7 years ago
parent bd31c0175d
commit 1ad990ad72

@ -487,6 +487,11 @@ namespace Emby.Dlna.ContentDirectory
return GetMusicArtistItems(item, null, user, sort, startIndex, limit); return GetMusicArtistItems(item, null, user, sort, startIndex, limit);
} }
if (item is Genre)
{
return GetGenreItems(item, null, user, sort, startIndex, limit);
}
var collectionFolder = item as ICollectionFolder; var collectionFolder = item as ICollectionFolder;
if (collectionFolder != null && string.Equals(CollectionType.Music, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase)) if (collectionFolder != null && string.Equals(CollectionType.Music, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
{ {
@ -1173,6 +1178,26 @@ namespace Emby.Dlna.ContentDirectory
return ToResult(result); return ToResult(result);
} }
private QueryResult<ServerItem> GetGenreItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit)
{
var query = new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parentId,
GenreIds = new[] { item.Id.ToString("N") },
IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name },
Limit = limit,
StartIndex = startIndex,
DtoOptions = GetDtoOptions()
};
SetSorting(query, sort, false);
var result = _libraryManager.GetItemsResult(query);
return ToResult(result);
}
private QueryResult<ServerItem> GetMusicGenreItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit) private QueryResult<ServerItem> GetMusicGenreItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit)
{ {
var query = new InternalItemsQuery(user) var query = new InternalItemsQuery(user)

@ -198,7 +198,7 @@ namespace Emby.Dlna.Didl
streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions
{ {
ItemId = GetClientId(video), ItemId = GetClientId(video),
MediaSources = sources, MediaSources = sources.ToArray(sources.Count),
Profile = _profile, Profile = _profile,
DeviceId = deviceId, DeviceId = deviceId,
MaxBitrate = _profile.MaxStreamingBitrate MaxBitrate = _profile.MaxStreamingBitrate
@ -513,7 +513,7 @@ namespace Emby.Dlna.Didl
streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions
{ {
ItemId = GetClientId(audio), ItemId = GetClientId(audio),
MediaSources = sources, MediaSources = sources.ToArray(sources.Count),
Profile = _profile, Profile = _profile,
DeviceId = deviceId DeviceId = deviceId
}); });

@ -20,6 +20,7 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Events; using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Extensions;
namespace Emby.Dlna.PlayTo namespace Emby.Dlna.PlayTo
{ {
@ -589,7 +590,7 @@ namespace Emby.Dlna.PlayTo
StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildVideoItem(new VideoOptions
{ {
ItemId = item.Id.ToString("N"), ItemId = item.Id.ToString("N"),
MediaSources = mediaSources, MediaSources = mediaSources.ToArray(mediaSources.Count),
Profile = profile, Profile = profile,
DeviceId = deviceId, DeviceId = deviceId,
MaxBitrate = profile.MaxStreamingBitrate, MaxBitrate = profile.MaxStreamingBitrate,
@ -609,7 +610,7 @@ namespace Emby.Dlna.PlayTo
StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions StreamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger()).BuildAudioItem(new AudioOptions
{ {
ItemId = item.Id.ToString("N"), ItemId = item.Id.ToString("N"),
MediaSources = mediaSources, MediaSources = mediaSources.ToArray(mediaSources.Count),
Profile = profile, Profile = profile,
DeviceId = deviceId, DeviceId = deviceId,
MaxBitrate = profile.MaxStreamingBitrate, MaxBitrate = profile.MaxStreamingBitrate,

@ -182,7 +182,7 @@ namespace Emby.Dlna.PlayTo
{ {
PlayableMediaTypes = profile.GetSupportedMediaTypes(), PlayableMediaTypes = profile.GetSupportedMediaTypes(),
SupportedCommands = new List<string> SupportedCommands = new string[]
{ {
GeneralCommandType.VolumeDown.ToString(), GeneralCommandType.VolumeDown.ToString(),
GeneralCommandType.VolumeUp.ToString(), GeneralCommandType.VolumeUp.ToString(),

@ -1853,9 +1853,9 @@ namespace Emby.Server.Implementations
HasPendingRestart = HasPendingRestart, HasPendingRestart = HasPendingRestart,
Version = ApplicationVersion.ToString(), Version = ApplicationVersion.ToString(),
WebSocketPortNumber = HttpPort, WebSocketPortNumber = HttpPort,
FailedPluginAssemblies = FailedAssemblies.ToList(), FailedPluginAssemblies = FailedAssemblies.ToArray(),
InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToList(), InProgressInstallations = InstallationManager.CurrentInstallations.Select(i => i.Item1).ToArray(),
CompletedInstallations = InstallationManager.CompletedInstallations.ToList(), CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
Id = SystemId, Id = SystemId,
ProgramDataPath = ApplicationPaths.ProgramDataPath, ProgramDataPath = ApplicationPaths.ProgramDataPath,
LogPath = ApplicationPaths.LogDirectoryPath, LogPath = ApplicationPaths.LogDirectoryPath,

@ -182,10 +182,8 @@ namespace Emby.Server.Implementations.Channels
{ {
}; };
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user) var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
@ -464,14 +462,14 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetItemById(id) as Channel; return _libraryManager.GetItemById(id) as Channel;
} }
public IEnumerable<ChannelFeatures> GetAllChannelFeatures() public ChannelFeatures[] GetAllChannelFeatures()
{ {
return _libraryManager.GetItemIds(new InternalItemsQuery return _libraryManager.GetItemIds(new InternalItemsQuery
{ {
IncludeItemTypes = new[] { typeof(Channel).Name }, IncludeItemTypes = new[] { typeof(Channel).Name },
SortBy = new[] { ItemSortBy.SortName } SortBy = new[] { ItemSortBy.SortName }
}).Select(i => GetChannelFeatures(i.ToString("N"))); }).Select(i => GetChannelFeatures(i.ToString("N"))).ToArray();
} }
public ChannelFeatures GetChannelFeatures(string id) public ChannelFeatures GetChannelFeatures(string id)
@ -511,10 +509,10 @@ namespace Emby.Server.Implementations.Channels
{ {
CanFilter = !features.MaxPageSize.HasValue, CanFilter = !features.MaxPageSize.HasValue,
CanSearch = provider is ISearchableChannel, CanSearch = provider is ISearchableChannel,
ContentTypes = features.ContentTypes, ContentTypes = features.ContentTypes.ToArray(),
DefaultSortFields = features.DefaultSortFields, DefaultSortFields = features.DefaultSortFields.ToArray(),
MaxPageSize = features.MaxPageSize, MaxPageSize = features.MaxPageSize,
MediaTypes = features.MediaTypes, MediaTypes = features.MediaTypes.ToArray(),
SupportsSortOrderToggle = features.SupportsSortOrderToggle, SupportsSortOrderToggle = features.SupportsSortOrderToggle,
SupportsLatestMedia = supportsLatest, SupportsLatestMedia = supportsLatest,
Name = channel.Name, Name = channel.Name,
@ -566,12 +564,10 @@ namespace Emby.Server.Implementations.Channels
var dtoOptions = new DtoOptions() var dtoOptions = new DtoOptions()
{ {
Fields = query.Fields.ToList() Fields = query.Fields
}; };
var returnList = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false)); var returnItems = (await _dtoService.GetBaseItemDtos(items, dtoOptions, user).ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
@ -833,13 +829,11 @@ namespace Emby.Server.Implementations.Channels
var dtoOptions = new DtoOptions() var dtoOptions = new DtoOptions()
{ {
Fields = query.Fields.ToList() Fields = query.Fields
}; };
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user) var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
@ -987,13 +981,11 @@ namespace Emby.Server.Implementations.Channels
var dtoOptions = new DtoOptions() var dtoOptions = new DtoOptions()
{ {
Fields = query.Fields.ToList() Fields = query.Fields
}; };
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user) var returnItems = (await _dtoService.GetBaseItemDtos(internalResult.Items, dtoOptions, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnItems = returnList
.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {

@ -84,7 +84,7 @@ namespace Emby.Server.Implementations.Collections
ProviderIds = options.ProviderIds, ProviderIds = options.ProviderIds,
Shares = options.UserIds.Select(i => new Share Shares = options.UserIds.Select(i => new Share
{ {
UserId = i.ToString("N"), UserId = i,
CanEdit = true CanEdit = true
}).ToList() }).ToList()
@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.Collections
await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false); await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false);
if (options.ItemIdList.Count > 0) if (options.ItemIdList.Length > 0)
{ {
await AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(_fileSystem) await AddToCollection(collection.Id, options.ItemIdList, false, new MetadataRefreshOptions(_fileSystem)
{ {
@ -149,12 +149,12 @@ namespace Emby.Server.Implementations.Collections
return GetCollectionsFolder(string.Empty); return GetCollectionsFolder(string.Empty);
} }
public Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids) public Task AddToCollection(Guid collectionId, string[] ids)
{ {
return AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(_fileSystem)); return AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(_fileSystem));
} }
private async Task AddToCollection(Guid collectionId, IEnumerable<Guid> ids, bool fireEvent, MetadataRefreshOptions refreshOptions) private async Task AddToCollection(Guid collectionId, string[] ids, bool fireEvent, MetadataRefreshOptions refreshOptions)
{ {
var collection = _libraryManager.GetItemById(collectionId) as BoxSet; var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
@ -165,11 +165,12 @@ namespace Emby.Server.Implementations.Collections
var list = new List<LinkedChild>(); var list = new List<LinkedChild>();
var itemList = new List<BaseItem>(); var itemList = new List<BaseItem>();
var currentLinkedChildren = collection.GetLinkedChildren().ToList(); var currentLinkedChildrenIds = collection.GetLinkedChildren().Select(i => i.Id).ToList();
foreach (var itemId in ids) foreach (var itemId in ids)
{ {
var item = _libraryManager.GetItemById(itemId); var guidId = new Guid(itemId);
var item = _libraryManager.GetItemById(guidId);
if (string.IsNullOrWhiteSpace(item.Path)) if (string.IsNullOrWhiteSpace(item.Path))
{ {
@ -183,7 +184,7 @@ namespace Emby.Server.Implementations.Collections
itemList.Add(item); itemList.Add(item);
if (currentLinkedChildren.All(i => i.Id != itemId)) if (!currentLinkedChildrenIds.Contains(guidId))
{ {
list.Add(LinkedChild.Create(item)); list.Add(LinkedChild.Create(item));
} }
@ -213,7 +214,7 @@ namespace Emby.Server.Implementations.Collections
} }
} }
public async Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds) public async Task RemoveFromCollection(Guid collectionId, string[] itemIds)
{ {
var collection = _libraryManager.GetItemById(collectionId) as BoxSet; var collection = _libraryManager.GetItemById(collectionId) as BoxSet;
@ -227,9 +228,10 @@ namespace Emby.Server.Implementations.Collections
foreach (var itemId in itemIds) foreach (var itemId in itemIds)
{ {
var childItem = _libraryManager.GetItemById(itemId); var guidId = new Guid(itemId);
var childItem = _libraryManager.GetItemById(guidId);
var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value == itemId) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase))); var child = collection.LinkedChildren.FirstOrDefault(i => (i.ItemId.HasValue && i.ItemId.Value == guidId) || (childItem != null && string.Equals(childItem.Path, i.Path, StringComparison.OrdinalIgnoreCase)));
if (child == null) if (child == null)
{ {

@ -149,7 +149,7 @@ namespace Emby.Server.Implementations.Data
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))", "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)", "create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
"create index if not exists idx_AncestorIds2 on AncestorIds(AncestorIdText)", "create index if not exists idx_AncestorIds5 on AncestorIds(AncestorIdText,ItemId)",
"create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT, CleanValue TEXT)", "create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT, CleanValue TEXT)",
@ -308,6 +308,7 @@ namespace Emby.Server.Implementations.Data
"drop index if exists idx_TypeSeriesPresentationUniqueKey2", "drop index if exists idx_TypeSeriesPresentationUniqueKey2",
"drop index if exists idx_AncestorIds3", "drop index if exists idx_AncestorIds3",
"drop index if exists idx_AncestorIds4", "drop index if exists idx_AncestorIds4",
"drop index if exists idx_AncestorIds2",
"create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)", "create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)",
"create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)", "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",

@ -11,6 +11,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session; using MediaBrowser.Model.Session;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Devices namespace Emby.Server.Implementations.Devices
{ {
@ -199,7 +200,10 @@ namespace Emby.Server.Implementations.Devices
} }
history.DeviceId = deviceId; history.DeviceId = deviceId;
history.FilesUploaded.Add(file);
var list = history.FilesUploaded.ToList();
list.Add(file);
history.FilesUploaded = list.ToArray(list.Count);
_json.SerializeToFile(history, path); _json.SerializeToFile(history, path);
} }

@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.Dto
/// <param name="owner">The owner.</param> /// <param name="owner">The owner.</param>
/// <returns>Task{DtoBaseItem}.</returns> /// <returns>Task{DtoBaseItem}.</returns>
/// <exception cref="System.ArgumentNullException">item</exception> /// <exception cref="System.ArgumentNullException">item</exception>
public BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null) public BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null)
{ {
var options = new DtoOptions var options = new DtoOptions
{ {
@ -87,7 +87,17 @@ namespace Emby.Server.Implementations.Dto
return GetBaseItemDto(item, options, user, owner); return GetBaseItemDto(item, options, user, owner);
} }
public async Task<List<BaseItemDto>> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null) public Task<BaseItemDto[]> GetBaseItemDtos(List<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
{
return GetBaseItemDtos(items, items.Count, options, user, owner);
}
public Task<BaseItemDto[]> GetBaseItemDtos(BaseItem[] items, DtoOptions options, User user = null, BaseItem owner = null)
{
return GetBaseItemDtos(items, items.Length, options, user, owner);
}
public async Task<BaseItemDto[]> GetBaseItemDtos(IEnumerable<BaseItem> items, int itemCount, DtoOptions options, User user = null, BaseItem owner = null)
{ {
if (items == null) if (items == null)
{ {
@ -101,7 +111,7 @@ namespace Emby.Server.Implementations.Dto
var syncDictionary = GetSyncedItemProgress(options); var syncDictionary = GetSyncedItemProgress(options);
var list = new List<BaseItemDto>(); var returnItems = new BaseItemDto[itemCount];
var programTuples = new List<Tuple<BaseItem, BaseItemDto>>(); var programTuples = new List<Tuple<BaseItem, BaseItemDto>>();
var channelTuples = new List<Tuple<BaseItemDto, LiveTvChannel>>(); var channelTuples = new List<Tuple<BaseItemDto, LiveTvChannel>>();
@ -109,6 +119,7 @@ namespace Emby.Server.Implementations.Dto
? _providerManager.GetRefreshQueue() ? _providerManager.GetRefreshQueue()
: null; : null;
var index = 0;
foreach (var item in items) foreach (var item in items)
{ {
var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user, owner); var dto = GetBaseItemDtoInternal(item, options, refreshQueue, user, owner);
@ -144,7 +155,8 @@ namespace Emby.Server.Implementations.Dto
FillSyncInfo(dto, item, options, user, syncDictionary); FillSyncInfo(dto, item, options, user, syncDictionary);
list.Add(dto); returnItems[index] = dto;
index++;
} }
if (programTuples.Count > 0) if (programTuples.Count > 0)
@ -157,7 +169,7 @@ namespace Emby.Server.Implementations.Dto
await _livetvManager().AddChannelInfo(channelTuples, options, user).ConfigureAwait(false); await _livetvManager().AddChannelInfo(channelTuples, options, user).ConfigureAwait(false);
} }
return list; return returnItems;
} }
public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
@ -992,7 +1004,7 @@ namespace Emby.Server.Implementations.Dto
{ {
dto.RemoteTrailers = hasTrailers != null ? dto.RemoteTrailers = hasTrailers != null ?
hasTrailers.RemoteTrailers : hasTrailers.RemoteTrailers :
new MediaUrl[] {}; new MediaUrl[] { };
} }
dto.Name = item.Name; dto.Name = item.Name;
@ -1053,7 +1065,7 @@ namespace Emby.Server.Implementations.Dto
if (dto.Taglines == null) if (dto.Taglines == null)
{ {
dto.Taglines = new string[]{}; dto.Taglines = new string[] { };
} }
} }
@ -1243,17 +1255,17 @@ namespace Emby.Server.Implementations.Dto
if (iHasMediaSources != null) if (iHasMediaSources != null)
{ {
List<MediaStream> mediaStreams; MediaStream[] mediaStreams;
if (dto.MediaSources != null && dto.MediaSources.Count > 0) if (dto.MediaSources != null && dto.MediaSources.Count > 0)
{ {
mediaStreams = dto.MediaSources.Where(i => new Guid(i.Id) == item.Id) mediaStreams = dto.MediaSources.Where(i => new Guid(i.Id) == item.Id)
.SelectMany(i => i.MediaStreams) .SelectMany(i => i.MediaStreams)
.ToList(); .ToArray();
} }
else else
{ {
mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams; mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams.ToArray();
} }
dto.MediaStreams = mediaStreams; dto.MediaStreams = mediaStreams;

@ -367,15 +367,15 @@ namespace Emby.Server.Implementations.EntryPoints
return new LibraryUpdateInfo return new LibraryUpdateInfo
{ {
ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToList(), ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray(),
FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList() FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToArray()
}; };
} }

@ -126,7 +126,7 @@ namespace Emby.Server.Implementations.EntryPoints
dto.ItemId = i.Id.ToString("N"); dto.ItemId = i.Id.ToString("N");
return dto; return dto;
}) })
.ToList(); .ToArray();
var info = new UserDataChangeInfo var info = new UserDataChangeInfo
{ {

@ -162,7 +162,7 @@ namespace Emby.Server.Implementations.HttpServer
return serviceType; return serviceType;
} }
public void AddServiceInfo(Type serviceType, Type requestType, Type responseType) public void AddServiceInfo(Type serviceType, Type requestType)
{ {
ServiceOperationsMap[requestType] = serviceType; ServiceOperationsMap[requestType] = serviceType;
} }

@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.IO
/// <summary> /// <summary>
/// Any file name ending in any of these will be ignored by the watchers /// Any file name ending in any of these will be ignored by the watchers
/// </summary> /// </summary>
private readonly IReadOnlyList<string> _alwaysIgnoreFiles = new List<string> private readonly string[] _alwaysIgnoreFiles = new string[]
{ {
"small.jpg", "small.jpg",
"albumart.jpg", "albumart.jpg",
@ -45,7 +45,7 @@ namespace Emby.Server.Implementations.IO
"TempSBE" "TempSBE"
}; };
private readonly IReadOnlyList<string> _alwaysIgnoreSubstrings = new List<string> private readonly string[] _alwaysIgnoreSubstrings = new string[]
{ {
// Synology // Synology
"eaDir", "eaDir",
@ -54,7 +54,7 @@ namespace Emby.Server.Implementations.IO
".actors" ".actors"
}; };
private readonly IReadOnlyList<string> _alwaysIgnoreExtensions = new List<string> private readonly string[] _alwaysIgnoreExtensions = new string[]
{ {
// thumbs.db // thumbs.db
".db", ".db",

@ -1208,7 +1208,7 @@ namespace Emby.Server.Implementations.Library
.Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase)) .Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase))
.Select(_fileSystem.ResolveShortcut) .Select(_fileSystem.ResolveShortcut)
.OrderBy(i => i) .OrderBy(i => i)
.ToList(), .ToArray(),
CollectionType = GetCollectionType(dir) CollectionType = GetCollectionType(dir)
}; };
@ -1554,7 +1554,7 @@ namespace Emby.Server.Implementations.Library
IncludeHidden = true, IncludeHidden = true,
IncludeExternalContent = allowExternalContent IncludeExternalContent = allowExternalContent
}, CancellationToken.None).Result.ToList(); }, CancellationToken.None).Result;
query.TopParentIds = userViews.SelectMany(i => GetTopParentIdsForQuery(i, user)).Select(i => i.ToString("N")).ToArray(); query.TopParentIds = userViews.SelectMany(i => GetTopParentIdsForQuery(i, user)).Select(i => i.ToString("N")).ToArray();
} }
@ -3061,7 +3061,7 @@ namespace Emby.Server.Implementations.Library
var topLibraryFolders = GetUserRootFolder().Children.ToList(); var topLibraryFolders = GetUserRootFolder().Children.ToList();
var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders, null); var info = GetVirtualFolderInfo(virtualFolderPath, topLibraryFolders, null);
if (info.Locations.Count > 0 && info.Locations.Count != options.PathInfos.Length) if (info.Locations.Length > 0 && info.Locations.Length != options.PathInfos.Length)
{ {
var list = options.PathInfos.ToList(); var list = options.PathInfos.ToList();

@ -181,7 +181,7 @@ namespace Emby.Server.Implementations.Library
DtoOptions = new DtoOptions DtoOptions = new DtoOptions
{ {
Fields = new List<ItemFields> Fields = new ItemFields[]
{ {
ItemFields.AirTime, ItemFields.AirTime,
ItemFields.DateCreated, ItemFields.DateCreated,

@ -187,11 +187,11 @@ namespace Emby.Server.Implementations.Library
var userData = GetUserData(user.Id, item); var userData = GetUserData(user.Id, item);
var dto = GetUserItemDataDto(userData); var dto = GetUserItemDataDto(userData);
item.FillUserDataDtoValues(dto, userData, null, user, new List<ItemFields>()); item.FillUserDataDtoValues(dto, userData, null, user, new ItemFields[]{});
return dto; return dto;
} }
public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields) public UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, ItemFields[] fields)
{ {
var userData = GetUserData(user.Id, item); var userData = GetUserData(user.Id, item);
var dto = GetUserItemDataDto(userData); var dto = GetUserItemDataDto(userData);

@ -39,7 +39,7 @@ namespace Emby.Server.Implementations.Library
_config = config; _config = config;
} }
public async Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken) public async Task<Folder[]> GetUserViews(UserViewQuery query, CancellationToken cancellationToken)
{ {
var user = _userManager.GetUserById(query.UserId); var user = _userManager.GetUserById(query.UserId);
@ -154,7 +154,8 @@ namespace Emby.Server.Implementations.Library
return index == -1 ? int.MaxValue : index; return index == -1 ? int.MaxValue : index;
}) })
.ThenBy(sorted.IndexOf) .ThenBy(sorted.IndexOf)
.ThenBy(i => i.SortName); .ThenBy(i => i.SortName)
.ToArray();
} }
public Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken) public Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken)

@ -208,7 +208,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
continue; continue;
} }
if (virtualFolder.Locations.Count == 1) if (virtualFolder.Locations.Length == 1)
{ {
// remove entire virtual folder // remove entire virtual folder
try try
@ -458,7 +458,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return GetEpgChannelFromTunerChannel(info, tunerChannel, epgChannels); return GetEpgChannelFromTunerChannel(info, tunerChannel, epgChannels);
} }
private string GetMappedChannel(string channelId, List<NameValuePair> mappings) private string GetMappedChannel(string channelId, NameValuePair[] mappings)
{ {
foreach (NameValuePair mapping in mappings) foreach (NameValuePair mapping in mappings)
{ {
@ -472,10 +472,10 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private ChannelInfo GetEpgChannelFromTunerChannel(ListingsProviderInfo info, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels) private ChannelInfo GetEpgChannelFromTunerChannel(ListingsProviderInfo info, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
{ {
return GetEpgChannelFromTunerChannel(info.ChannelMappings.ToList(), tunerChannel, epgChannels); return GetEpgChannelFromTunerChannel(info.ChannelMappings, tunerChannel, epgChannels);
} }
public ChannelInfo GetEpgChannelFromTunerChannel(List<NameValuePair> mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels) public ChannelInfo GetEpgChannelFromTunerChannel(NameValuePair[] mappings, ChannelInfo tunerChannel, List<ChannelInfo> epgChannels)
{ {
if (!string.IsNullOrWhiteSpace(tunerChannel.Id)) if (!string.IsNullOrWhiteSpace(tunerChannel.Id))
{ {
@ -2591,7 +2591,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{ {
list.Add(new VirtualFolderInfo list.Add(new VirtualFolderInfo
{ {
Locations = new List<string> { defaultFolder }, Locations = new string[] { defaultFolder },
Name = defaultName Name = defaultName
}); });
} }
@ -2601,7 +2601,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{ {
list.Add(new VirtualFolderInfo list.Add(new VirtualFolderInfo
{ {
Locations = new List<string> { customPath }, Locations = new string[] { customPath },
Name = "Recorded Movies", Name = "Recorded Movies",
CollectionType = CollectionType.Movies CollectionType = CollectionType.Movies
}); });
@ -2612,7 +2612,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{ {
list.Add(new VirtualFolderInfo list.Add(new VirtualFolderInfo
{ {
Locations = new List<string> { customPath }, Locations = new string[] { customPath },
Name = "Recorded Shows", Name = "Recorded Shows",
CollectionType = CollectionType.TvShows CollectionType = CollectionType.TvShows
}); });

@ -15,6 +15,8 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.LiveTv namespace Emby.Server.Implementations.LiveTv
{ {
@ -110,7 +112,7 @@ namespace Emby.Server.Implementations.LiveTv
PostPaddingSeconds = info.PostPaddingSeconds, PostPaddingSeconds = info.PostPaddingSeconds,
IsPostPaddingRequired = info.IsPostPaddingRequired, IsPostPaddingRequired = info.IsPostPaddingRequired,
IsPrePaddingRequired = info.IsPrePaddingRequired, IsPrePaddingRequired = info.IsPrePaddingRequired,
Days = info.Days, Days = info.Days.ToArray(),
Priority = info.Priority, Priority = info.Priority,
RecordAnyChannel = info.RecordAnyChannel, RecordAnyChannel = info.RecordAnyChannel,
RecordAnyTime = info.RecordAnyTime, RecordAnyTime = info.RecordAnyTime,
@ -135,7 +137,7 @@ namespace Emby.Server.Implementations.LiveTv
dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N"); dto.ProgramId = GetInternalProgramId(service.Name, info.ProgramId).ToString("N");
} }
dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days); dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days.ToArray(info.Days.Count));
FillImages(dto, info.Name, info.SeriesId); FillImages(dto, info.Name, info.SeriesId);
@ -150,10 +152,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = seriesName, Name = seriesName,
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Thumb }, ImageTypes = new ImageType[] { ImageType.Thumb },
DtoOptions = new DtoOptions DtoOptions = new DtoOptions(false)
{
Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
}
}).FirstOrDefault(); }).FirstOrDefault();
@ -196,10 +195,7 @@ namespace Emby.Server.Implementations.LiveTv
ExternalSeriesId = programSeriesId, ExternalSeriesId = programSeriesId,
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new ImageType[] { ImageType.Primary },
DtoOptions = new DtoOptions DtoOptions = new DtoOptions(false)
{
Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
}
}).FirstOrDefault(); }).FirstOrDefault();
@ -248,10 +244,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = seriesName, Name = seriesName,
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Thumb }, ImageTypes = new ImageType[] { ImageType.Thumb },
DtoOptions = new DtoOptions DtoOptions = new DtoOptions(false)
{
Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
}
}).FirstOrDefault(); }).FirstOrDefault();
@ -274,7 +267,7 @@ namespace Emby.Server.Implementations.LiveTv
{ {
try try
{ {
dto.ParentBackdropImageTags = new List<string> dto.ParentBackdropImageTags = new string[]
{ {
_imageProcessor.GetImageCacheTag(librarySeries, image) _imageProcessor.GetImageCacheTag(librarySeries, image)
}; };
@ -294,10 +287,7 @@ namespace Emby.Server.Implementations.LiveTv
Name = seriesName, Name = seriesName,
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new ImageType[] { ImageType.Primary },
DtoOptions = new DtoOptions DtoOptions = new DtoOptions(false)
{
Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
}
}).FirstOrDefault() ?? _libraryManager.GetItemList(new InternalItemsQuery }).FirstOrDefault() ?? _libraryManager.GetItemList(new InternalItemsQuery
{ {
@ -305,10 +295,7 @@ namespace Emby.Server.Implementations.LiveTv
ExternalSeriesId = programSeriesId, ExternalSeriesId = programSeriesId,
Limit = 1, Limit = 1,
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new ImageType[] { ImageType.Primary },
DtoOptions = new DtoOptions DtoOptions = new DtoOptions(false)
{
Fields = new List<MediaBrowser.Model.Querying.ItemFields>()
}
}).FirstOrDefault(); }).FirstOrDefault();
@ -327,14 +314,14 @@ namespace Emby.Server.Implementations.LiveTv
} }
} }
if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Count == 0) if (dto.ParentBackdropImageTags == null || dto.ParentBackdropImageTags.Length == 0)
{ {
image = program.GetImageInfo(ImageType.Backdrop, 0); image = program.GetImageInfo(ImageType.Backdrop, 0);
if (image != null) if (image != null)
{ {
try try
{ {
dto.ParentBackdropImageTags = new List<string> dto.ParentBackdropImageTags = new string[]
{ {
_imageProcessor.GetImageCacheTag(program, image) _imageProcessor.GetImageCacheTag(program, image)
}; };
@ -349,24 +336,24 @@ namespace Emby.Server.Implementations.LiveTv
} }
} }
public DayPattern? GetDayPattern(List<DayOfWeek> days) public DayPattern? GetDayPattern(DayOfWeek[] days)
{ {
DayPattern? pattern = null; DayPattern? pattern = null;
if (days.Count > 0) if (days.Length > 0)
{ {
if (days.Count == 7) if (days.Length == 7)
{ {
pattern = DayPattern.Daily; pattern = DayPattern.Daily;
} }
else if (days.Count == 2) else if (days.Length == 2)
{ {
if (days.Contains(DayOfWeek.Saturday) && days.Contains(DayOfWeek.Sunday)) if (days.Contains(DayOfWeek.Saturday) && days.Contains(DayOfWeek.Sunday))
{ {
pattern = DayPattern.Weekends; pattern = DayPattern.Weekends;
} }
} }
else if (days.Count == 5) else if (days.Length == 5)
{ {
if (days.Contains(DayOfWeek.Monday) && days.Contains(DayOfWeek.Tuesday) && days.Contains(DayOfWeek.Wednesday) && days.Contains(DayOfWeek.Thursday) && days.Contains(DayOfWeek.Friday)) if (days.Contains(DayOfWeek.Monday) && days.Contains(DayOfWeek.Tuesday) && days.Contains(DayOfWeek.Wednesday) && days.Contains(DayOfWeek.Thursday) && days.Contains(DayOfWeek.Friday))
{ {
@ -384,7 +371,7 @@ namespace Emby.Server.Implementations.LiveTv
{ {
Name = info.Name, Name = info.Name,
Id = info.Id, Id = info.Id,
Clients = info.Clients, Clients = info.Clients.ToArray(),
ProgramName = info.ProgramName, ProgramName = info.ProgramName,
SourceType = info.SourceType, SourceType = info.SourceType,
Status = info.Status, Status = info.Status,
@ -543,7 +530,7 @@ namespace Emby.Server.Implementations.LiveTv
PostPaddingSeconds = dto.PostPaddingSeconds, PostPaddingSeconds = dto.PostPaddingSeconds,
IsPostPaddingRequired = dto.IsPostPaddingRequired, IsPostPaddingRequired = dto.IsPostPaddingRequired,
IsPrePaddingRequired = dto.IsPrePaddingRequired, IsPrePaddingRequired = dto.IsPrePaddingRequired,
Days = dto.Days, Days = dto.Days.ToList(),
Priority = dto.Priority, Priority = dto.Priority,
RecordAnyChannel = dto.RecordAnyChannel, RecordAnyChannel = dto.RecordAnyChannel,
RecordAnyTime = dto.RecordAnyTime, RecordAnyTime = dto.RecordAnyTime,

@ -985,9 +985,8 @@ namespace Emby.Server.Implementations.LiveTv
var queryResult = _libraryManager.QueryItems(internalQuery); var queryResult = _libraryManager.QueryItems(internalQuery);
var returnList = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user) var returnArray = (await _dtoService.GetBaseItemDtos(queryResult.Items, options, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
@ -998,7 +997,7 @@ namespace Emby.Server.Implementations.LiveTv
return result; return result;
} }
public async Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken) public async Task<QueryResult<BaseItem>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken)
{ {
var user = _userManager.GetUserById(query.UserId); var user = _userManager.GetUserById(query.UserId);
@ -1036,10 +1035,10 @@ namespace Emby.Server.Implementations.LiveTv
} }
} }
var programList = _libraryManager.QueryItems(internalQuery).Items.Cast<LiveTvProgram>().ToList(); var programList = _libraryManager.QueryItems(internalQuery).Items;
var totalCount = programList.Count; var totalCount = programList.Length;
IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.OrderBy(i => i.StartDate.Date); IOrderedEnumerable<LiveTvProgram> orderedPrograms = programList.Cast<LiveTvProgram>().OrderBy(i => i.StartDate.Date);
if (query.IsAiring ?? false) if (query.IsAiring ?? false)
{ {
@ -1047,14 +1046,14 @@ namespace Emby.Server.Implementations.LiveTv
.ThenByDescending(i => GetRecommendationScore(i, user.Id, true)); .ThenByDescending(i => GetRecommendationScore(i, user.Id, true));
} }
IEnumerable<LiveTvProgram> programs = orderedPrograms; IEnumerable<BaseItem> programs = orderedPrograms;
if (query.Limit.HasValue) if (query.Limit.HasValue)
{ {
programs = programs.Take(query.Limit.Value); programs = programs.Take(query.Limit.Value);
} }
var result = new QueryResult<LiveTvProgram> var result = new QueryResult<BaseItem>
{ {
Items = programs.ToArray(), Items = programs.ToArray(),
TotalRecordCount = totalCount TotalRecordCount = totalCount
@ -1071,9 +1070,8 @@ namespace Emby.Server.Implementations.LiveTv
var user = _userManager.GetUserById(query.UserId); var user = _userManager.GetUserById(query.UserId);
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user) var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
@ -1262,8 +1260,8 @@ namespace Emby.Server.Implementations.LiveTv
progress.Report(100 * percent); progress.Report(100 * percent);
} }
await CleanDatabaseInternal(newChannelIdList, new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false); await CleanDatabaseInternal(newChannelIdList.ToArray(), new[] { typeof(LiveTvChannel).Name }, progress, cancellationToken).ConfigureAwait(false);
await CleanDatabaseInternal(newProgramIdList, new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false); await CleanDatabaseInternal(newProgramIdList.ToArray(), new[] { typeof(LiveTvProgram).Name }, progress, cancellationToken).ConfigureAwait(false);
var coreService = _services.OfType<EmbyTV.EmbyTV>().FirstOrDefault(); var coreService = _services.OfType<EmbyTV.EmbyTV>().FirstOrDefault();
@ -1275,8 +1273,11 @@ namespace Emby.Server.Implementations.LiveTv
// Load these now which will prefetch metadata // Load these now which will prefetch metadata
var dtoOptions = new DtoOptions(); var dtoOptions = new DtoOptions();
dtoOptions.Fields.Remove(ItemFields.SyncInfo); var fields = dtoOptions.Fields.ToList();
dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); fields.Remove(ItemFields.SyncInfo);
fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields = fields.ToArray(fields.Count);
await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false); await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false);
progress.Report(100); progress.Report(100);
@ -1446,14 +1447,14 @@ namespace Emby.Server.Implementations.LiveTv
return new Tuple<List<Guid>, List<Guid>>(channels, programs); return new Tuple<List<Guid>, List<Guid>>(channels, programs);
} }
private async Task CleanDatabaseInternal(List<Guid> currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken) private async Task CleanDatabaseInternal(Guid[] currentIdList, string[] validTypes, IProgress<double> progress, CancellationToken cancellationToken)
{ {
var list = _itemRepo.GetItemIdsList(new InternalItemsQuery var list = _itemRepo.GetItemIdsList(new InternalItemsQuery
{ {
IncludeItemTypes = validTypes, IncludeItemTypes = validTypes,
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
}).ToList(); });
var numComplete = 0; var numComplete = 0;
@ -1543,7 +1544,7 @@ namespace Emby.Server.Implementations.LiveTv
var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false); var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
await CleanDatabaseInternal(idList.ToList(), new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false); await CleanDatabaseInternal(idList, new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }, new SimpleProgress<double>(), cancellationToken).ConfigureAwait(false);
_lastRecordingRefreshTime = DateTime.UtcNow; _lastRecordingRefreshTime = DateTime.UtcNow;
} }
@ -1701,11 +1702,9 @@ namespace Emby.Server.Implementations.LiveTv
DtoOptions = options DtoOptions = options
}); });
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user) var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
return new QueryResult<BaseItemDto> return new QueryResult<BaseItemDto>
{ {
Items = returnArray, Items = returnArray,
@ -1841,7 +1840,7 @@ namespace Emby.Server.Implementations.LiveTv
}; };
} }
public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, List<ItemFields> fields, User user = null) public async Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> tuples, ItemFields[] fields, User user = null)
{ {
var programTuples = new List<Tuple<BaseItemDto, string, string, string>>(); var programTuples = new List<Tuple<BaseItemDto, string, string, string>>();
var hasChannelImage = fields.Contains(ItemFields.ChannelImage); var hasChannelImage = fields.Contains(ItemFields.ChannelImage);
@ -1961,7 +1960,7 @@ namespace Emby.Server.Implementations.LiveTv
if (dto.MediaStreams == null) if (dto.MediaStreams == null)
{ {
dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToArray();
} }
if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue) if (info.Status == RecordingStatus.InProgress && info.EndDate.HasValue)
@ -1995,9 +1994,8 @@ namespace Emby.Server.Implementations.LiveTv
var internalResult = await GetInternalRecordings(query, options, cancellationToken).ConfigureAwait(false); var internalResult = await GetInternalRecordings(query, options, cancellationToken).ConfigureAwait(false);
var returnList = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user) var returnArray = (await _dtoService.GetBaseItemDtos(internalResult.Items, options, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
return new QueryResult<BaseItemDto> return new QueryResult<BaseItemDto>
{ {
@ -2479,7 +2477,7 @@ namespace Emby.Server.Implementations.LiveTv
var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false); var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false);
var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null); var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null);
info.Days = defaults.Item1.Days; info.Days = defaults.Item1.Days.ToArray();
info.DayPattern = _tvDtoService.GetDayPattern(info.Days); info.DayPattern = _tvDtoService.GetDayPattern(info.Days);
@ -2656,8 +2654,7 @@ namespace Emby.Server.Implementations.LiveTv
var series = recordings var series = recordings
.Where(i => i.IsSeries) .Where(i => i.IsSeries)
.ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase) .ToLookup(i => i.Name, StringComparer.OrdinalIgnoreCase);
.ToList();
groups.AddRange(series.OrderByString(i => i.Key).Select(i => new BaseItemDto groups.AddRange(series.OrderByString(i => i.Key).Select(i => new BaseItemDto
{ {
@ -2762,7 +2759,7 @@ namespace Emby.Server.Implementations.LiveTv
} }
} }
private async Task<IEnumerable<LiveTvServiceInfo>> GetServiceInfos(CancellationToken cancellationToken) private async Task<LiveTvServiceInfo[]> GetServiceInfos(CancellationToken cancellationToken)
{ {
var tasks = Services.Select(i => GetServiceInfo(i, cancellationToken)); var tasks = Services.Select(i => GetServiceInfo(i, cancellationToken));
@ -2806,7 +2803,7 @@ namespace Emby.Server.Implementations.LiveTv
return dto; return dto;
}).ToList(); }).ToArray();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -2822,25 +2819,24 @@ namespace Emby.Server.Implementations.LiveTv
public async Task<LiveTvInfo> GetLiveTvInfo(CancellationToken cancellationToken) public async Task<LiveTvInfo> GetLiveTvInfo(CancellationToken cancellationToken)
{ {
var services = await GetServiceInfos(CancellationToken.None).ConfigureAwait(false); var services = await GetServiceInfos(CancellationToken.None).ConfigureAwait(false);
var servicesList = services.ToList();
var info = new LiveTvInfo var info = new LiveTvInfo
{ {
Services = servicesList.ToList(), Services = services,
IsEnabled = servicesList.Count > 0 IsEnabled = services.Length > 0
}; };
info.EnabledUsers = _userManager.Users info.EnabledUsers = _userManager.Users
.Where(IsLiveTvEnabled) .Where(IsLiveTvEnabled)
.Select(i => i.Id.ToString("N")) .Select(i => i.Id.ToString("N"))
.ToList(); .ToArray();
return info; return info;
} }
private bool IsLiveTvEnabled(User user) private bool IsLiveTvEnabled(User user)
{ {
return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Count > 0); return user.Policy.EnableLiveTvAccess && (Services.Count > 1 || GetConfiguration().TunerHosts.Length > 0);
} }
public IEnumerable<User> GetEnabledUsers() public IEnumerable<User> GetEnabledUsers()
@ -2880,10 +2876,13 @@ namespace Emby.Server.Implementations.LiveTv
private void RemoveFields(DtoOptions options) private void RemoveFields(DtoOptions options)
{ {
options.Fields.Remove(ItemFields.CanDelete); var fields = options.Fields.ToList();
options.Fields.Remove(ItemFields.CanDownload);
options.Fields.Remove(ItemFields.DisplayPreferencesId); fields.Remove(ItemFields.CanDelete);
options.Fields.Remove(ItemFields.Etag); fields.Remove(ItemFields.CanDownload);
fields.Remove(ItemFields.DisplayPreferencesId);
fields.Remove(ItemFields.Etag);
options.Fields = fields.ToArray(fields.Count);
} }
public async Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken) public async Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken)
@ -2911,12 +2910,14 @@ namespace Emby.Server.Implementations.LiveTv
var config = GetConfiguration(); var config = GetConfiguration();
var index = config.TunerHosts.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); var list = config.TunerHosts.ToList();
var index = list.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
if (index == -1 || string.IsNullOrWhiteSpace(info.Id)) if (index == -1 || string.IsNullOrWhiteSpace(info.Id))
{ {
info.Id = Guid.NewGuid().ToString("N"); info.Id = Guid.NewGuid().ToString("N");
config.TunerHosts.Add(info); list.Add(info);
config.TunerHosts = list.ToArray(list.Count);
} }
else else
{ {
@ -2948,12 +2949,14 @@ namespace Emby.Server.Implementations.LiveTv
var config = GetConfiguration(); var config = GetConfiguration();
var index = config.ListingProviders.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase)); var list = config.ListingProviders.ToList();
var index = list.FindIndex(i => string.Equals(i.Id, info.Id, StringComparison.OrdinalIgnoreCase));
if (index == -1 || string.IsNullOrWhiteSpace(info.Id)) if (index == -1 || string.IsNullOrWhiteSpace(info.Id))
{ {
info.Id = Guid.NewGuid().ToString("N"); info.Id = Guid.NewGuid().ToString("N");
config.ListingProviders.Add(info); list.Add(info);
config.ListingProviders = list.ToArray(list.Count);
info.EnableNewProgramIds = true; info.EnableNewProgramIds = true;
} }
else else
@ -2972,7 +2975,7 @@ namespace Emby.Server.Implementations.LiveTv
{ {
var config = GetConfiguration(); var config = GetConfiguration();
config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList(); config.ListingProviders = config.ListingProviders.Where(i => !string.Equals(id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray();
_config.SaveConfiguration("livetv", config); _config.SaveConfiguration("livetv", config);
_taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>(); _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
@ -3004,7 +3007,7 @@ namespace Emby.Server.Implementations.LiveTv
var providerChannels = await GetChannelsFromListingsProviderData(providerId, CancellationToken.None) var providerChannels = await GetChannelsFromListingsProviderData(providerId, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
var mappings = listingsProviderInfo.ChannelMappings.ToList(); var mappings = listingsProviderInfo.ChannelMappings;
var tunerChannelMappings = var tunerChannelMappings =
tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList(); tunerChannels.Select(i => GetTunerChannelMapping(i, mappings, providerChannels)).ToList();
@ -3014,7 +3017,7 @@ namespace Emby.Server.Implementations.LiveTv
return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase)); return tunerChannelMappings.First(i => string.Equals(i.Id, tunerChannelId, StringComparison.OrdinalIgnoreCase));
} }
public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, List<NameValuePair> mappings, List<ChannelInfo> epgChannels) public TunerChannelMapping GetTunerChannelMapping(ChannelInfo tunerChannel, NameValuePair[] mappings, List<ChannelInfo> epgChannels)
{ {
var result = new TunerChannelMapping var result = new TunerChannelMapping
{ {
@ -3078,7 +3081,7 @@ namespace Emby.Server.Implementations.LiveTv
if (string.Equals(feature, "dvr-l", StringComparison.OrdinalIgnoreCase)) if (string.Equals(feature, "dvr-l", StringComparison.OrdinalIgnoreCase))
{ {
var config = GetConfiguration(); var config = GetConfiguration();
if (config.TunerHosts.Count > 0 && if (config.TunerHosts.Length > 0 &&
config.ListingProviders.Count(i => (i.EnableAllTuners || i.EnabledTuners.Length > 0) && string.Equals(i.Type, SchedulesDirect.TypeName, StringComparison.OrdinalIgnoreCase)) > 0) config.ListingProviders.Count(i => (i.EnableAllTuners || i.EnabledTuners.Length > 0) && string.Equals(i.Type, SchedulesDirect.TypeName, StringComparison.OrdinalIgnoreCase)) > 0)
{ {
return Task.FromResult(new MBRegistrationRecord return Task.FromResult(new MBRegistrationRecord

@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.LiveTv
public bool IsHidden public bool IsHidden
{ {
get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Count == 0; } get { return _liveTvManager.Services.Count == 1 && GetConfiguration().TunerHosts.Length == 0; }
} }
public bool IsEnabled public bool IsEnabled

@ -24,8 +24,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken) public async Task CopyUntilCancelled(Stream source, Action onStarted, CancellationToken cancellationToken)
{ {
byte[] buffer = new byte[BufferSize];
if (source == null) if (source == null)
{ {
throw new ArgumentNullException("source"); throw new ArgumentNullException("source");
@ -35,6 +33,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
byte[] buffer = new byte[BufferSize];
var bytesRead = source.Read(buffer, 0, buffer.Length); var bytesRead = source.Read(buffer, 0, buffer.Length);
if (bytesRead > 0) if (bytesRead > 0)
@ -47,12 +47,12 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//} //}
//else //else
{ {
byte[] copy = new byte[bytesRead]; //byte[] copy = new byte[bytesRead];
Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead); //Buffer.BlockCopy(buffer, 0, copy, 0, bytesRead);
foreach (var stream in allStreams) foreach (var stream in allStreams)
{ {
stream.Value.Queue(copy, 0, copy.Length); stream.Value.Queue(buffer, 0, bytesRead);
} }
} }

@ -13,7 +13,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public class QueueStream public class QueueStream
{ {
private readonly Stream _outputStream; private readonly Stream _outputStream;
private readonly ConcurrentQueue<Tuple<byte[], int, int>> _queue = new ConcurrentQueue<Tuple<byte[], int, int>>(); private readonly BlockingCollection<Tuple<byte[], int, int>> _queue = new BlockingCollection<Tuple<byte[], int, int>>();
public TaskCompletionSource<bool> TaskCompletion { get; private set; } public TaskCompletionSource<bool> TaskCompletion { get; private set; }
public Action<QueueStream> OnFinished { get; set; } public Action<QueueStream> OnFinished { get; set; }
@ -29,7 +29,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public void Queue(byte[] bytes, int offset, int count) public void Queue(byte[] bytes, int offset, int count)
{ {
_queue.Enqueue(new Tuple<byte[], int, int>(bytes, offset, count)); _queue.Add(new Tuple<byte[], int, int>(bytes, offset, count));
} }
public void Start(CancellationToken cancellationToken) public void Start(CancellationToken cancellationToken)
@ -37,17 +37,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
Task.Run(() => StartInternal(cancellationToken)); Task.Run(() => StartInternal(cancellationToken));
} }
private Tuple<byte[], int, int> Dequeue()
{
Tuple<byte[], int, int> result;
if (_queue.TryDequeue(out result))
{
return result;
}
return null;
}
private void OnClosed() private void OnClosed()
{ {
GC.Collect(); GC.Collect();
@ -79,7 +68,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
} }
} }
private async Task StartInternal(CancellationToken cancellationToken) private void StartInternal(CancellationToken cancellationToken)
{ {
try try
{ {
@ -87,15 +76,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var result = Dequeue(); foreach (var result in _queue.GetConsumingEnumerable())
if (result != null)
{ {
_outputStream.Write(result.Item1, result.Item2, result.Item3); _outputStream.Write(result.Item1, result.Item2, result.Item3);
} }
else
{
await Task.Delay(50, cancellationToken).ConfigureAwait(false);
}
} }
} }
catch (OperationCanceledException) catch (OperationCanceledException)

@ -132,7 +132,7 @@ namespace Emby.Server.Implementations.Localization
/// Gets the cultures. /// Gets the cultures.
/// </summary> /// </summary>
/// <returns>IEnumerable{CultureDto}.</returns> /// <returns>IEnumerable{CultureDto}.</returns>
public List<CultureDto> GetCultures() public CultureDto[] GetCultures()
{ {
var type = GetType(); var type = GetType();
var path = type.Namespace + ".iso6392.txt"; var path = type.Namespace + ".iso6392.txt";
@ -169,21 +169,21 @@ namespace Emby.Server.Implementations.Localization
return list.Where(i => !string.IsNullOrWhiteSpace(i.Name) && return list.Where(i => !string.IsNullOrWhiteSpace(i.Name) &&
!string.IsNullOrWhiteSpace(i.DisplayName) && !string.IsNullOrWhiteSpace(i.DisplayName) &&
!string.IsNullOrWhiteSpace(i.ThreeLetterISOLanguageName) && !string.IsNullOrWhiteSpace(i.ThreeLetterISOLanguageName) &&
!string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToList(); !string.IsNullOrWhiteSpace(i.TwoLetterISOLanguageName)).ToArray();
} }
/// <summary> /// <summary>
/// Gets the countries. /// Gets the countries.
/// </summary> /// </summary>
/// <returns>IEnumerable{CountryInfo}.</returns> /// <returns>IEnumerable{CountryInfo}.</returns>
public List<CountryInfo> GetCountries() public CountryInfo[] GetCountries()
{ {
var type = GetType(); var type = GetType();
var path = type.Namespace + ".countries.json"; var path = type.Namespace + ".countries.json";
using (var stream = _assemblyInfo.GetManifestResourceStream(type, path)) using (var stream = _assemblyInfo.GetManifestResourceStream(type, path))
{ {
return _jsonSerializer.DeserializeFromStream<List<CountryInfo>>(stream); return _jsonSerializer.DeserializeFromStream<CountryInfo[]>(stream);
} }
} }
@ -191,9 +191,9 @@ namespace Emby.Server.Implementations.Localization
/// Gets the parental ratings. /// Gets the parental ratings.
/// </summary> /// </summary>
/// <returns>IEnumerable{ParentalRating}.</returns> /// <returns>IEnumerable{ParentalRating}.</returns>
public IEnumerable<ParentalRating> GetParentalRatings() public ParentalRating[] GetParentalRatings()
{ {
return GetParentalRatingsDictionary().Values.ToList(); return GetParentalRatingsDictionary().Values.ToArray();
} }
/// <summary> /// <summary>
@ -382,9 +382,9 @@ namespace Emby.Server.Implementations.Localization
return culture + ".json"; return culture + ".json";
} }
public IEnumerable<LocalizatonOption> GetLocalizationOptions() public LocalizatonOption[] GetLocalizationOptions()
{ {
return new List<LocalizatonOption> return new LocalizatonOption[]
{ {
new LocalizatonOption{ Name="Arabic", Value="ar"}, new LocalizatonOption{ Name="Arabic", Value="ar"},
new LocalizatonOption{ Name="Bulgarian (Bulgaria)", Value="bg-BG"}, new LocalizatonOption{ Name="Bulgarian (Bulgaria)", Value="bg-BG"},
@ -421,7 +421,7 @@ namespace Emby.Server.Implementations.Localization
new LocalizatonOption{ Name="Ukrainian", Value="uk"}, new LocalizatonOption{ Name="Ukrainian", Value="uk"},
new LocalizatonOption{ Name="Vietnamese", Value="vi"} new LocalizatonOption{ Name="Vietnamese", Value="vi"}
}.OrderBy(i => i.Name); };
} }
} }

@ -129,7 +129,7 @@ namespace Emby.Server.Implementations.MediaEncoder
var protocol = MediaProtocol.File; var protocol = MediaProtocol.File;
var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, new List<string>()); var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, new string[] { });
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));

@ -28,21 +28,21 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.ApplicationUpdateInstalled.ToString(), Type = NotificationType.ApplicationUpdateInstalled.ToString(),
DefaultDescription = "{ReleaseNotes}", DefaultDescription = "{ReleaseNotes}",
DefaultTitle = "A new version of Emby Server has been installed.", DefaultTitle = "A new version of Emby Server has been installed.",
Variables = new List<string>{"Version"} Variables = new string[]{"Version"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.InstallationFailed.ToString(), Type = NotificationType.InstallationFailed.ToString(),
DefaultTitle = "{Name} installation failed.", DefaultTitle = "{Name} installation failed.",
Variables = new List<string>{"Name", "Version"} Variables = new string[]{"Name", "Version"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.PluginInstalled.ToString(), Type = NotificationType.PluginInstalled.ToString(),
DefaultTitle = "{Name} was installed.", DefaultTitle = "{Name} was installed.",
Variables = new List<string>{"Name", "Version"} Variables = new string[]{"Name", "Version"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
@ -50,14 +50,14 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.PluginError.ToString(), Type = NotificationType.PluginError.ToString(),
DefaultTitle = "{Name} has encountered an error.", DefaultTitle = "{Name} has encountered an error.",
DefaultDescription = "{ErrorMessage}", DefaultDescription = "{ErrorMessage}",
Variables = new List<string>{"Name", "ErrorMessage"} Variables = new string[]{"Name", "ErrorMessage"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.PluginUninstalled.ToString(), Type = NotificationType.PluginUninstalled.ToString(),
DefaultTitle = "{Name} was uninstalled.", DefaultTitle = "{Name} was uninstalled.",
Variables = new List<string>{"Name", "Version"} Variables = new string[]{"Name", "Version"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
@ -65,7 +65,7 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.PluginUpdateInstalled.ToString(), Type = NotificationType.PluginUpdateInstalled.ToString(),
DefaultTitle = "{Name} was updated.", DefaultTitle = "{Name} was updated.",
DefaultDescription = "{ReleaseNotes}", DefaultDescription = "{ReleaseNotes}",
Variables = new List<string>{"Name", "ReleaseNotes", "Version"} Variables = new string[]{"Name", "ReleaseNotes", "Version"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
@ -79,70 +79,70 @@ namespace Emby.Server.Implementations.Notifications
Type = NotificationType.TaskFailed.ToString(), Type = NotificationType.TaskFailed.ToString(),
DefaultTitle = "{Name} failed.", DefaultTitle = "{Name} failed.",
DefaultDescription = "{ErrorMessage}", DefaultDescription = "{ErrorMessage}",
Variables = new List<string>{"Name", "ErrorMessage"} Variables = new string[]{"Name", "ErrorMessage"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.NewLibraryContent.ToString(), Type = NotificationType.NewLibraryContent.ToString(),
DefaultTitle = "{Name} has been added to your media library.", DefaultTitle = "{Name} has been added to your media library.",
Variables = new List<string>{"Name"} Variables = new string[]{"Name"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.AudioPlayback.ToString(), Type = NotificationType.AudioPlayback.ToString(),
DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.", DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.",
Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.GamePlayback.ToString(), Type = NotificationType.GamePlayback.ToString(),
DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.", DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.",
Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.VideoPlayback.ToString(), Type = NotificationType.VideoPlayback.ToString(),
DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.", DefaultTitle = "{UserName} is playing {ItemName} on {DeviceName}.",
Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.AudioPlaybackStopped.ToString(), Type = NotificationType.AudioPlaybackStopped.ToString(),
DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.", DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.",
Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.GamePlaybackStopped.ToString(), Type = NotificationType.GamePlaybackStopped.ToString(),
DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.", DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.",
Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.VideoPlaybackStopped.ToString(), Type = NotificationType.VideoPlaybackStopped.ToString(),
DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.", DefaultTitle = "{UserName} has finished playing {ItemName} on {DeviceName}.",
Variables = new List<string>{"UserName", "ItemName", "DeviceName", "AppName"} Variables = new string[]{"UserName", "ItemName", "DeviceName", "AppName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.CameraImageUploaded.ToString(), Type = NotificationType.CameraImageUploaded.ToString(),
DefaultTitle = "A new camera image has been uploaded from {DeviceName}.", DefaultTitle = "A new camera image has been uploaded from {DeviceName}.",
Variables = new List<string>{"DeviceName"} Variables = new string[]{"DeviceName"}
}, },
new NotificationTypeInfo new NotificationTypeInfo
{ {
Type = NotificationType.UserLockedOut.ToString(), Type = NotificationType.UserLockedOut.ToString(),
DefaultTitle = "{UserName} has been locked out.", DefaultTitle = "{UserName} has been locked out.",
Variables = new List<string>{"UserName"} Variables = new string[]{"UserName"}
} }
}; };

@ -251,7 +251,7 @@ namespace Emby.Server.Implementations.Notifications
_typeFactories = notificationTypeFactories.ToArray(); _typeFactories = notificationTypeFactories.ToArray();
} }
public IEnumerable<NotificationTypeInfo> GetNotificationTypes() public List<NotificationTypeInfo> GetNotificationTypes()
{ {
var list = _typeFactories.Select(i => var list = _typeFactories.Select(i =>
{ {

@ -133,7 +133,7 @@ namespace Emby.Server.Implementations.Playlists
await playlist.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = true }, CancellationToken.None) await playlist.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = true }, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
if (options.ItemIdList.Count > 0) if (options.ItemIdList.Length > 0)
{ {
await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false) await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false)
{ {

@ -29,13 +29,6 @@ namespace Emby.Server.Implementations.Services
} }
} }
private Type[] GetGenericArguments(Type type)
{
return type.GetTypeInfo().IsGenericTypeDefinition
? type.GetTypeInfo().GenericTypeParameters
: type.GetTypeInfo().GenericTypeArguments;
}
public void RegisterService(HttpListenerHost appHost, Type serviceType) public void RegisterService(HttpListenerHost appHost, Type serviceType)
{ {
var processedReqs = new HashSet<Type>(); var processedReqs = new HashSet<Type>();
@ -50,38 +43,19 @@ namespace Emby.Server.Implementations.Services
ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions); ServiceExecGeneral.CreateServiceRunnersFor(requestType, actions);
var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>)); //var returnMarker = GetTypeWithGenericTypeDefinitionOf(requestType, typeof(IReturn<>));
var responseType = returnMarker != null ? //var responseType = returnMarker != null ?
GetGenericArguments(returnMarker)[0] // GetGenericArguments(returnMarker)[0]
: mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ? // : mi.ReturnType != typeof(object) && mi.ReturnType != typeof(void) ?
mi.ReturnType // mi.ReturnType
: Type.GetType(requestType.FullName + "Response"); // : Type.GetType(requestType.FullName + "Response");
RegisterRestPaths(appHost, requestType); RegisterRestPaths(appHost, requestType);
appHost.AddServiceInfo(serviceType, requestType, responseType); appHost.AddServiceInfo(serviceType, requestType);
} }
} }
private static Type GetTypeWithGenericTypeDefinitionOf(Type type, Type genericTypeDefinition)
{
foreach (var t in type.GetTypeInfo().ImplementedInterfaces)
{
if (t.GetTypeInfo().IsGenericType && t.GetGenericTypeDefinition() == genericTypeDefinition)
{
return t;
}
}
var genericType = FirstGenericType(type);
if (genericType != null && genericType.GetGenericTypeDefinition() == genericTypeDefinition)
{
return genericType;
}
return null;
}
public static Type FirstGenericType(Type type) public static Type FirstGenericType(Type type)
{ {
while (type != null) while (type != null)

@ -468,7 +468,7 @@ namespace Emby.Server.Implementations.Session
if (!userId.HasValue) if (!userId.HasValue)
{ {
sessionInfo.AdditionalUsers.Clear(); sessionInfo.AdditionalUsers = new SessionUserInfo[] { };
} }
if (sessionInfo.SessionController == null) if (sessionInfo.SessionController == null)
@ -1074,7 +1074,7 @@ namespace Emby.Server.Implementations.Session
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
{ {
EnableImages = false, EnableImages = false,
Fields = new List<ItemFields> Fields = new ItemFields[]
{ {
ItemFields.SortName ItemFields.SortName
} }
@ -1097,7 +1097,7 @@ namespace Emby.Server.Implementations.Session
DtoOptions = new DtoOptions(false) DtoOptions = new DtoOptions(false)
{ {
EnableImages = false, EnableImages = false,
Fields = new List<ItemFields> Fields = new ItemFields[]
{ {
ItemFields.SortName ItemFields.SortName
} }
@ -1340,11 +1340,15 @@ namespace Emby.Server.Implementations.Session
{ {
var user = _userManager.GetUserById(userId); var user = _userManager.GetUserById(userId);
session.AdditionalUsers.Add(new SessionUserInfo var list = session.AdditionalUsers.ToList();
list.Add(new SessionUserInfo
{ {
UserId = userId, UserId = userId,
UserName = user.Name UserName = user.Name
}); });
session.AdditionalUsers = list.ToArray(list.Count);
} }
} }
@ -1368,7 +1372,10 @@ namespace Emby.Server.Implementations.Session
if (user != null) if (user != null)
{ {
session.AdditionalUsers.Remove(user); var list = session.AdditionalUsers.ToList();
list.Remove(user);
session.AdditionalUsers = list.ToArray(list.Count);
} }
} }
@ -1661,35 +1668,39 @@ namespace Emby.Server.Implementations.Session
AddProgramRecordingInfo = false AddProgramRecordingInfo = false
}; };
dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); var fields = dtoOptions.Fields.ToList();
dtoOptions.Fields.Remove(ItemFields.SyncInfo);
dtoOptions.Fields.Remove(ItemFields.CanDelete); fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields.Remove(ItemFields.CanDownload); fields.Remove(ItemFields.SyncInfo);
dtoOptions.Fields.Remove(ItemFields.ChildCount); fields.Remove(ItemFields.CanDelete);
dtoOptions.Fields.Remove(ItemFields.CustomRating); fields.Remove(ItemFields.CanDownload);
dtoOptions.Fields.Remove(ItemFields.DateLastMediaAdded); fields.Remove(ItemFields.ChildCount);
dtoOptions.Fields.Remove(ItemFields.DateLastRefreshed); fields.Remove(ItemFields.CustomRating);
dtoOptions.Fields.Remove(ItemFields.DateLastSaved); fields.Remove(ItemFields.DateLastMediaAdded);
dtoOptions.Fields.Remove(ItemFields.DisplayPreferencesId); fields.Remove(ItemFields.DateLastRefreshed);
dtoOptions.Fields.Remove(ItemFields.Etag); fields.Remove(ItemFields.DateLastSaved);
dtoOptions.Fields.Remove(ItemFields.ExternalEtag); fields.Remove(ItemFields.DisplayPreferencesId);
dtoOptions.Fields.Remove(ItemFields.InheritedParentalRatingValue); fields.Remove(ItemFields.Etag);
dtoOptions.Fields.Remove(ItemFields.ItemCounts); fields.Remove(ItemFields.ExternalEtag);
dtoOptions.Fields.Remove(ItemFields.MediaSourceCount); fields.Remove(ItemFields.InheritedParentalRatingValue);
dtoOptions.Fields.Remove(ItemFields.MediaStreams); fields.Remove(ItemFields.ItemCounts);
dtoOptions.Fields.Remove(ItemFields.MediaSources); fields.Remove(ItemFields.MediaSourceCount);
dtoOptions.Fields.Remove(ItemFields.People); fields.Remove(ItemFields.MediaStreams);
dtoOptions.Fields.Remove(ItemFields.PlayAccess); fields.Remove(ItemFields.MediaSources);
dtoOptions.Fields.Remove(ItemFields.People); fields.Remove(ItemFields.People);
dtoOptions.Fields.Remove(ItemFields.ProductionLocations); fields.Remove(ItemFields.PlayAccess);
dtoOptions.Fields.Remove(ItemFields.RecursiveItemCount); fields.Remove(ItemFields.People);
dtoOptions.Fields.Remove(ItemFields.RemoteTrailers); fields.Remove(ItemFields.ProductionLocations);
dtoOptions.Fields.Remove(ItemFields.SeasonUserData); fields.Remove(ItemFields.RecursiveItemCount);
dtoOptions.Fields.Remove(ItemFields.Settings); fields.Remove(ItemFields.RemoteTrailers);
dtoOptions.Fields.Remove(ItemFields.SortName); fields.Remove(ItemFields.SeasonUserData);
dtoOptions.Fields.Remove(ItemFields.Tags); fields.Remove(ItemFields.Settings);
dtoOptions.Fields.Remove(ItemFields.ThemeSongIds); fields.Remove(ItemFields.SortName);
dtoOptions.Fields.Remove(ItemFields.ThemeVideoIds); fields.Remove(ItemFields.Tags);
fields.Remove(ItemFields.ThemeSongIds);
fields.Remove(ItemFields.ThemeVideoIds);
dtoOptions.Fields = fields.ToArray(fields.Count);
_itemInfoDtoOptions = dtoOptions; _itemInfoDtoOptions = dtoOptions;
} }
@ -1698,7 +1709,7 @@ namespace Emby.Server.Implementations.Session
if (mediaSource != null) if (mediaSource != null)
{ {
info.MediaStreams = mediaSource.MediaStreams; info.MediaStreams = mediaSource.MediaStreams.ToArray();
} }
return info; return info;

@ -72,7 +72,7 @@ namespace Emby.Server.Implementations.TV
Recursive = true, Recursive = true,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
{ {
Fields = new List<ItemFields> Fields = new ItemFields[]
{ {
ItemFields.SeriesPresentationUniqueKey ItemFields.SeriesPresentationUniqueKey
} }
@ -128,7 +128,7 @@ namespace Emby.Server.Implementations.TV
Limit = limit, Limit = limit,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
{ {
Fields = new List<ItemFields> Fields = new ItemFields[]
{ {
ItemFields.SeriesPresentationUniqueKey ItemFields.SeriesPresentationUniqueKey
}, },
@ -207,7 +207,7 @@ namespace Emby.Server.Implementations.TV
ParentIndexNumberNotEquals = 0, ParentIndexNumberNotEquals = 0,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
{ {
Fields = new List<ItemFields> Fields = new ItemFields[]
{ {
ItemFields.SortName ItemFields.SortName
}, },

@ -157,7 +157,7 @@ namespace Emby.Server.Implementations.Updates
/// Gets all available packages. /// Gets all available packages.
/// </summary> /// </summary>
/// <returns>Task{List{PackageInfo}}.</returns> /// <returns>Task{List{PackageInfo}}.</returns>
public async Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken, public async Task<PackageInfo[]> GetAvailablePackages(CancellationToken cancellationToken,
bool withRegistration = true, bool withRegistration = true,
string packageType = null, string packageType = null,
Version applicationVersion = null) Version applicationVersion = null)
@ -175,7 +175,7 @@ namespace Emby.Server.Implementations.Updates
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(json).ToList(); var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(json);
return FilterPackages(packages, packageType, applicationVersion); return FilterPackages(packages, packageType, applicationVersion);
} }
@ -184,7 +184,7 @@ namespace Emby.Server.Implementations.Updates
{ {
var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); var packages = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
return FilterPackages(packages.ToList(), packageType, applicationVersion); return FilterPackages(packages, packageType, applicationVersion);
} }
} }
@ -195,14 +195,14 @@ namespace Emby.Server.Implementations.Updates
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{List{PackageInfo}}.</returns> /// <returns>Task{List{PackageInfo}}.</returns>
public async Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken) public async Task<PackageInfo[]> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
{ {
_logger.Info("Opening {0}", PackageCachePath); _logger.Info("Opening {0}", PackageCachePath);
try try
{ {
using (var stream = _fileSystem.OpenRead(PackageCachePath)) using (var stream = _fileSystem.OpenRead(PackageCachePath))
{ {
var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList(); var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream);
if (DateTime.UtcNow - _lastPackageUpdateTime > GetCacheLength()) if (DateTime.UtcNow - _lastPackageUpdateTime > GetCacheLength())
{ {
@ -221,7 +221,7 @@ namespace Emby.Server.Implementations.Updates
await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false); await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false);
using (var stream = _fileSystem.OpenRead(PackageCachePath)) using (var stream = _fileSystem.OpenRead(PackageCachePath))
{ {
return _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList(); return _jsonSerializer.DeserializeFromStream<PackageInfo[]>(stream);
} }
} }
@ -288,31 +288,29 @@ namespace Emby.Server.Implementations.Updates
} }
} }
protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages) protected PackageInfo[] FilterPackages(List<PackageInfo> packages)
{ {
foreach (var package in packages) foreach (var package in packages)
{ {
package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl)) package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
.OrderByDescending(GetPackageVersion).ToList(); .OrderByDescending(GetPackageVersion).ToArray();
} }
// Remove packages with no versions // Remove packages with no versions
packages = packages.Where(p => p.versions.Any()).ToList(); return packages.Where(p => p.versions.Any()).ToArray();
return packages;
} }
protected IEnumerable<PackageInfo> FilterPackages(List<PackageInfo> packages, string packageType, Version applicationVersion) protected PackageInfo[] FilterPackages(PackageInfo[] packages, string packageType, Version applicationVersion)
{ {
foreach (var package in packages) foreach (var package in packages)
{ {
package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl)) package.versions = package.versions.Where(v => !string.IsNullOrWhiteSpace(v.sourceUrl))
.OrderByDescending(GetPackageVersion).ToList(); .OrderByDescending(GetPackageVersion).ToArray();
} }
if (!string.IsNullOrWhiteSpace(packageType)) if (!string.IsNullOrWhiteSpace(packageType))
{ {
packages = packages.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)).ToList(); packages = packages.Where(p => string.Equals(p.type, packageType, StringComparison.OrdinalIgnoreCase)).ToArray();
} }
// If an app version was supplied, filter the versions for each package to only include supported versions // If an app version was supplied, filter the versions for each package to only include supported versions
@ -320,14 +318,12 @@ namespace Emby.Server.Implementations.Updates
{ {
foreach (var package in packages) foreach (var package in packages)
{ {
package.versions = package.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToList(); package.versions = package.versions.Where(v => IsPackageVersionUpToDate(v, applicationVersion)).ToArray();
} }
} }
// Remove packages with no versions // Remove packages with no versions
packages = packages.Where(p => p.versions.Any()).ToList(); return packages.Where(p => p.versions.Any()).ToArray();
return packages;
} }
/// <summary> /// <summary>
@ -418,30 +414,24 @@ namespace Emby.Server.Implementations.Updates
/// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns> /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns>
public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version applicationVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken) public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version applicationVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken)
{ {
var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); if (!_config.CommonConfiguration.EnableAutoUpdate)
var plugins = _applicationHost.Plugins.ToList();
if (withAutoUpdateEnabled)
{ {
plugins = plugins return new PackageVersionInfo[] { };
.Where(p => _config.CommonConfiguration.EnableAutoUpdate)
.ToList();
} }
var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
var systemUpdateLevel = GetSystemUpdateLevel(); var systemUpdateLevel = GetSystemUpdateLevel();
// Figure out what needs to be installed // Figure out what needs to be installed
var packages = plugins.Select(p => return _applicationHost.Plugins.Select(p =>
{ {
var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Id.ToString(), applicationVersion, systemUpdateLevel); var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Id.ToString(), applicationVersion, systemUpdateLevel);
return latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null; return latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null;
}).Where(i => i != null).ToList(); }).Where(i => i != null)
.Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase)));
return packages
.Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase)));
} }
/// <summary> /// <summary>

@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api namespace MediaBrowser.Api
{ {
@ -54,6 +55,17 @@ namespace MediaBrowser.Api
return Request.Headers[name]; return Request.Headers[name];
} }
private static readonly string[] EmptyStringArray = new string[] { };
public static string[] SplitValue(string value, char delim)
{
if (string.IsNullOrWhiteSpace(value))
{
return EmptyStringArray;
}
return value.Split(new[] { delim }, StringSplitOptions.RemoveEmptyEntries);
}
/// <summary> /// <summary>
/// To the optimized result. /// To the optimized result.
/// </summary> /// </summary>
@ -128,7 +140,7 @@ namespace MediaBrowser.Api
var hasFields = request as IHasItemFields; var hasFields = request as IHasItemFields;
if (hasFields != null) if (hasFields != null)
{ {
options.Fields = hasFields.GetItemFields().ToList(); options.Fields = hasFields.GetItemFields();
} }
var client = authInfo.Client ?? string.Empty; var client = authInfo.Client ?? string.Empty;
@ -137,7 +149,9 @@ namespace MediaBrowser.Api
client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 || client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1) client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
{ {
options.Fields.Add(Model.Querying.ItemFields.RecursiveItemCount); var list = options.Fields.ToList();
list.Add(Model.Querying.ItemFields.RecursiveItemCount);
options.Fields = list.ToArray(list.Count);
} }
if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 || if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
@ -148,7 +162,9 @@ namespace MediaBrowser.Api
client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 || client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1) client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
{ {
options.Fields.Add(Model.Querying.ItemFields.ChildCount); var list = options.Fields.ToList();
list.Add(Model.Querying.ItemFields.ChildCount);
options.Fields = list.ToArray(list.Count);
} }
var hasDtoOptions = request as IHasDtoOptions; var hasDtoOptions = request as IHasDtoOptions;
@ -167,7 +183,7 @@ namespace MediaBrowser.Api
if (!string.IsNullOrWhiteSpace(hasDtoOptions.EnableImageTypes)) if (!string.IsNullOrWhiteSpace(hasDtoOptions.EnableImageTypes))
{ {
options.ImageTypes = (hasDtoOptions.EnableImageTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToList(); options.ImageTypes = (hasDtoOptions.EnableImageTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToArray();
} }
} }

@ -55,7 +55,7 @@ namespace MediaBrowser.Api
} }
[Route("/Channels/Features", "GET", Summary = "Gets features for a channel")] [Route("/Channels/Features", "GET", Summary = "Gets features for a channel")]
public class GetAllChannelFeatures : IReturn<List<ChannelFeatures>> public class GetAllChannelFeatures : IReturn<ChannelFeatures[]>
{ {
} }
@ -187,7 +187,7 @@ namespace MediaBrowser.Api
public object Get(GetAllChannelFeatures request) public object Get(GetAllChannelFeatures request)
{ {
var result = _channelManager.GetAllChannelFeatures().ToList(); var result = _channelManager.GetAllChannelFeatures();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
@ -247,7 +247,7 @@ namespace MediaBrowser.Api
ChannelIds = (request.ChannelIds ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(), ChannelIds = (request.ChannelIds ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(),
UserId = request.UserId, UserId = request.UserId,
Filters = request.GetFilters().ToArray(), Filters = request.GetFilters().ToArray(),
Fields = request.GetItemFields().ToList() Fields = request.GetItemFields()
}, CancellationToken.None).ConfigureAwait(false); }, CancellationToken.None).ConfigureAwait(false);

@ -62,7 +62,7 @@ namespace MediaBrowser.Api
[Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")] [Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")]
[Authenticated(Roles = "Admin")] [Authenticated(Roles = "Admin")]
public class GetMetadataPlugins : IReturn<List<MetadataPluginSummary>> public class GetMetadataPlugins : IReturn<MetadataPluginSummary[]>
{ {
} }
@ -170,7 +170,7 @@ namespace MediaBrowser.Api
public object Get(GetMetadataPlugins request) public object Get(GetMetadataPlugins request)
{ {
return ToOptimizedSerializedResultUsingCache(_providerManager.GetAllMetadataPlugins().ToList()); return ToOptimizedSerializedResultUsingCache(_providerManager.GetAllMetadataPlugins());
} }
} }
} }

@ -1,14 +1,13 @@
using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Dlna namespace MediaBrowser.Api.Dlna
{ {
[Route("/Dlna/ProfileInfos", "GET", Summary = "Gets a list of profiles")] [Route("/Dlna/ProfileInfos", "GET", Summary = "Gets a list of profiles")]
public class GetProfileInfos : IReturn<List<DeviceProfileInfo>> public class GetProfileInfos : IReturn<DeviceProfileInfo[]>
{ {
} }
@ -53,7 +52,7 @@ namespace MediaBrowser.Api.Dlna
public object Get(GetProfileInfos request) public object Get(GetProfileInfos request)
{ {
var result = _dlnaManager.GetProfileInfos().ToList(); var result = _dlnaManager.GetProfileInfos().ToArray();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }

@ -226,7 +226,7 @@ namespace MediaBrowser.Api
return ToOptimizedSerializedResultUsingCache(GetNetworkShares(path).OrderBy(i => i.Path).ToList()); return ToOptimizedSerializedResultUsingCache(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
} }
return ToOptimizedSerializedResultUsingCache(GetFileSystemEntries(request).OrderBy(i => i.Path).ToList()); return ToOptimizedSerializedResultUsingCache(GetFileSystemEntries(request).ToList());
} }
public object Get(GetNetworkShares request) public object Get(GetNetworkShares request)
@ -271,9 +271,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public object Get(GetNetworkDevices request) public object Get(GetNetworkDevices request)
{ {
var result = _networkManager.GetNetworkDevices() var result = _networkManager.GetNetworkDevices().ToList();
.OrderBy(i => i.Path)
.ToList();
return ToOptimizedSerializedResultUsingCache(result); return ToOptimizedSerializedResultUsingCache(result);
} }
@ -300,7 +298,6 @@ namespace MediaBrowser.Api
/// <returns>IEnumerable{FileSystemEntryInfo}.</returns> /// <returns>IEnumerable{FileSystemEntryInfo}.</returns>
private IEnumerable<FileSystemEntryInfo> GetFileSystemEntries(GetDirectoryContents request) private IEnumerable<FileSystemEntryInfo> GetFileSystemEntries(GetDirectoryContents request)
{ {
// using EnumerateFileSystemInfos doesn't handle reparse points (symlinks)
var entries = _fileSystem.GetFileSystemEntries(request.Path).Where(i => var entries = _fileSystem.GetFileSystemEntries(request.Path).Where(i =>
{ {
if (!request.IncludeHidden && i.IsHidden) if (!request.IncludeHidden && i.IsHidden)
@ -329,7 +326,7 @@ namespace MediaBrowser.Api
Path = f.FullName, Path = f.FullName,
Type = f.IsDirectory ? FileSystemEntryType.Directory : FileSystemEntryType.File Type = f.IsDirectory ? FileSystemEntryType.Directory : FileSystemEntryType.File
}).ToList(); });
} }
public object Get(GetParentPath request) public object Get(GetParentPath request)

@ -108,7 +108,7 @@ namespace MediaBrowser.Api
EnableTotalRecordCount = false, EnableTotalRecordCount = false,
DtoOptions = new Controller.Dto.DtoOptions DtoOptions = new Controller.Dto.DtoOptions
{ {
Fields = new List<ItemFields> { ItemFields.Genres, ItemFields.Tags }, Fields = new ItemFields[] { ItemFields.Genres, ItemFields.Tags },
EnableImages = false, EnableImages = false,
EnableUserData = false EnableUserData = false
} }

@ -28,21 +28,7 @@ namespace MediaBrowser.Api
/// Class GetGameSystemSummaries /// Class GetGameSystemSummaries
/// </summary> /// </summary>
[Route("/Games/SystemSummaries", "GET", Summary = "Finds games similar to a given game.")] [Route("/Games/SystemSummaries", "GET", Summary = "Finds games similar to a given game.")]
public class GetGameSystemSummaries : IReturn<List<GameSystemSummary>> public class GetGameSystemSummaries : IReturn<GameSystemSummary[]>
{
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string UserId { get; set; }
}
/// <summary>
/// Class GetGameSystemSummaries
/// </summary>
[Route("/Games/PlayerIndex", "GET", Summary = "Gets an index of players (1-x) and the number of games listed under each")]
public class GetPlayerIndex : IReturn<List<ItemIndex>>
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -117,47 +103,17 @@ namespace MediaBrowser.Api
EnableImages = false EnableImages = false
} }
}; };
var gameSystems = _libraryManager.GetItemList(query)
.Cast<GameSystem>()
.ToList();
var result = gameSystems var result = _libraryManager.GetItemList(query)
.Cast<GameSystem>()
.Select(i => GetSummary(i, user)) .Select(i => GetSummary(i, user))
.ToList(); .ToArray();
return ToOptimizedSerializedResultUsingCache(result); return ToOptimizedSerializedResultUsingCache(result);
} }
private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
public object Get(GetPlayerIndex request)
{
var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId);
var query = new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Game).Name },
DtoOptions = new DtoOptions(false)
{
EnableImages = false
}
};
var games = _libraryManager.GetItemList(query)
.Cast<Game>()
.ToList();
var lookup = games
.ToLookup(i => i.PlayersSupported ?? -1)
.OrderBy(i => i.Key)
.Select(i => new ItemIndex
{
ItemCount = i.Count(),
Name = i.Key == -1 ? string.Empty : i.Key.ToString(UsCulture)
})
.ToList();
return ToOptimizedSerializedResultUsingCache(lookup);
}
/// <summary> /// <summary>
/// Gets the summary. /// Gets the summary.
/// </summary> /// </summary>
@ -183,15 +139,15 @@ namespace MediaBrowser.Api
} }
}); });
var games = items.Cast<Game>().ToList(); var games = items.Cast<Game>().ToArray();
summary.ClientInstalledGameCount = games.Count(i => i.IsPlaceHolder); summary.ClientInstalledGameCount = games.Count(i => i.IsPlaceHolder);
summary.GameCount = games.Count; summary.GameCount = games.Length;
summary.GameFileExtensions = games.Where(i => !i.IsPlaceHolder).Select(i => Path.GetExtension(i.Path)) summary.GameFileExtensions = games.Where(i => !i.IsPlaceHolder).Select(i => Path.GetExtension(i.Path))
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.ToList(); .ToArray();
return summary; return summary;
} }
@ -234,7 +190,7 @@ namespace MediaBrowser.Api
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
Items = returnList.ToArray(returnList.Count), Items = returnList,
TotalRecordCount = itemsResult.Count TotalRecordCount = itemsResult.Count
}; };

@ -27,7 +27,7 @@ namespace MediaBrowser.Api
/// </summary> /// </summary>
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
/// <returns>IEnumerable{ItemFields}.</returns> /// <returns>IEnumerable{ItemFields}.</returns>
public static IEnumerable<ItemFields> GetItemFields(this IHasItemFields request) public static ItemFields[] GetItemFields(this IHasItemFields request)
{ {
var val = request.Fields; var val = request.Fields;
@ -46,7 +46,7 @@ namespace MediaBrowser.Api
} }
return null; return null;
}).Where(i => i.HasValue).Select(i => i.Value); }).Where(i => i.HasValue).Select(i => i.Value).ToArray();
} }
} }
} }

@ -150,7 +150,7 @@ namespace MediaBrowser.Api.Images
}, CancellationToken.None).ConfigureAwait(false); }, CancellationToken.None).ConfigureAwait(false);
var imagesList = images.ToList(); var imagesList = images.ToArray();
var allProviders = _providerManager.GetRemoteImageProviderInfo(item); var allProviders = _providerManager.GetRemoteImageProviderInfo(item);
@ -161,22 +161,22 @@ namespace MediaBrowser.Api.Images
var result = new RemoteImageResult var result = new RemoteImageResult
{ {
TotalRecordCount = imagesList.Count, TotalRecordCount = imagesList.Length,
Providers = allProviders.Select(i => i.Name) Providers = allProviders.Select(i => i.Name)
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.ToList() .ToArray()
}; };
if (request.StartIndex.HasValue) if (request.StartIndex.HasValue)
{ {
imagesList = imagesList.Skip(request.StartIndex.Value) imagesList = imagesList.Skip(request.StartIndex.Value)
.ToList(); .ToArray();
} }
if (request.Limit.HasValue) if (request.Limit.HasValue)
{ {
imagesList = imagesList.Take(request.Limit.Value) imagesList = imagesList.Take(request.Limit.Value)
.ToList(); .ToArray();
} }
result.Images = imagesList; result.Images = imagesList;

@ -64,8 +64,8 @@ namespace MediaBrowser.Api
var info = new MetadataEditorInfo var info = new MetadataEditorInfo
{ {
ParentalRatingOptions = _localizationManager.GetParentalRatings().ToList(), ParentalRatingOptions = _localizationManager.GetParentalRatings(),
ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToList(), ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToArray(),
Countries = _localizationManager.GetCountries(), Countries = _localizationManager.GetCountries(),
Cultures = _localizationManager.GetCultures() Cultures = _localizationManager.GetCultures()
}; };
@ -78,14 +78,14 @@ namespace MediaBrowser.Api
if (string.IsNullOrWhiteSpace(inheritedContentType) || !string.IsNullOrWhiteSpace(configuredContentType)) if (string.IsNullOrWhiteSpace(inheritedContentType) || !string.IsNullOrWhiteSpace(configuredContentType))
{ {
info.ContentTypeOptions = GetContentTypeOptions(true); info.ContentTypeOptions = GetContentTypeOptions(true).ToArray();
info.ContentType = configuredContentType; info.ContentType = configuredContentType;
if (string.IsNullOrWhiteSpace(inheritedContentType) || string.Equals(inheritedContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) if (string.IsNullOrWhiteSpace(inheritedContentType) || string.Equals(inheritedContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{ {
info.ContentTypeOptions = info.ContentTypeOptions info.ContentTypeOptions = info.ContentTypeOptions
.Where(i => string.IsNullOrWhiteSpace(i.Value) || string.Equals(i.Value, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) .Where(i => string.IsNullOrWhiteSpace(i.Value) || string.Equals(i.Value, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
.ToList(); .ToArray();
} }
} }
} }

@ -227,7 +227,7 @@ namespace MediaBrowser.Api.Library
[Route("/Library/MediaFolders", "GET", Summary = "Gets all user media folders.")] [Route("/Library/MediaFolders", "GET", Summary = "Gets all user media folders.")]
[Authenticated] [Authenticated]
public class GetMediaFolders : IReturn<ItemsResult> public class GetMediaFolders : IReturn<QueryResult<BaseItemDto>>
{ {
[ApiMember(Name = "IsHidden", Description = "Optional. Filter by folders that are marked hidden, or not.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "IsHidden", Description = "Optional. Filter by folders that are marked hidden, or not.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? IsHidden { get; set; } public bool? IsHidden { get; set; }
@ -400,7 +400,7 @@ namespace MediaBrowser.Api.Library
}); });
} }
return new ItemsResult(); return new QueryResult<BaseItemDto>();
} }
public object Get(GetMediaFolders request) public object Get(GetMediaFolders request)
@ -416,7 +416,7 @@ namespace MediaBrowser.Api.Library
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
TotalRecordCount = items.Count, TotalRecordCount = items.Count,
@ -615,7 +615,7 @@ namespace MediaBrowser.Api.Library
parent = parent.GetParent(); parent = parent.GetParent();
} }
return baseItemDtos.ToList(); return baseItemDtos;
} }
private BaseItem TranslateParentItem(BaseItem item, User user) private BaseItem TranslateParentItem(BaseItem item, User user)

@ -648,7 +648,7 @@ namespace MediaBrowser.Api.LiveTv
{ {
public List<TunerChannelMapping> TunerChannels { get; set; } public List<TunerChannelMapping> TunerChannels { get; set; }
public List<NameIdPair> ProviderChannels { get; set; } public List<NameIdPair> ProviderChannels { get; set; }
public List<NameValuePair> Mappings { get; set; } public NameValuePair[] Mappings { get; set; }
public string ProviderName { get; set; } public string ProviderName { get; set; }
} }
@ -789,7 +789,7 @@ namespace MediaBrowser.Api.LiveTv
var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None) var providerChannels = await _liveTvManager.GetChannelsFromListingsProviderData(request.ProviderId, CancellationToken.None)
.ConfigureAwait(false); .ConfigureAwait(false);
var mappings = listingsProviderInfo.ChannelMappings.ToList(); var mappings = listingsProviderInfo.ChannelMappings;
var result = new ChannelMappingOptions var result = new ChannelMappingOptions
{ {
@ -862,7 +862,7 @@ namespace MediaBrowser.Api.LiveTv
{ {
var config = GetConfiguration(); var config = GetConfiguration();
config.TunerHosts = config.TunerHosts.Where(i => !string.Equals(request.Id, i.Id, StringComparison.OrdinalIgnoreCase)).ToList(); config.TunerHosts = config.TunerHosts.Where(i => !string.Equals(request.Id, i.Id, StringComparison.OrdinalIgnoreCase)).ToArray();
_config.SaveConfiguration("livetv", config); _config.SaveConfiguration("livetv", config);
} }
@ -922,9 +922,8 @@ namespace MediaBrowser.Api.LiveTv
options.AddCurrentProgram = request.AddCurrentProgram; options.AddCurrentProgram = request.AddCurrentProgram;
var returnList = (await _dtoService.GetBaseItemDtos(channelResult.Items, options, user) var returnArray = (await _dtoService.GetBaseItemDtos(channelResult.Items, options, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var returnArray = returnList.ToArray(returnList.Count);
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
@ -937,10 +936,13 @@ namespace MediaBrowser.Api.LiveTv
private void RemoveFields(DtoOptions options) private void RemoveFields(DtoOptions options)
{ {
options.Fields.Remove(ItemFields.CanDelete); var fields = options.Fields.ToList();
options.Fields.Remove(ItemFields.CanDownload);
options.Fields.Remove(ItemFields.DisplayPreferencesId); fields.Remove(ItemFields.CanDelete);
options.Fields.Remove(ItemFields.Etag); fields.Remove(ItemFields.CanDownload);
fields.Remove(ItemFields.DisplayPreferencesId);
fields.Remove(ItemFields.Etag);
options.Fields = fields.ToArray(fields.Count);
} }
public object Get(GetChannel request) public object Get(GetChannel request)

@ -11,7 +11,7 @@ namespace MediaBrowser.Api
/// Class GetCultures /// Class GetCultures
/// </summary> /// </summary>
[Route("/Localization/Cultures", "GET", Summary = "Gets known cultures")] [Route("/Localization/Cultures", "GET", Summary = "Gets known cultures")]
public class GetCultures : IReturn<List<CultureDto>> public class GetCultures : IReturn<CultureDto[]>
{ {
} }
@ -19,7 +19,7 @@ namespace MediaBrowser.Api
/// Class GetCountries /// Class GetCountries
/// </summary> /// </summary>
[Route("/Localization/Countries", "GET", Summary = "Gets known countries")] [Route("/Localization/Countries", "GET", Summary = "Gets known countries")]
public class GetCountries : IReturn<List<CountryInfo>> public class GetCountries : IReturn<CountryInfo[]>
{ {
} }
@ -27,7 +27,7 @@ namespace MediaBrowser.Api
/// Class ParentalRatings /// Class ParentalRatings
/// </summary> /// </summary>
[Route("/Localization/ParentalRatings", "GET", Summary = "Gets known parental ratings")] [Route("/Localization/ParentalRatings", "GET", Summary = "Gets known parental ratings")]
public class GetParentalRatings : IReturn<List<ParentalRating>> public class GetParentalRatings : IReturn<ParentalRating[]>
{ {
} }
@ -35,7 +35,7 @@ namespace MediaBrowser.Api
/// Class ParentalRatings /// Class ParentalRatings
/// </summary> /// </summary>
[Route("/Localization/Options", "GET", Summary = "Gets localization options")] [Route("/Localization/Options", "GET", Summary = "Gets localization options")]
public class GetLocalizationOptions : IReturn<List<LocalizatonOption>> public class GetLocalizationOptions : IReturn<LocalizatonOption[]>
{ {
} }
@ -66,14 +66,14 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public object Get(GetParentalRatings request) public object Get(GetParentalRatings request)
{ {
var result = _localization.GetParentalRatings().ToList(); var result = _localization.GetParentalRatings();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
public object Get(GetLocalizationOptions request) public object Get(GetLocalizationOptions request)
{ {
var result = _localization.GetLocalizationOptions().ToList(); var result = _localization.GetLocalizationOptions();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }

@ -97,7 +97,6 @@
<Compile Include="Movies\MoviesService.cs" /> <Compile Include="Movies\MoviesService.cs" />
<Compile Include="NewsService.cs" /> <Compile Include="NewsService.cs" />
<Compile Include="NotificationsService.cs" /> <Compile Include="NotificationsService.cs" />
<Compile Include="PackageReviewService.cs" />
<Compile Include="PackageService.cs" /> <Compile Include="PackageService.cs" />
<Compile Include="PluginService.cs" /> <Compile Include="PluginService.cs" />
<Compile Include="Images\RemoteImageService.cs" /> <Compile Include="Images\RemoteImageService.cs" />

@ -71,8 +71,8 @@ namespace MediaBrowser.Api.Movies
IsLocked = request.IsLocked, IsLocked = request.IsLocked,
Name = request.Name, Name = request.Name,
ParentId = parentId, ParentId = parentId,
ItemIdList = (request.Ids ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(), ItemIdList = SplitValue(request.Ids, ','),
UserIds = new List<Guid> { new Guid(userId) } UserIds = new string[] { userId }
}).ConfigureAwait(false); }).ConfigureAwait(false);
@ -88,14 +88,14 @@ namespace MediaBrowser.Api.Movies
public void Post(AddToCollection request) public void Post(AddToCollection request)
{ {
var task = _collectionManager.AddToCollection(new Guid(request.Id), request.Ids.Split(',').Select(i => new Guid(i))); var task = _collectionManager.AddToCollection(new Guid(request.Id), SplitValue(request.Ids, ','));
Task.WaitAll(task); Task.WaitAll(task);
} }
public void Delete(RemoveFromCollection request) public void Delete(RemoveFromCollection request)
{ {
var task = _collectionManager.RemoveFromCollection(new Guid(request.Id), request.Ids.Split(',').Select(i => new Guid(i))); var task = _collectionManager.RemoveFromCollection(new Guid(request.Id), SplitValue(request.Ids, ','));
Task.WaitAll(task); Task.WaitAll(task);
} }

@ -170,7 +170,7 @@ namespace MediaBrowser.Api.Movies
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
Items = returnList.ToArray(returnList.Count), Items = returnList,
TotalRecordCount = itemsResult.Count TotalRecordCount = itemsResult.Count
}; };
@ -320,7 +320,7 @@ namespace MediaBrowser.Api.Movies
BaselineItemName = name, BaselineItemName = name,
CategoryId = name.GetMD5().ToString("N"), CategoryId = name.GetMD5().ToString("N"),
RecommendationType = type, RecommendationType = type,
Items = returnItems.ToArray(returnItems.Count) Items = returnItems
}; };
} }
} }
@ -360,7 +360,7 @@ namespace MediaBrowser.Api.Movies
BaselineItemName = name, BaselineItemName = name,
CategoryId = name.GetMD5().ToString("N"), CategoryId = name.GetMD5().ToString("N"),
RecommendationType = type, RecommendationType = type,
Items = returnItems.ToArray(returnItems.Count) Items = returnItems
}; };
} }
} }
@ -397,7 +397,7 @@ namespace MediaBrowser.Api.Movies
BaselineItemName = item.Name, BaselineItemName = item.Name,
CategoryId = item.Id.ToString("N"), CategoryId = item.Id.ToString("N"),
RecommendationType = type, RecommendationType = type,
Items = returnItems.ToArray(returnItems.Count) Items = returnItems
}; };
} }
} }

@ -4,6 +4,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Querying; using MediaBrowser.Model.Querying;
using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Collections;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
@ -11,7 +12,7 @@ using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Movies namespace MediaBrowser.Api.Movies
{ {
[Route("/Trailers", "GET", Summary = "Finds movies and trailers similar to a given trailer.")] [Route("/Trailers", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
public class Getrailers : BaseItemsRequest, IReturn<ItemsResult> public class Getrailers : BaseItemsRequest, IReturn<QueryResult<BaseItemDto>>
{ {
} }

@ -8,6 +8,7 @@ using MediaBrowser.Model.Querying;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Extensions;
@ -185,15 +186,20 @@ namespace MediaBrowser.Api.Music
{ {
var list = items; var list = items;
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
TotalRecordCount = list.Count TotalRecordCount = list.Count
}; };
var returnList = (await _dtoService.GetBaseItemDtos(list.Take(request.Limit ?? list.Count), dtoOptions, user) if (request.Limit.HasValue)
{
list = list.Take(request.Limit.Value).ToList();
}
var returnList = (await _dtoService.GetBaseItemDtos(list, dtoOptions, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
result.Items = returnList.ToArray(returnList.Count); result.Items = returnList;
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }

@ -99,7 +99,7 @@ namespace MediaBrowser.Api
public object Get(GetNotificationTypes request) public object Get(GetNotificationTypes request)
{ {
var result = _notificationManager.GetNotificationTypes().ToList(); var result = _notificationManager.GetNotificationTypes();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }

@ -1,162 +0,0 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Serialization;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Api
{
/// <summary>
/// Class InstallPackage
/// </summary>
[Route("/Packages/Reviews/{Id}", "POST", Summary = "Creates or updates a package review")]
public class CreateReviewRequest : IReturnVoid
{
/// <summary>
/// Gets or sets the Id.
/// </summary>
/// <value>The Id.</value>
[ApiMember(Name = "Id", Description = "Package Id", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "POST")]
public int Id { get; set; }
/// <summary>
/// Gets or sets the rating.
/// </summary>
/// <value>The review.</value>
[ApiMember(Name = "Rating", Description = "The rating value (1-5)", IsRequired = true, DataType = "int", ParameterType = "query", Verb = "POST")]
public int Rating { get; set; }
/// <summary>
/// Gets or sets the recommend value.
/// </summary>
/// <value>Whether or not this review recommends this item.</value>
[ApiMember(Name = "Recommend", Description = "Whether or not this review recommends this item", IsRequired = true, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool Recommend { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
[ApiMember(Name = "Title", Description = "Optional short description of review.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
public string Title { get; set; }
/// <summary>
/// Gets or sets the full review.
/// </summary>
/// <value>The full review.</value>
[ApiMember(Name = "Review", Description = "Optional full review.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
public string Review { get; set; }
}
/// <summary>
/// Class InstallPackage
/// </summary>
[Route("/Packages/{Id}/Reviews", "GET", Summary = "Gets reviews for a package")]
public class ReviewRequest : IReturn<List<PackageReviewInfo>>
{
/// <summary>
/// Gets or sets the Id.
/// </summary>
/// <value>The Id.</value>
[ApiMember(Name = "Id", Description = "Package Id", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
public int Id { get; set; }
/// <summary>
/// Gets or sets the max rating.
/// </summary>
/// <value>The max rating.</value>
[ApiMember(Name = "MaxRating", Description = "Retrieve only reviews less than or equal to this", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int MaxRating { get; set; }
/// <summary>
/// Gets or sets the min rating.
/// </summary>
/// <value>The max rating.</value>
[ApiMember(Name = "MinRating", Description = "Retrieve only reviews greator than or equal to this", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int MinRating { get; set; }
/// <summary>
/// Only retrieve reviews with at least a short review.
/// </summary>
/// <value>True if should only get reviews with a title.</value>
[ApiMember(Name = "ForceTitle", Description = "Whether or not to restrict results to those with a title", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool ForceTitle { get; set; }
/// <summary>
/// Gets or sets the limit for the query.
/// </summary>
/// <value>The max rating.</value>
[ApiMember(Name = "Limit", Description = "Limit the result to this many reviews (ordered by latest)", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int Limit { get; set; }
}
[Authenticated]
public class PackageReviewService : BaseApiService
{
private readonly IHttpClient _httpClient;
private readonly IJsonSerializer _serializer;
private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
private readonly IServerApplicationHost _appHost;
public PackageReviewService(IHttpClient httpClient, IJsonSerializer serializer, IServerApplicationHost appHost)
{
_httpClient = httpClient;
_serializer = serializer;
_appHost = appHost;
}
public async Task<object> Get(ReviewRequest request)
{
var parms = "?id=" + request.Id;
if (request.MaxRating > 0)
{
parms += "&max=" + request.MaxRating;
}
if (request.MinRating > 0)
{
parms += "&min=" + request.MinRating;
}
if (request.MinRating > 0)
{
parms += "&limit=" + request.Limit;
}
if (request.ForceTitle)
{
parms += "&title=true";
}
using (var result = await _httpClient.Get(MbAdminUrl + "/service/packageReview/retrieve" + parms, CancellationToken.None)
.ConfigureAwait(false))
{
var reviews = _serializer.DeserializeFromStream<List<PackageReviewInfo>>(result);
return ToOptimizedResult(reviews);
}
}
public void Post(CreateReviewRequest request)
{
var reviewText = WebUtility.HtmlEncode(request.Review ?? string.Empty);
var title = WebUtility.HtmlEncode(request.Title ?? string.Empty);
var review = new Dictionary<string, string>
{ { "id", request.Id.ToString(CultureInfo.InvariantCulture) },
{ "mac", _appHost.SystemId },
{ "rating", request.Rating.ToString(CultureInfo.InvariantCulture) },
{ "recommend", request.Recommend.ToString() },
{ "title", title },
{ "review", reviewText },
};
Task.WaitAll(_httpClient.Post(MbAdminUrl + "/service/packageReview/update", review, CancellationToken.None));
}
}
}

@ -40,7 +40,7 @@ namespace MediaBrowser.Api
/// </summary> /// </summary>
[Route("/Packages", "GET", Summary = "Gets available packages")] [Route("/Packages", "GET", Summary = "Gets available packages")]
[Authenticated] [Authenticated]
public class GetPackages : IReturn<List<PackageInfo>> public class GetPackages : IReturn<PackageInfo[]>
{ {
/// <summary> /// <summary>
/// Gets or sets the name. /// Gets or sets the name.
@ -66,7 +66,7 @@ namespace MediaBrowser.Api
/// </summary> /// </summary>
[Route("/Packages/Updates", "GET", Summary = "Gets available package updates for currently installed packages")] [Route("/Packages/Updates", "GET", Summary = "Gets available package updates for currently installed packages")]
[Authenticated(Roles = "Admin")] [Authenticated(Roles = "Admin")]
public class GetPackageVersionUpdates : IReturn<List<PackageVersionInfo>> public class GetPackageVersionUpdates : IReturn<PackageVersionInfo[]>
{ {
/// <summary> /// <summary>
/// Gets or sets the name. /// Gets or sets the name.
@ -148,24 +148,26 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public object Get(GetPackageVersionUpdates request) public object Get(GetPackageVersionUpdates request)
{ {
var result = new List<PackageVersionInfo>(); PackageVersionInfo[] result = null;
if (string.Equals(request.PackageType, "UserInstalled", StringComparison.OrdinalIgnoreCase) || string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase)) if (string.Equals(request.PackageType, "UserInstalled", StringComparison.OrdinalIgnoreCase) || string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase))
{ {
result.AddRange(_installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).Result.ToList()); result = _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).Result.ToArray();
} }
else if (string.Equals(request.PackageType, "System", StringComparison.OrdinalIgnoreCase) || string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase)) else if (string.Equals(request.PackageType, "System", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase))
{ {
var updateCheckResult = _appHost.CheckForApplicationUpdate(CancellationToken.None, new SimpleProgress<double>()).Result; var updateCheckResult = _appHost
.CheckForApplicationUpdate(CancellationToken.None, new SimpleProgress<double>()).Result;
if (updateCheckResult.IsUpdateAvailable) if (updateCheckResult.IsUpdateAvailable)
{ {
result.Add(updateCheckResult.Package); result = new PackageVersionInfo[] {updateCheckResult.Package};
} }
} }
return ToOptimizedResult(result); return ToOptimizedResult(result ?? new PackageVersionInfo[] { });
} }
/// <summary> /// <summary>
@ -176,10 +178,9 @@ namespace MediaBrowser.Api
public object Get(GetPackage request) public object Get(GetPackage request)
{ {
var packages = _installationManager.GetAvailablePackages(CancellationToken.None, applicationVersion: _appHost.ApplicationVersion).Result; var packages = _installationManager.GetAvailablePackages(CancellationToken.None, applicationVersion: _appHost.ApplicationVersion).Result;
var list = packages.ToList();
var result = list.FirstOrDefault(p => string.Equals(p.guid, request.AssemblyGuid ?? "none", StringComparison.OrdinalIgnoreCase)) var result = packages.FirstOrDefault(p => string.Equals(p.guid, request.AssemblyGuid ?? "none", StringComparison.OrdinalIgnoreCase))
?? list.FirstOrDefault(p => p.name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); ?? packages.FirstOrDefault(p => p.name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
@ -191,7 +192,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public async Task<object> Get(GetPackages request) public async Task<object> Get(GetPackages request)
{ {
var packages = await _installationManager.GetAvailablePackages(CancellationToken.None, false, request.PackageType, _appHost.ApplicationVersion).ConfigureAwait(false); IEnumerable<PackageInfo> packages = await _installationManager.GetAvailablePackages(CancellationToken.None, false, request.PackageType, _appHost.ApplicationVersion).ConfigureAwait(false);
if (!string.IsNullOrEmpty(request.TargetSystems)) if (!string.IsNullOrEmpty(request.TargetSystems))
{ {
@ -215,7 +216,7 @@ namespace MediaBrowser.Api
packages = packages.Where(p => p.enableInAppStore == request.IsAppStoreEnabled.Value); packages = packages.Where(p => p.enableInAppStore == request.IsAppStoreEnabled.Value);
} }
return ToOptimizedResult(packages.ToList()); return ToOptimizedResult(packages.ToArray());
} }
/// <summary> /// <summary>

@ -149,7 +149,7 @@ namespace MediaBrowser.Api
var result = await _playlistManager.CreatePlaylist(new PlaylistCreationRequest var result = await _playlistManager.CreatePlaylist(new PlaylistCreationRequest
{ {
Name = request.Name, Name = request.Name,
ItemIdList = (request.Ids ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(), ItemIdList = SplitValue(request.Ids, ','),
UserId = request.UserId, UserId = request.UserId,
MediaType = request.MediaType MediaType = request.MediaType
@ -193,10 +193,8 @@ namespace MediaBrowser.Api
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
var returnList = (await _dtoService.GetBaseItemDtos(items.Select(i => i.Item2), dtoOptions, user) var dtos = (await _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user)
.ConfigureAwait(false)); .ConfigureAwait(false));
var dtos = returnList
.ToArray(returnList.Count);
var index = 0; var index = 0;
foreach (var item in dtos) foreach (var item in dtos)
@ -205,7 +203,7 @@ namespace MediaBrowser.Api
index++; index++;
} }
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
Items = dtos, Items = dtos,
TotalRecordCount = count TotalRecordCount = count

@ -23,7 +23,7 @@ namespace MediaBrowser.Api
/// </summary> /// </summary>
[Route("/Plugins", "GET", Summary = "Gets a list of currently installed plugins")] [Route("/Plugins", "GET", Summary = "Gets a list of currently installed plugins")]
[Authenticated] [Authenticated]
public class GetPlugins : IReturn<List<PluginInfo>> public class GetPlugins : IReturn<PluginInfo[]>
{ {
public bool? IsAppStoreEnabled { get; set; } public bool? IsAppStoreEnabled { get; set; }
} }
@ -195,14 +195,13 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns> /// <returns>System.Object.</returns>
public async Task<object> Get(GetPlugins request) public async Task<object> Get(GetPlugins request)
{ {
var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToList(); var result = _appHost.Plugins.OrderBy(p => p.Name).Select(p => p.GetPluginInfo()).ToArray();
var requireAppStoreEnabled = request.IsAppStoreEnabled.HasValue && request.IsAppStoreEnabled.Value; var requireAppStoreEnabled = request.IsAppStoreEnabled.HasValue && request.IsAppStoreEnabled.Value;
// Don't fail just on account of image url's // Don't fail just on account of image url's
try try
{ {
var packages = (await _installationManager.GetAvailablePackagesWithoutRegistrationInfo(CancellationToken.None)) var packages = (await _installationManager.GetAvailablePackagesWithoutRegistrationInfo(CancellationToken.None));
.ToList();
foreach (var plugin in result) foreach (var plugin in result)
{ {
@ -223,7 +222,7 @@ namespace MediaBrowser.Api
return pkg != null && pkg.enableInAppStore; return pkg != null && pkg.enableInAppStore;
}) })
.ToList(); .ToArray();
} }
} }
catch catch
@ -232,7 +231,7 @@ namespace MediaBrowser.Api
// Play it safe here // Play it safe here
if (requireAppStoreEnabled) if (requireAppStoreEnabled)
{ {
result = new List<PluginInfo>(); result = new PluginInfo[] { };
} }
} }

@ -27,7 +27,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// Class GetScheduledTasks /// Class GetScheduledTasks
/// </summary> /// </summary>
[Route("/ScheduledTasks", "GET", Summary = "Gets scheduled tasks")] [Route("/ScheduledTasks", "GET", Summary = "Gets scheduled tasks")]
public class GetScheduledTasks : IReturn<List<TaskInfo>> public class GetScheduledTasks : IReturn<TaskInfo[]>
{ {
[ApiMember(Name = "IsHidden", Description = "Optional filter tasks that are hidden, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "IsHidden", Description = "Optional filter tasks that are hidden, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsHidden { get; set; } public bool? IsHidden { get; set; }
@ -158,7 +158,7 @@ namespace MediaBrowser.Api.ScheduledTasks
var infos = result var infos = result
.Select(ScheduledTaskHelpers.GetTaskInfo) .Select(ScheduledTaskHelpers.GetTaskInfo)
.ToList(); .ToArray();
return ToOptimizedResult(infos); return ToOptimizedResult(infos);
} }

@ -18,7 +18,7 @@ namespace MediaBrowser.Api.Session
/// </summary> /// </summary>
[Route("/Sessions", "GET", Summary = "Gets a list of sessions")] [Route("/Sessions", "GET", Summary = "Gets a list of sessions")]
[Authenticated] [Authenticated]
public class GetSessions : IReturn<List<SessionInfoDto>> public class GetSessions : IReturn<SessionInfoDto[]>
{ {
[ApiMember(Name = "ControllableByUserId", Description = "Optional. Filter by sessions that a given user is allowed to remote control.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "ControllableByUserId", Description = "Optional. Filter by sessions that a given user is allowed to remote control.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ControllableByUserId { get; set; } public string ControllableByUserId { get; set; }
@ -396,7 +396,7 @@ namespace MediaBrowser.Api.Session
}); });
} }
return ToOptimizedResult(result.Select(_sessionManager.GetSessionInfoDto).ToList()); return ToOptimizedResult(result.Select(_sessionManager.GetSessionInfoDto).ToArray());
} }
public void Post(SendPlaystateCommand request) public void Post(SendPlaystateCommand request)
@ -532,9 +532,9 @@ namespace MediaBrowser.Api.Session
} }
_sessionManager.ReportCapabilities(request.Id, new ClientCapabilities _sessionManager.ReportCapabilities(request.Id, new ClientCapabilities
{ {
PlayableMediaTypes = (request.PlayableMediaTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(), PlayableMediaTypes = SplitValue(request.PlayableMediaTypes, ','),
SupportedCommands = (request.SupportedCommands ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(), SupportedCommands = SplitValue(request.SupportedCommands, ','),
SupportsMediaControl = request.SupportsMediaControl, SupportsMediaControl = request.SupportsMediaControl,

@ -30,7 +30,7 @@ namespace MediaBrowser.Api
public string ExcludeArtistIds { get; set; } public string ExcludeArtistIds { get; set; }
} }
public class BaseGetSimilarItems : IReturn<ItemsResult>, IHasDtoOptions public class BaseGetSimilarItems : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
{ {
[ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? EnableImages { get; set; } public bool? EnableImages { get; set; }
@ -97,18 +97,18 @@ namespace MediaBrowser.Api
var items = GetSimilaritems(item, libraryManager, inputItems, getSimilarityScore) var items = GetSimilaritems(item, libraryManager, inputItems, getSimilarityScore)
.ToList(); .ToList();
IEnumerable<BaseItem> returnItems = items; List<BaseItem> returnItems = items;
if (request.Limit.HasValue) if (request.Limit.HasValue)
{ {
returnItems = returnItems.Take(request.Limit.Value); returnItems = returnItems.Take(request.Limit.Value).ToList();
} }
var dtos = await dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ConfigureAwait(false); var dtos = await dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ConfigureAwait(false);
return new QueryResult<BaseItemDto> return new QueryResult<BaseItemDto>
{ {
Items = dtos.ToArray(dtos.Count), Items = dtos,
TotalRecordCount = items.Count TotalRecordCount = items.Count
}; };

@ -14,8 +14,6 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MimeTypes = MediaBrowser.Model.Net.MimeTypes; using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
@ -39,7 +37,7 @@ namespace MediaBrowser.Api.Subtitles
[Route("/Items/{Id}/RemoteSearch/Subtitles/{Language}", "GET")] [Route("/Items/{Id}/RemoteSearch/Subtitles/{Language}", "GET")]
[Authenticated] [Authenticated]
public class SearchRemoteSubtitles : IReturn<List<RemoteSubtitleInfo>> public class SearchRemoteSubtitles : IReturn<RemoteSubtitleInfo[]>
{ {
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; } public string Id { get; set; }
@ -52,7 +50,7 @@ namespace MediaBrowser.Api.Subtitles
[Route("/Items/{Id}/RemoteSearch/Subtitles/Providers", "GET")] [Route("/Items/{Id}/RemoteSearch/Subtitles/Providers", "GET")]
[Authenticated] [Authenticated]
public class GetSubtitleProviders : IReturn<List<SubtitleProviderInfo>> public class GetSubtitleProviders : IReturn<SubtitleProviderInfo[]>
{ {
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; } public string Id { get; set; }

@ -72,7 +72,7 @@ namespace MediaBrowser.Api
return new QueryResult<BaseItemDto> return new QueryResult<BaseItemDto>
{ {
TotalRecordCount = result.TotalRecordCount, TotalRecordCount = result.TotalRecordCount,
Items = dtoList.ToArray(dtoList.Count) Items = dtoList
}; };
} }

@ -60,7 +60,7 @@ namespace MediaBrowser.Api.System
[Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")] [Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")]
[Authenticated(Roles = "Admin")] [Authenticated(Roles = "Admin")]
public class GetServerLogs : IReturn<List<LogFile>> public class GetServerLogs : IReturn<LogFile[]>
{ {
} }
@ -126,7 +126,7 @@ namespace MediaBrowser.Api.System
} }
catch (IOException) catch (IOException)
{ {
files = new List<FileSystemMetadata>(); files = new FileSystemMetadata[]{};
} }
var result = files.Select(i => new LogFile var result = files.Select(i => new LogFile
@ -139,7 +139,7 @@ namespace MediaBrowser.Api.System
}).OrderByDescending(i => i.DateModified) }).OrderByDescending(i => i.DateModified)
.ThenByDescending(i => i.DateCreated) .ThenByDescending(i => i.DateCreated)
.ThenBy(i => i.Name) .ThenBy(i => i.Name)
.ToList(); .ToArray();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }

@ -22,7 +22,7 @@ namespace MediaBrowser.Api
/// Class GetNextUpEpisodes /// Class GetNextUpEpisodes
/// </summary> /// </summary>
[Route("/Shows/NextUp", "GET", Summary = "Gets a list of next up episodes")] [Route("/Shows/NextUp", "GET", Summary = "Gets a list of next up episodes")]
public class GetNextUpEpisodes : IReturn<ItemsResult>, IHasDtoOptions public class GetNextUpEpisodes : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -82,7 +82,7 @@ namespace MediaBrowser.Api
} }
[Route("/Shows/Upcoming", "GET", Summary = "Gets a list of upcoming episodes")] [Route("/Shows/Upcoming", "GET", Summary = "Gets a list of upcoming episodes")]
public class GetUpcomingEpisodes : IReturn<ItemsResult>, IHasDtoOptions public class GetUpcomingEpisodes : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -138,7 +138,7 @@ namespace MediaBrowser.Api
} }
[Route("/Shows/{Id}/Episodes", "GET", Summary = "Gets episodes for a tv season")] [Route("/Shows/{Id}/Episodes", "GET", Summary = "Gets episodes for a tv season")]
public class GetEpisodes : IReturn<ItemsResult>, IHasItemFields, IHasDtoOptions public class GetEpisodes : IReturn<QueryResult<BaseItemDto>>, IHasItemFields, IHasDtoOptions
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -206,7 +206,7 @@ namespace MediaBrowser.Api
} }
[Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")] [Route("/Shows/{Id}/Seasons", "GET", Summary = "Gets seasons for a tv series")]
public class GetSeasons : IReturn<ItemsResult>, IHasItemFields, IHasDtoOptions public class GetSeasons : IReturn<QueryResult<BaseItemDto>>, IHasItemFields, IHasDtoOptions
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -327,7 +327,7 @@ namespace MediaBrowser.Api
var result = new QueryResult<BaseItemDto> var result = new QueryResult<BaseItemDto>
{ {
Items = returnList.ToArray(returnList.Count), Items = returnList,
TotalRecordCount = itemsResult.Count TotalRecordCount = itemsResult.Count
}; };
@ -359,10 +359,9 @@ namespace MediaBrowser.Api
}); });
var returnList = (await _dtoService.GetBaseItemDtos(itemsResult, options, user).ConfigureAwait(false)); var returnItems = (await _dtoService.GetBaseItemDtos(itemsResult, options, user).ConfigureAwait(false));
var returnItems = returnList.ToArray(returnList.Count);
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
TotalRecordCount = itemsResult.Count, TotalRecordCount = itemsResult.Count,
Items = returnItems Items = returnItems
@ -392,10 +391,9 @@ namespace MediaBrowser.Api
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
var returnList = (await _dtoService.GetBaseItemDtos(result.Items, options, user).ConfigureAwait(false)); var returnItems = (await _dtoService.GetBaseItemDtos(result.Items, options, user).ConfigureAwait(false));
var returnItems = returnList.ToArray(returnList.Count);
return ToOptimizedSerializedResultUsingCache(new ItemsResult return ToOptimizedSerializedResultUsingCache(new QueryResult<BaseItemDto>
{ {
TotalRecordCount = result.TotalRecordCount, TotalRecordCount = result.TotalRecordCount,
Items = returnItems Items = returnItems
@ -443,14 +441,13 @@ namespace MediaBrowser.Api
IsSpecialSeason = request.IsSpecialSeason, IsSpecialSeason = request.IsSpecialSeason,
AdjacentTo = request.AdjacentTo AdjacentTo = request.AdjacentTo
})).OfType<Season>(); }));
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
var returnList = (await _dtoService.GetBaseItemDtos(seasons, dtoOptions, user).ConfigureAwait(false)); var returnItems = (await _dtoService.GetBaseItemDtos(seasons, dtoOptions, user).ConfigureAwait(false));
var returnItems = returnList.ToArray(returnList.Count);
return new ItemsResult return new QueryResult<BaseItemDto>
{ {
TotalRecordCount = returnItems.Length, TotalRecordCount = returnItems.Length,
Items = returnItems Items = returnItems
@ -471,7 +468,7 @@ namespace MediaBrowser.Api
{ {
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
IEnumerable<Episode> episodes; List<BaseItem> episodes;
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
@ -499,11 +496,11 @@ namespace MediaBrowser.Api
if (season == null) if (season == null)
{ {
episodes = new List<Episode>(); episodes = new List<BaseItem>();
} }
else else
{ {
episodes = season.GetEpisodes(user, dtoOptions); episodes = ((Season)season).GetEpisodes(user, dtoOptions);
} }
} }
else else
@ -515,44 +512,44 @@ namespace MediaBrowser.Api
throw new ResourceNotFoundException("Series not found"); throw new ResourceNotFoundException("Series not found");
} }
episodes = series.GetEpisodes(user, dtoOptions); episodes = series.GetEpisodes(user, dtoOptions).ToList();
} }
// Filter after the fact in case the ui doesn't want them // Filter after the fact in case the ui doesn't want them
if (request.IsMissing.HasValue) if (request.IsMissing.HasValue)
{ {
var val = request.IsMissing.Value; var val = request.IsMissing.Value;
episodes = episodes.Where(i => i.IsMissingEpisode == val); episodes = episodes.Where(i => ((Episode)i).IsMissingEpisode == val).ToList();
} }
if (!string.IsNullOrWhiteSpace(request.StartItemId)) if (!string.IsNullOrWhiteSpace(request.StartItemId))
{ {
episodes = episodes.SkipWhile(i => !string.Equals(i.Id.ToString("N"), request.StartItemId, StringComparison.OrdinalIgnoreCase)); episodes = episodes.SkipWhile(i => !string.Equals(i.Id.ToString("N"), request.StartItemId, StringComparison.OrdinalIgnoreCase)).ToList();
} }
IEnumerable<BaseItem> returnItems = episodes;
// This must be the last filter // This must be the last filter
if (!string.IsNullOrEmpty(request.AdjacentTo)) if (!string.IsNullOrEmpty(request.AdjacentTo))
{ {
returnItems = UserViewBuilder.FilterForAdjacency(returnItems, request.AdjacentTo); episodes = UserViewBuilder.FilterForAdjacency(episodes, request.AdjacentTo).ToList();
} }
if (string.Equals(request.SortBy, ItemSortBy.Random, StringComparison.OrdinalIgnoreCase)) if (string.Equals(request.SortBy, ItemSortBy.Random, StringComparison.OrdinalIgnoreCase))
{ {
returnItems = returnItems.OrderBy(i => Guid.NewGuid()); episodes = episodes.OrderBy(i => Guid.NewGuid()).ToList();
} }
var returnList = returnItems.ToList(); var returnItems = episodes;
var pagedItems = ApplyPaging(returnList, request.StartIndex, request.Limit); if (request.StartIndex.HasValue || request.Limit.HasValue)
{
returnItems = ApplyPaging(episodes, request.StartIndex, request.Limit).ToList();
}
var returnDtos = (await _dtoService.GetBaseItemDtos(pagedItems, dtoOptions, user).ConfigureAwait(false)); var dtos = (await _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user).ConfigureAwait(false));
var dtos = returnDtos.ToArray(returnDtos.Count);
return new ItemsResult return new QueryResult<BaseItemDto>
{ {
TotalRecordCount = returnList.Count, TotalRecordCount = episodes.Count,
Items = dtos Items = dtos
}; };
} }

@ -88,7 +88,7 @@ namespace MediaBrowser.Api.UserLibrary
return null; return null;
} }
protected ItemsResult GetResultSlim(GetItemsByName request) protected QueryResult<BaseItemDto> GetResultSlim(GetItemsByName request)
{ {
var dtoOptions = GetDtoOptions(AuthorizationContext, request); var dtoOptions = GetDtoOptions(AuthorizationContext, request);
@ -209,7 +209,7 @@ namespace MediaBrowser.Api.UserLibrary
return dto; return dto;
}); });
return new ItemsResult return new QueryResult<BaseItemDto>
{ {
Items = dtos.ToArray(result.Items.Length), Items = dtos.ToArray(result.Items.Length),
TotalRecordCount = result.TotalRecordCount TotalRecordCount = result.TotalRecordCount
@ -240,7 +240,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary> /// </summary>
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
/// <returns>Task{ItemsResult}.</returns> /// <returns>Task{ItemsResult}.</returns>
protected ItemsResult GetResult(GetItemsByName request) protected QueryResult<BaseItemDto> GetResult(GetItemsByName request)
{ {
var dtoOptions = GetDtoOptions(AuthorizationContext, request); var dtoOptions = GetDtoOptions(AuthorizationContext, request);
@ -305,7 +305,7 @@ namespace MediaBrowser.Api.UserLibrary
IEnumerable<BaseItem> ibnItems = ibnItemsArray; IEnumerable<BaseItem> ibnItems = ibnItemsArray;
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
TotalRecordCount = ibnItemsArray.Count TotalRecordCount = ibnItemsArray.Count
}; };
@ -357,13 +357,13 @@ namespace MediaBrowser.Api.UserLibrary
items = items.Where(i => string.Compare(request.NameLessThan, i.SortName, StringComparison.CurrentCultureIgnoreCase) == 1); items = items.Where(i => string.Compare(request.NameLessThan, i.SortName, StringComparison.CurrentCultureIgnoreCase) == 1);
} }
var imageTypes = request.GetImageTypes().ToList(); var imageTypes = request.GetImageTypes();
if (imageTypes.Count > 0) if (imageTypes.Length > 0)
{ {
items = items.Where(item => imageTypes.Any(item.HasImage)); items = items.Where(item => imageTypes.Any(item.HasImage));
} }
var filters = request.GetFilters().ToList(); var filters = request.GetFilters();
if (filters.Contains(ItemFilter.Dislikes)) if (filters.Contains(ItemFilter.Dislikes))
{ {
@ -506,7 +506,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <summary> /// <summary>
/// Class GetItemsByName /// Class GetItemsByName
/// </summary> /// </summary>
public class GetItemsByName : BaseItemsRequest, IReturn<ItemsResult> public class GetItemsByName : BaseItemsRequest, IReturn<QueryResult<BaseItemDto>>
{ {
public GetItemsByName() public GetItemsByName()
{ {

@ -435,7 +435,7 @@ namespace MediaBrowser.Api.UserLibrary
/// Gets the filters. /// Gets the filters.
/// </summary> /// </summary>
/// <returns>IEnumerable{ItemFilter}.</returns> /// <returns>IEnumerable{ItemFilter}.</returns>
public IEnumerable<ItemFilter> GetFilters() public ItemFilter[] GetFilters()
{ {
var val = Filters; var val = Filters;
@ -444,7 +444,7 @@ namespace MediaBrowser.Api.UserLibrary
return new ItemFilter[] { }; return new ItemFilter[] { };
} }
return val.Split(',').Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true)); return val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true)).ToArray();
} }
/// <summary> /// <summary>

@ -10,6 +10,7 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Extensions;
@ -21,7 +22,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary> /// </summary>
[Route("/Items", "GET", Summary = "Gets items based on a query.")] [Route("/Items", "GET", Summary = "Gets items based on a query.")]
[Route("/Users/{UserId}/Items", "GET", Summary = "Gets items based on a query.")] [Route("/Users/{UserId}/Items", "GET", Summary = "Gets items based on a query.")]
public class GetItems : BaseItemsRequest, IReturn<ItemsResult> public class GetItems : BaseItemsRequest, IReturn<QueryResult<BaseItemDto>>
{ {
} }
@ -100,7 +101,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary> /// </summary>
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
/// <returns>Task{ItemsResult}.</returns> /// <returns>Task{ItemsResult}.</returns>
private async Task<ItemsResult> GetItems(GetItems request) private async Task<QueryResult<BaseItemDto>> GetItems(GetItems request)
{ {
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null; var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
@ -125,10 +126,10 @@ namespace MediaBrowser.Api.UserLibrary
throw new InvalidOperationException("GetBaseItemDtos returned null"); throw new InvalidOperationException("GetBaseItemDtos returned null");
} }
return new ItemsResult return new QueryResult<BaseItemDto>
{ {
TotalRecordCount = result.TotalRecordCount, TotalRecordCount = result.TotalRecordCount,
Items = dtoList.ToArray(dtoList.Count) Items = dtoList
}; };
} }
@ -180,9 +181,7 @@ namespace MediaBrowser.Api.UserLibrary
return folder.GetItems(GetItemsQuery(request, dtoOptions, user)); return folder.GetItems(GetItemsQuery(request, dtoOptions, user));
} }
IEnumerable<BaseItem> items = folder.GetChildren(user, true); var itemsArray = folder.GetChildren(user, true).ToArray();
var itemsArray = items.ToArray();
return new QueryResult<BaseItem> return new QueryResult<BaseItem>
{ {
@ -332,13 +331,11 @@ namespace MediaBrowser.Api.UserLibrary
if (!string.IsNullOrEmpty(request.LocationTypes)) if (!string.IsNullOrEmpty(request.LocationTypes))
{ {
var requestedLocationTypes = var requestedLocationTypes =
request.LocationTypes.Split(',') request.LocationTypes.Split(',');
.Select(d => (LocationType)Enum.Parse(typeof(LocationType), d, true))
.ToList();
if (requestedLocationTypes.Count > 0 && requestedLocationTypes.Count < 4) if (requestedLocationTypes.Length > 0 && requestedLocationTypes.Length < 4)
{ {
query.IsVirtualItem = requestedLocationTypes.Contains(LocationType.Virtual); query.IsVirtualItem = requestedLocationTypes.Contains(LocationType.Virtual.ToString());
} }
} }

@ -59,7 +59,7 @@ namespace MediaBrowser.Api.UserLibrary
/// Class GetIntros /// Class GetIntros
/// </summary> /// </summary>
[Route("/Users/{UserId}/Items/{Id}/Intros", "GET", Summary = "Gets intros to play before the main media item plays")] [Route("/Users/{UserId}/Items/{Id}/Intros", "GET", Summary = "Gets intros to play before the main media item plays")]
public class GetIntros : IReturn<ItemsResult> public class GetIntros : IReturn<QueryResult<BaseItemDto>>
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -171,7 +171,7 @@ namespace MediaBrowser.Api.UserLibrary
/// Class GetLocalTrailers /// Class GetLocalTrailers
/// </summary> /// </summary>
[Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET", Summary = "Gets local trailers for an item")] [Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET", Summary = "Gets local trailers for an item")]
public class GetLocalTrailers : IReturn<List<BaseItemDto>> public class GetLocalTrailers : IReturn<BaseItemDto[]>
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -192,7 +192,7 @@ namespace MediaBrowser.Api.UserLibrary
/// Class GetSpecialFeatures /// Class GetSpecialFeatures
/// </summary> /// </summary>
[Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET", Summary = "Gets special features for an item")] [Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET", Summary = "Gets special features for an item")]
public class GetSpecialFeatures : IReturn<List<BaseItemDto>> public class GetSpecialFeatures : IReturn<BaseItemDto[]>
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -210,7 +210,7 @@ namespace MediaBrowser.Api.UserLibrary
} }
[Route("/Users/{UserId}/Items/Latest", "GET", Summary = "Gets latest media")] [Route("/Users/{UserId}/Items/Latest", "GET", Summary = "Gets latest media")]
public class GetLatestMedia : IReturn<List<BaseItemDto>>, IHasDtoOptions public class GetLatestMedia : IReturn<BaseItemDto[]>, IHasDtoOptions
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -338,10 +338,10 @@ namespace MediaBrowser.Api.UserLibrary
return dto; return dto;
}); });
return ToOptimizedResult(dtos.ToList()); return ToOptimizedResult(dtos.ToArray());
} }
private List<BaseItemDto> GetAsync(GetSpecialFeatures request) private BaseItemDto[] GetAsync(GetSpecialFeatures request)
{ {
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
@ -364,7 +364,7 @@ namespace MediaBrowser.Api.UserLibrary
.Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0) .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, currentUser)); .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, currentUser));
return dtos.ToList(); return dtos.ToArray();
} }
var movie = item as IHasSpecialFeatures; var movie = item as IHasSpecialFeatures;
@ -379,10 +379,10 @@ namespace MediaBrowser.Api.UserLibrary
.OrderBy(i => i.SortName) .OrderBy(i => i.SortName)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
return dtos.ToList(); return dtos.ToArray();
} }
return new List<BaseItemDto>(); return new BaseItemDto[] { };
} }
/// <summary> /// <summary>
@ -396,19 +396,24 @@ namespace MediaBrowser.Api.UserLibrary
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id); var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
var trailerIds = new List<Guid>(); List<Guid> trailerIds = null;
var hasTrailers = item as IHasTrailers; var hasTrailers = item as IHasTrailers;
if (hasTrailers != null) if (hasTrailers != null)
{ {
trailerIds = hasTrailers.GetTrailerIds(); trailerIds = hasTrailers.GetTrailerIds();
} }
else
{
trailerIds = new List<Guid>();
}
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
var dtos = trailerIds var dtos = trailerIds
.Select(_libraryManager.GetItemById) .Select(_libraryManager.GetItemById)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
.ToArray();
return ToOptimizedSerializedResultUsingCache(dtos); return ToOptimizedSerializedResultUsingCache(dtos);
} }
@ -489,7 +494,7 @@ namespace MediaBrowser.Api.UserLibrary
var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray(); var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray();
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
Items = dtos, Items = dtos,
TotalRecordCount = dtos.Length TotalRecordCount = dtos.Length

@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api.UserLibrary namespace MediaBrowser.Api.UserLibrary
{ {
@ -32,7 +33,7 @@ namespace MediaBrowser.Api.UserLibrary
} }
[Route("/Users/{UserId}/GroupingOptions", "GET")] [Route("/Users/{UserId}/GroupingOptions", "GET")]
public class GetGroupingOptions : IReturn<List<SpecialViewOption>> public class GetGroupingOptions : IReturn<SpecialViewOption[]>
{ {
/// <summary> /// <summary>
/// Gets or sets the user id. /// Gets or sets the user id.
@ -84,10 +85,13 @@ namespace MediaBrowser.Api.UserLibrary
var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false); var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false);
var dtoOptions = GetDtoOptions(_authContext, request); var dtoOptions = GetDtoOptions(_authContext, request);
dtoOptions.Fields.Add(ItemFields.PrimaryImageAspectRatio); var fields = dtoOptions.Fields.ToList();
dtoOptions.Fields.Add(ItemFields.DisplayPreferencesId);
dtoOptions.Fields.Remove(ItemFields.SyncInfo); fields.Add(ItemFields.PrimaryImageAspectRatio);
dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo); fields.Add(ItemFields.DisplayPreferencesId);
fields.Remove(ItemFields.SyncInfo);
fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields = fields.ToArray(fields.Count);
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
@ -107,13 +111,10 @@ namespace MediaBrowser.Api.UserLibrary
{ {
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
var views = user.RootFolder var list = user.RootFolder
.GetChildren(user, true) .GetChildren(user, true)
.OfType<Folder>() .OfType<Folder>()
.Where(UserView.IsEligibleForGrouping) .Where(UserView.IsEligibleForGrouping)
.ToList();
var list = views
.Select(i => new SpecialViewOption .Select(i => new SpecialViewOption
{ {
Name = i.Name, Name = i.Name,
@ -121,7 +122,7 @@ namespace MediaBrowser.Api.UserLibrary
}) })
.OrderBy(i => i.Name) .OrderBy(i => i.Name)
.ToList(); .ToArray();
return ToOptimizedResult(list); return ToOptimizedResult(list);
} }

@ -22,7 +22,7 @@ namespace MediaBrowser.Api
/// </summary> /// </summary>
[Route("/Users", "GET", Summary = "Gets a list of users")] [Route("/Users", "GET", Summary = "Gets a list of users")]
[Authenticated] [Authenticated]
public class GetUsers : IReturn<List<UserDto>> public class GetUsers : IReturn<UserDto[]>
{ {
[ApiMember(Name = "IsHidden", Description = "Optional filter by IsHidden=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "IsHidden", Description = "Optional filter by IsHidden=true or false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsHidden { get; set; } public bool? IsHidden { get; set; }
@ -35,7 +35,7 @@ namespace MediaBrowser.Api
} }
[Route("/Users/Public", "GET", Summary = "Gets a list of publicly visible users for display on a login screen.")] [Route("/Users/Public", "GET", Summary = "Gets a list of publicly visible users for display on a login screen.")]
public class GetPublicUsers : IReturn<List<UserDto>> public class GetPublicUsers : IReturn<UserDto[]>
{ {
} }
@ -329,7 +329,7 @@ namespace MediaBrowser.Api
var result = users var result = users
.OrderBy(u => u.Name) .OrderBy(u => u.Name)
.Select(i => _userManager.GetUserDto(i, Request.RemoteIp)) .Select(i => _userManager.GetUserDto(i, Request.RemoteIp))
.ToList(); .ToArray();
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }

@ -19,7 +19,7 @@ namespace MediaBrowser.Api
{ {
[Route("/Videos/{Id}/AdditionalParts", "GET", Summary = "Gets additional parts for a video.")] [Route("/Videos/{Id}/AdditionalParts", "GET", Summary = "Gets additional parts for a video.")]
[Authenticated] [Authenticated]
public class GetAdditionalParts : IReturn<ItemsResult> public class GetAdditionalParts : IReturn<QueryResult<BaseItemDto>>
{ {
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string UserId { get; set; } public string UserId { get; set; }
@ -99,7 +99,7 @@ namespace MediaBrowser.Api
items = new BaseItemDto[] { }; items = new BaseItemDto[] { };
} }
var result = new ItemsResult var result = new QueryResult<BaseItemDto>
{ {
Items = items, Items = items,
TotalRecordCount = items.Length TotalRecordCount = items.Length

@ -48,7 +48,7 @@ namespace MediaBrowser.Common.Updates
/// <param name="packageType">Type of the package.</param> /// <param name="packageType">Type of the package.</param>
/// <param name="applicationVersion">The application version.</param> /// <param name="applicationVersion">The application version.</param>
/// <returns>Task{List{PackageInfo}}.</returns> /// <returns>Task{List{PackageInfo}}.</returns>
Task<IEnumerable<PackageInfo>> GetAvailablePackages(CancellationToken cancellationToken, Task<PackageInfo[]> GetAvailablePackages(CancellationToken cancellationToken,
bool withRegistration = true, bool withRegistration = true,
string packageType = null, string packageType = null,
Version applicationVersion = null); Version applicationVersion = null);
@ -58,7 +58,7 @@ namespace MediaBrowser.Common.Updates
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{List{PackageInfo}}.</returns> /// <returns>Task{List{PackageInfo}}.</returns>
Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken); Task<PackageInfo[]> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Gets the package. /// Gets the package.

@ -30,7 +30,7 @@ namespace MediaBrowser.Controller.Channels
/// Gets all channel features. /// Gets all channel features.
/// </summary> /// </summary>
/// <returns>IEnumerable{ChannelFeatures}.</returns> /// <returns>IEnumerable{ChannelFeatures}.</returns>
IEnumerable<ChannelFeatures> GetAllChannelFeatures(); ChannelFeatures[] GetAllChannelFeatures();
/// <summary> /// <summary>
/// Gets the channel. /// Gets the channel.

@ -58,13 +58,4 @@ namespace MediaBrowser.Controller.Channels
DefaultSortFields = new List<ChannelItemSortField>(); DefaultSortFields = new List<ChannelItemSortField>();
} }
} }
public class ChannelDownloadException : Exception
{
public ChannelDownloadException(string message)
: base(message)
{
}
}
} }

@ -14,14 +14,14 @@ namespace MediaBrowser.Controller.Collections
public Dictionary<string, string> ProviderIds { get; set; } public Dictionary<string, string> ProviderIds { get; set; }
public List<Guid> ItemIdList { get; set; } public string[] ItemIdList { get; set; }
public List<Guid> UserIds { get; set; } public string[] UserIds { get; set; }
public CollectionCreationOptions() public CollectionCreationOptions()
{ {
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
ItemIdList = new List<Guid>(); ItemIdList = new string[] { };
UserIds = new List<Guid>(); UserIds = new string[] { };
} }
} }
} }

@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Collections
/// <param name="collectionId">The collection identifier.</param> /// <param name="collectionId">The collection identifier.</param>
/// <param name="itemIds">The item ids.</param> /// <param name="itemIds">The item ids.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task AddToCollection(Guid collectionId, IEnumerable<Guid> itemIds); Task AddToCollection(Guid collectionId, string[] itemIds);
/// <summary> /// <summary>
/// Removes from collection. /// Removes from collection.
@ -44,7 +44,7 @@ namespace MediaBrowser.Controller.Collections
/// <param name="collectionId">The collection identifier.</param> /// <param name="collectionId">The collection identifier.</param>
/// <param name="itemIds">The item ids.</param> /// <param name="itemIds">The item ids.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task RemoveFromCollection(Guid collectionId, IEnumerable<Guid> itemIds); Task RemoveFromCollection(Guid collectionId, string[] itemIds);
/// <summary> /// <summary>
/// Collapses the items within box sets. /// Collapses the items within box sets.

@ -14,8 +14,8 @@ namespace MediaBrowser.Controller.Dto
ItemFields.RefreshState ItemFields.RefreshState
}; };
public List<ItemFields> Fields { get; set; } public ItemFields[] Fields { get; set; }
public List<ImageType> ImageTypes { get; set; } public ImageType[] ImageTypes { get; set; }
public int ImageTypeLimit { get; set; } public int ImageTypeLimit { get; set; }
public bool EnableImages { get; set; } public bool EnableImages { get; set; }
public bool AddProgramRecordingInfo { get; set; } public bool AddProgramRecordingInfo { get; set; }
@ -28,6 +28,15 @@ namespace MediaBrowser.Controller.Dto
{ {
} }
private static readonly ImageType[] AllImageTypes = Enum.GetNames(typeof(ImageType))
.Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
.ToArray();
private static readonly ItemFields[] AllItemFields = Enum.GetNames(typeof(ItemFields))
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.Except(DefaultExcludedFields)
.ToArray();
public DtoOptions(bool allFields) public DtoOptions(bool allFields)
{ {
ImageTypeLimit = int.MaxValue; ImageTypeLimit = int.MaxValue;
@ -37,19 +46,14 @@ namespace MediaBrowser.Controller.Dto
if (allFields) if (allFields)
{ {
Fields = Enum.GetNames(typeof(ItemFields)) Fields = AllItemFields;
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.Except(DefaultExcludedFields)
.ToList();
} }
else else
{ {
Fields = new List<ItemFields>(); Fields = new ItemFields[] { };
} }
ImageTypes = Enum.GetNames(typeof(ImageType)) ImageTypes = AllImageTypes;
.Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
.ToList();
} }
public int GetImageLimit(ImageType type) public int GetImageLimit(ImageType type)

@ -41,7 +41,7 @@ namespace MediaBrowser.Controller.Dto
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
/// <param name="owner">The owner.</param> /// <param name="owner">The owner.</param>
/// <returns>Task{BaseItemDto}.</returns> /// <returns>Task{BaseItemDto}.</returns>
BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null); BaseItemDto GetBaseItemDto(BaseItem item, ItemFields[] fields, User user = null, BaseItem owner = null);
/// <summary> /// <summary>
/// Gets the base item dto. /// Gets the base item dto.
@ -61,9 +61,10 @@ namespace MediaBrowser.Controller.Dto
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
/// <param name="owner">The owner.</param> /// <param name="owner">The owner.</param>
/// <returns>IEnumerable&lt;BaseItemDto&gt;.</returns> /// <returns>IEnumerable&lt;BaseItemDto&gt;.</returns>
Task<List<BaseItemDto>> GetBaseItemDtos(IEnumerable<BaseItem> items, DtoOptions options, User user = null, Task<BaseItemDto[]> GetBaseItemDtos(BaseItem[] items, DtoOptions options, User user = null, BaseItem owner = null);
BaseItem owner = null);
Task<BaseItemDto[]> GetBaseItemDtos(List<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null);
/// <summary> /// <summary>
/// Gets the chapter information dto. /// Gets the chapter information dto.
/// </summary> /// </summary>

@ -2265,7 +2265,7 @@ namespace MediaBrowser.Controller.Entities
return path; return path;
} }
public virtual void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> fields) public virtual void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields)
{ {
if (RunTimeTicks.HasValue) if (RunTimeTicks.HasValue)
{ {

@ -711,7 +711,7 @@ namespace MediaBrowser.Controller.Entities
{ {
if (!(this is ICollectionFolder)) if (!(this is ICollectionFolder))
{ {
return GetChildren(user, true).Count(); return GetChildren(user, true).Count;
} }
} }
@ -792,16 +792,16 @@ namespace MediaBrowser.Controller.Entities
query.StartIndex = null; query.StartIndex = null;
query.Limit = null; query.Limit = null;
IEnumerable<BaseItem> itemsList = LibraryManager.GetItemList(query); var itemsList = LibraryManager.GetItemList(query);
var user = query.User; var user = query.User;
if (user != null) if (user != null)
{ {
// needed for boxsets // needed for boxsets
itemsList = itemsList.Where(i => i.IsVisibleStandalone(query.User)); itemsList = itemsList.Where(i => i.IsVisibleStandalone(query.User)).ToList();
} }
IEnumerable<BaseItem> returnItems; BaseItem[] returnItems;
int totalCount = 0; int totalCount = 0;
if (query.EnableTotalRecordCount) if (query.EnableTotalRecordCount)
@ -812,16 +812,16 @@ namespace MediaBrowser.Controller.Entities
} }
else else
{ {
returnItems = itemsList; returnItems = itemsList.ToArray();
} }
if (limit.HasValue) if (limit.HasValue)
{ {
returnItems = returnItems.Skip(startIndex ?? 0).Take(limit.Value); returnItems = returnItems.Skip(startIndex ?? 0).Take(limit.Value).ToArray();
} }
else if (startIndex.HasValue) else if (startIndex.HasValue)
{ {
returnItems = returnItems.Skip(startIndex.Value); returnItems = returnItems.Skip(startIndex.Value).ToArray();
} }
return new QueryResult<BaseItem> return new QueryResult<BaseItem>
@ -1044,7 +1044,7 @@ namespace MediaBrowser.Controller.Entities
return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager, collapseBoxSetItems, enableSorting); return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager, ConfigurationManager, collapseBoxSetItems, enableSorting);
} }
public virtual IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) public virtual List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{ {
if (user == null) if (user == null)
{ {
@ -1058,7 +1058,7 @@ namespace MediaBrowser.Controller.Entities
AddChildren(user, includeLinkedChildren, result, false, null); AddChildren(user, includeLinkedChildren, result, false, null);
return result.Values; return result.Values.ToList();
} }
protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
@ -1477,7 +1477,7 @@ namespace MediaBrowser.Controller.Entities
} }
} }
public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> fields) public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields)
{ {
if (!SupportsUserDataFromChildren) if (!SupportsUserDataFromChildren)
{ {

@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary> /// <summary>
/// Fills the user data dto values. /// Fills the user data dto values.
/// </summary> /// </summary>
void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List<ItemFields> fields); void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, ItemFields[] fields);
bool EnableRememberingTrackSelections { get; } bool EnableRememberingTrackSelections { get; }

@ -170,24 +170,24 @@ namespace MediaBrowser.Controller.Entities.Movies
StringComparison.OrdinalIgnoreCase); StringComparison.OrdinalIgnoreCase);
} }
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{ {
var children = base.GetChildren(user, includeLinkedChildren); var children = base.GetChildren(user, includeLinkedChildren);
if (string.Equals(DisplayOrder, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase)) if (string.Equals(DisplayOrder, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase))
{ {
// Sort by name // Sort by name
return LibraryManager.Sort(children, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending); return LibraryManager.Sort(children, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList();
} }
if (string.Equals(DisplayOrder, ItemSortBy.PremiereDate, StringComparison.OrdinalIgnoreCase)) if (string.Equals(DisplayOrder, ItemSortBy.PremiereDate, StringComparison.OrdinalIgnoreCase))
{ {
// Sort by release date // Sort by release date
return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending); return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending).ToList();
} }
// Default sorting // Default sorting
return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending); return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending).ToList();
} }
public BoxSetInfo GetLookupInfo() public BoxSetInfo GetLookupInfo()

@ -160,27 +160,27 @@ namespace MediaBrowser.Controller.Entities.TV
/// <summary> /// <summary>
/// Gets the episodes. /// Gets the episodes.
/// </summary> /// </summary>
public IEnumerable<Episode> GetEpisodes(User user, DtoOptions options) public List<BaseItem> GetEpisodes(User user, DtoOptions options)
{ {
return GetEpisodes(Series, user, options); return GetEpisodes(Series, user, options);
} }
public IEnumerable<Episode> GetEpisodes(Series series, User user, DtoOptions options) public List<BaseItem> GetEpisodes(Series series, User user, DtoOptions options)
{ {
return GetEpisodes(series, user, null, options); return GetEpisodes(series, user, null, options);
} }
public IEnumerable<Episode> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options) public List<BaseItem> GetEpisodes(Series series, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options)
{ {
return series.GetSeasonEpisodes(this, user, allSeriesEpisodes, options); return series.GetSeasonEpisodes(this, user, allSeriesEpisodes, options);
} }
public IEnumerable<Episode> GetEpisodes() public List<BaseItem> GetEpisodes()
{ {
return Series.GetSeasonEpisodes(this, null, null, new DtoOptions(true)); return Series.GetSeasonEpisodes(this, null, null, new DtoOptions(true));
} }
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{ {
return GetEpisodes(user, new DtoOptions(true)); return GetEpisodes(user, new DtoOptions(true));
} }

@ -152,12 +152,8 @@ namespace MediaBrowser.Controller.Entities.TV
IncludeItemTypes = new[] { typeof(Season).Name }, IncludeItemTypes = new[] { typeof(Season).Name },
IsVirtualItem = false, IsVirtualItem = false,
Limit = 0, Limit = 0,
DtoOptions = new Dto.DtoOptions DtoOptions = new Dto.DtoOptions(false)
{ {
Fields = new List<ItemFields>
{
},
EnableImages = false EnableImages = false
} }
}); });
@ -173,12 +169,8 @@ namespace MediaBrowser.Controller.Entities.TV
{ {
AncestorWithPresentationUniqueKey = null, AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey, SeriesPresentationUniqueKey = seriesKey,
DtoOptions = new Dto.DtoOptions DtoOptions = new Dto.DtoOptions(false)
{ {
Fields = new List<ItemFields>
{
},
EnableImages = false EnableImages = false
} }
}; };
@ -226,12 +218,12 @@ namespace MediaBrowser.Controller.Entities.TV
} }
} }
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{ {
return GetSeasons(user, new DtoOptions(true)); return GetSeasons(user, new DtoOptions(true));
} }
public IEnumerable<Season> GetSeasons(User user, DtoOptions options) public List<BaseItem> GetSeasons(User user, DtoOptions options)
{ {
var query = new InternalItemsQuery(user) var query = new InternalItemsQuery(user)
{ {
@ -240,7 +232,7 @@ namespace MediaBrowser.Controller.Entities.TV
SetSeasonQueryOptions(query, user); SetSeasonQueryOptions(query, user);
return LibraryManager.GetItemList(query).Cast<Season>(); return LibraryManager.GetItemList(query);
} }
private void SetSeasonQueryOptions(InternalItemsQuery query, User user) private void SetSeasonQueryOptions(InternalItemsQuery query, User user)
@ -292,7 +284,7 @@ namespace MediaBrowser.Controller.Entities.TV
return LibraryManager.GetItemsResult(query); return LibraryManager.GetItemsResult(query);
} }
public IEnumerable<Episode> GetEpisodes(User user, DtoOptions options) public IEnumerable<BaseItem> GetEpisodes(User user, DtoOptions options)
{ {
var seriesKey = GetUniqueSeriesKey(this); var seriesKey = GetUniqueSeriesKey(this);
@ -312,7 +304,7 @@ namespace MediaBrowser.Controller.Entities.TV
var allItems = LibraryManager.GetItemList(query); var allItems = LibraryManager.GetItemList(query);
var allSeriesEpisodes = allItems.OfType<Episode>(); var allSeriesEpisodes = allItems.OfType<Episode>().ToList();
var allEpisodes = allItems.OfType<Season>() var allEpisodes = allItems.OfType<Season>()
.SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes, options)) .SelectMany(i => i.GetEpisodes(this, user, allSeriesEpisodes, options))
@ -396,7 +388,7 @@ namespace MediaBrowser.Controller.Entities.TV
await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false);
} }
public IEnumerable<Episode> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options) public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, DtoOptions options)
{ {
var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons; var queryFromSeries = ConfigurationManager.Configuration.DisplaySpecialsWithinSeasons;
@ -422,12 +414,12 @@ namespace MediaBrowser.Controller.Entities.TV
} }
} }
var allItems = LibraryManager.GetItemList(query).OfType<Episode>(); var allItems = LibraryManager.GetItemList(query);
return GetSeasonEpisodes(parentSeason, user, allItems, options); return GetSeasonEpisodes(parentSeason, user, allItems, options);
} }
public IEnumerable<Episode> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<Episode> allSeriesEpisodes, DtoOptions options) public List<BaseItem> GetSeasonEpisodes(Season parentSeason, User user, IEnumerable<BaseItem> allSeriesEpisodes, DtoOptions options)
{ {
if (allSeriesEpisodes == null) if (allSeriesEpisodes == null)
{ {
@ -438,14 +430,13 @@ namespace MediaBrowser.Controller.Entities.TV
var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder; var sortBy = (parentSeason.IndexNumber ?? -1) == 0 ? ItemSortBy.SortName : ItemSortBy.AiredEpisodeOrder;
return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending) return LibraryManager.Sort(episodes, user, new[] { sortBy }, SortOrder.Ascending).ToList();
.Cast<Episode>();
} }
/// <summary> /// <summary>
/// Filters the episodes by season. /// Filters the episodes by season.
/// </summary> /// </summary>
public static IEnumerable<Episode> FilterEpisodesBySeason(IEnumerable<Episode> episodes, Season parentSeason, bool includeSpecials) public static IEnumerable<BaseItem> FilterEpisodesBySeason(IEnumerable<BaseItem> episodes, Season parentSeason, bool includeSpecials)
{ {
var seasonNumber = parentSeason.IndexNumber; var seasonNumber = parentSeason.IndexNumber;
var seasonPresentationKey = GetUniqueSeriesKey(parentSeason); var seasonPresentationKey = GetUniqueSeriesKey(parentSeason);
@ -454,7 +445,9 @@ namespace MediaBrowser.Controller.Entities.TV
return episodes.Where(episode => return episodes.Where(episode =>
{ {
var currentSeasonNumber = supportSpecialsInSeason ? episode.AiredSeasonNumber : episode.ParentIndexNumber; var episodeItem = (Episode) episode;
var currentSeasonNumber = supportSpecialsInSeason ? episodeItem.AiredSeasonNumber : episode.ParentIndexNumber;
if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value) if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
{ {
return true; return true;
@ -465,7 +458,7 @@ namespace MediaBrowser.Controller.Entities.TV
return true; return true;
} }
var season = episode.Season; var season = episodeItem.Season;
return season != null && string.Equals(GetUniqueSeriesKey(season), seasonPresentationKey, StringComparison.OrdinalIgnoreCase); return season != null && string.Equals(GetUniqueSeriesKey(season), seasonPresentationKey, StringComparison.OrdinalIgnoreCase);
}); });
} }

@ -81,7 +81,7 @@ namespace MediaBrowser.Controller.Entities
public override int GetChildCount(User user) public override int GetChildCount(User user)
{ {
return GetChildren(user, true).Count(); return GetChildren(user, true).Count;
} }
[IgnoreDataMember] [IgnoreDataMember]

@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.Entities
.GetUserItems(parent, this, ViewType, query).Result; .GetUserItems(parent, this, ViewType, query).Result;
} }
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{ {
var result = GetItemList(new InternalItemsQuery var result = GetItemList(new InternalItemsQuery
{ {
@ -90,7 +90,7 @@ namespace MediaBrowser.Controller.Entities
}); });
return result; return result.ToList();
} }
public override bool CanDelete() public override bool CanDelete()

@ -533,7 +533,7 @@ namespace MediaBrowser.Controller.Entities
return ConvertToResult(_libraryManager.GetItemList(query)); return ConvertToResult(_libraryManager.GetItemList(query));
} }
private QueryResult<BaseItem> ConvertToResult(IEnumerable<BaseItem> items) private QueryResult<BaseItem> ConvertToResult(List<BaseItem> items)
{ {
var arr = items.ToArray(); var arr = items.ToArray();
return new QueryResult<BaseItem> return new QueryResult<BaseItem>
@ -789,7 +789,7 @@ namespace MediaBrowser.Controller.Entities
// This must be the last filter // This must be the last filter
if (!string.IsNullOrEmpty(query.AdjacentTo)) if (!string.IsNullOrEmpty(query.AdjacentTo))
{ {
items = FilterForAdjacency(items, query.AdjacentTo); items = FilterForAdjacency(items.ToList(), query.AdjacentTo);
} }
return SortAndPage(items, totalRecordLimit, query, libraryManager, enableSorting); return SortAndPage(items, totalRecordLimit, query, libraryManager, enableSorting);
@ -1763,10 +1763,8 @@ namespace MediaBrowser.Controller.Entities
return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None); return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None);
} }
public static IEnumerable<BaseItem> FilterForAdjacency(IEnumerable<BaseItem> items, string adjacentToId) public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, string adjacentToId)
{ {
var list = items.ToList();
var adjacentToIdGuid = new Guid(adjacentToId); var adjacentToIdGuid = new Guid(adjacentToId);
var adjacentToItem = list.FirstOrDefault(i => i.Id == adjacentToIdGuid); var adjacentToItem = list.FirstOrDefault(i => i.Id == adjacentToIdGuid);

@ -153,14 +153,14 @@ namespace MediaBrowser.Controller.Entities
/// Gets the playable stream files. /// Gets the playable stream files.
/// </summary> /// </summary>
/// <returns>List{System.String}.</returns> /// <returns>List{System.String}.</returns>
public List<string> GetPlayableStreamFiles() public string[] GetPlayableStreamFiles()
{ {
return GetPlayableStreamFiles(Path); return GetPlayableStreamFiles(Path);
} }
public List<string> GetPlayableStreamFileNames() public string[] GetPlayableStreamFileNames()
{ {
return GetPlayableStreamFiles().Select(System.IO.Path.GetFileName).ToList(); ; return GetPlayableStreamFiles().Select(System.IO.Path.GetFileName).ToArray();
} }
/// <summary> /// <summary>
@ -389,11 +389,11 @@ namespace MediaBrowser.Controller.Entities
/// </summary> /// </summary>
/// <param name="rootPath">The root path.</param> /// <param name="rootPath">The root path.</param>
/// <returns>List{System.String}.</returns> /// <returns>List{System.String}.</returns>
public List<string> GetPlayableStreamFiles(string rootPath) public string[] GetPlayableStreamFiles(string rootPath)
{ {
if (VideoType == VideoType.VideoFile) if (VideoType == VideoType.VideoFile)
{ {
return new List<string>(); return new string[] { };
} }
var allFiles = FileSystem.GetFilePaths(rootPath, true).ToList(); var allFiles = FileSystem.GetFilePaths(rootPath, true).ToList();
@ -411,10 +411,10 @@ namespace MediaBrowser.Controller.Entities
return QueryPlayableStreamFiles(rootPath, videoType).Select(name => allFiles.FirstOrDefault(f => string.Equals(System.IO.Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase))) return QueryPlayableStreamFiles(rootPath, videoType).Select(name => allFiles.FirstOrDefault(f => string.Equals(System.IO.Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase)))
.Where(f => !string.IsNullOrEmpty(f)) .Where(f => !string.IsNullOrEmpty(f))
.ToList(); .ToArray();
} }
public static List<string> QueryPlayableStreamFiles(string rootPath, VideoType videoType) public static string[] QueryPlayableStreamFiles(string rootPath, VideoType videoType)
{ {
if (videoType == VideoType.Dvd) if (videoType == VideoType.Dvd)
{ {
@ -423,7 +423,7 @@ namespace MediaBrowser.Controller.Entities
.ThenBy(i => i.FullName) .ThenBy(i => i.FullName)
.Take(1) .Take(1)
.Select(i => i.FullName) .Select(i => i.FullName)
.ToList(); .ToArray();
} }
if (videoType == VideoType.BluRay) if (videoType == VideoType.BluRay)
{ {
@ -432,9 +432,9 @@ namespace MediaBrowser.Controller.Entities
.ThenBy(i => i.FullName) .ThenBy(i => i.FullName)
.Take(1) .Take(1)
.Select(i => i.FullName) .Select(i => i.FullName)
.ToList(); .ToArray();
} }
return new List<string>(); return new string[] { };
} }
/// <summary> /// <summary>

@ -40,7 +40,7 @@ namespace MediaBrowser.Controller.Library
/// </summary> /// </summary>
UserItemDataDto GetUserDataDto(IHasUserData item, User user); UserItemDataDto GetUserDataDto(IHasUserData item, User user);
UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, List<ItemFields> fields); UserItemDataDto GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user, ItemFields[] fields);
/// <summary> /// <summary>
/// Get all user data for the given user /// Get all user data for the given user

@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Library
{ {
public interface IUserViewManager public interface IUserViewManager
{ {
Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken); Task<Folder[]> GetUserViews(UserViewQuery query, CancellationToken cancellationToken);
Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken); Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken);

@ -243,7 +243,7 @@ namespace MediaBrowser.Controller.LiveTv
/// Gets the recommended programs internal. /// Gets the recommended programs internal.
/// </summary> /// </summary>
/// <returns>Task&lt;QueryResult&lt;LiveTvProgram&gt;&gt;.</returns> /// <returns>Task&lt;QueryResult&lt;LiveTvProgram&gt;&gt;.</returns>
Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken); Task<QueryResult<BaseItem>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Gets the live tv information. /// Gets the live tv information.
@ -316,7 +316,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="fields">The fields.</param> /// <param name="fields">The fields.</param>
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> programs, List<ItemFields> fields, User user = null); Task AddInfoToProgramDto(List<Tuple<BaseItem, BaseItemDto>> programs, ItemFields[] fields, User user = null);
/// <summary> /// <summary>
/// Saves the tuner host. /// Saves the tuner host.
@ -335,7 +335,7 @@ namespace MediaBrowser.Controller.LiveTv
Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber); Task<TunerChannelMapping> SetChannelMapping(string providerId, string tunerChannelNumber, string providerChannelNumber);
TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, List<NameValuePair> mappings, List<ChannelInfo> providerChannels); TunerChannelMapping GetTunerChannelMapping(ChannelInfo channel, NameValuePair[] mappings, List<ChannelInfo> providerChannels);
/// <summary> /// <summary>
/// Gets the lineups. /// Gets the lineups.

@ -1521,7 +1521,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
var inputModifier = string.Empty; var inputModifier = string.Empty;
var numInputFiles = state.PlayableStreamFileNames.Count > 0 ? state.PlayableStreamFileNames.Count : 1; var numInputFiles = state.PlayableStreamFileNames.Length > 0 ? state.PlayableStreamFileNames.Length : 1;
var probeSizeArgument = GetProbeSizeArgument(numInputFiles); var probeSizeArgument = GetProbeSizeArgument(numInputFiles);
string analyzeDurationArgument; string analyzeDurationArgument;
@ -1676,12 +1676,12 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
else else
{ {
state.PlayableStreamFileNames = new List<string>(); state.PlayableStreamFileNames = new string[]{};
} }
} }
else else
{ {
state.PlayableStreamFileNames = new List<string>(); state.PlayableStreamFileNames = new string[] { };
} }
if (mediaSource.Timestamp.HasValue) if (mediaSource.Timestamp.HasValue)

@ -27,7 +27,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public string MediaPath { get; set; } public string MediaPath { get; set; }
public bool IsInputVideo { get; set; } public bool IsInputVideo { get; set; }
public IIsoMount IsoMount { get; set; } public IIsoMount IsoMount { get; set; }
public List<string> PlayableStreamFileNames { get; set; } public string[] PlayableStreamFileNames { get; set; }
public string OutputAudioCodec { get; set; } public string OutputAudioCodec { get; set; }
public int? OutputVideoBitrate { get; set; } public int? OutputVideoBitrate { get; set; }
public MediaStream SubtitleStream { get; set; } public MediaStream SubtitleStream { get; set; }
@ -42,8 +42,8 @@ namespace MediaBrowser.Controller.MediaEncoding
public bool ReadInputAtNativeFramerate { get; set; } public bool ReadInputAtNativeFramerate { get; set; }
private List<TranscodeReason> _transcodeReasons = null; private TranscodeReason[] _transcodeReasons = null;
public List<TranscodeReason> TranscodeReasons public TranscodeReason[] TranscodeReasons
{ {
get get
{ {
@ -53,7 +53,7 @@ namespace MediaBrowser.Controller.MediaEncoding
.Split(',') .Split(',')
.Where(i => !string.IsNullOrWhiteSpace(i)) .Where(i => !string.IsNullOrWhiteSpace(i))
.Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true)) .Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
.ToList(); .ToArray();
} }
return _transcodeReasons; return _transcodeReasons;
@ -164,7 +164,7 @@ namespace MediaBrowser.Controller.MediaEncoding
_logger = logger; _logger = logger;
TranscodingType = jobType; TranscodingType = jobType;
RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
PlayableStreamFileNames = new List<string>(); PlayableStreamFileNames = new string[]{};
SupportedAudioCodecs = new List<string>(); SupportedAudioCodecs = new List<string>();
SupportedVideoCodecs = new List<string>(); SupportedVideoCodecs = new List<string>();
SupportedSubtitleCodecs = new List<string>(); SupportedSubtitleCodecs = new List<string>();

@ -1,12 +1,9 @@
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using MediaBrowser.Controller.IO;
namespace MediaBrowser.Controller.MediaEncoding namespace MediaBrowser.Controller.MediaEncoding
{ {
/// <summary> /// <summary>
@ -23,34 +20,34 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <param name="isoMount">The iso mount.</param> /// <param name="isoMount">The iso mount.</param>
/// <param name="playableStreamFileNames">The playable stream file names.</param> /// <param name="playableStreamFileNames">The playable stream file names.</param>
/// <returns>System.String[][].</returns> /// <returns>System.String[][].</returns>
public static string[] GetInputArgument(IFileSystem fileSystem, string videoPath, MediaProtocol protocol, IIsoMount isoMount, List<string> playableStreamFileNames) public static string[] GetInputArgument(IFileSystem fileSystem, string videoPath, MediaProtocol protocol, IIsoMount isoMount, string[] playableStreamFileNames)
{ {
if (playableStreamFileNames.Count > 0) if (playableStreamFileNames.Length > 0)
{ {
if (isoMount == null) if (isoMount == null)
{ {
return GetPlayableStreamFiles(fileSystem, videoPath, playableStreamFileNames).ToArray(); return GetPlayableStreamFiles(fileSystem, videoPath, playableStreamFileNames);
} }
return GetPlayableStreamFiles(fileSystem, isoMount.MountedPath, playableStreamFileNames).ToArray(); return GetPlayableStreamFiles(fileSystem, isoMount.MountedPath, playableStreamFileNames);
} }
return new[] {videoPath}; return new[] {videoPath};
} }
private static List<string> GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, List<string> filenames) private static string[] GetPlayableStreamFiles(IFileSystem fileSystem, string rootPath, string[] filenames)
{ {
if (filenames.Count == 0) if (filenames.Length == 0)
{ {
return new List<string>(); return new string[]{};
} }
var allFiles = fileSystem var allFiles = fileSystem
.GetFilePaths(rootPath, true) .GetFilePaths(rootPath, true)
.ToList(); .ToArray();
return filenames.Select(name => allFiles.FirstOrDefault(f => string.Equals(Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase))) return filenames.Select(name => allFiles.FirstOrDefault(f => string.Equals(Path.GetFileName(f), name, StringComparison.OrdinalIgnoreCase)))
.Where(f => !string.IsNullOrEmpty(f)) .Where(f => !string.IsNullOrEmpty(f))
.ToList(); .ToArray();
} }
} }
} }

@ -14,12 +14,12 @@ namespace MediaBrowser.Controller.MediaEncoding
public DlnaProfileType MediaType { get; set; } public DlnaProfileType MediaType { get; set; }
public IIsoMount MountedIso { get; set; } public IIsoMount MountedIso { get; set; }
public VideoType VideoType { get; set; } public VideoType VideoType { get; set; }
public List<string> PlayableStreamFileNames { get; set; } public string[] PlayableStreamFileNames { get; set; }
public int AnalyzeDurationMs { get; set; } public int AnalyzeDurationMs { get; set; }
public MediaInfoRequest() public MediaInfoRequest()
{ {
PlayableStreamFileNames = new List<string>(); PlayableStreamFileNames = new string[] { };
} }
} }
} }

@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Notifications
/// Gets the notification types. /// Gets the notification types.
/// </summary> /// </summary>
/// <returns>IEnumerable{NotificationTypeInfo}.</returns> /// <returns>IEnumerable{NotificationTypeInfo}.</returns>
IEnumerable<NotificationTypeInfo> GetNotificationTypes(); List<NotificationTypeInfo> GetNotificationTypes();
/// <summary> /// <summary>
/// Gets the notification services. /// Gets the notification services.

@ -89,7 +89,7 @@ namespace MediaBrowser.Controller.Playlists
return new List<BaseItem>(); return new List<BaseItem>();
} }
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren) public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{ {
return GetPlayableItems(user, new DtoOptions(true)); return GetPlayableItems(user, new DtoOptions(true));
} }

@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Providers
/// Gets all metadata plugins. /// Gets all metadata plugins.
/// </summary> /// </summary>
/// <returns>IEnumerable{MetadataPlugin}.</returns> /// <returns>IEnumerable{MetadataPlugin}.</returns>
IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins(); MetadataPluginSummary[] GetAllMetadataPlugins();
/// <summary> /// <summary>
/// Gets the external urls. /// Gets the external urls.

@ -22,13 +22,13 @@ namespace MediaBrowser.Controller.Session
_sessionManager = sessionManager; _sessionManager = sessionManager;
_logger = logger; _logger = logger;
AdditionalUsers = new List<SessionUserInfo>(); AdditionalUsers = new SessionUserInfo[] { };
PlayState = new PlayerStateInfo(); PlayState = new PlayerStateInfo();
} }
public PlayerStateInfo PlayState { get; set; } public PlayerStateInfo PlayState { get; set; }
public List<SessionUserInfo> AdditionalUsers { get; set; } public SessionUserInfo[] AdditionalUsers { get; set; }
public ClientCapabilities Capabilities { get; set; } public ClientCapabilities Capabilities { get; set; }
@ -42,13 +42,13 @@ namespace MediaBrowser.Controller.Session
/// Gets or sets the playable media types. /// Gets or sets the playable media types.
/// </summary> /// </summary>
/// <value>The playable media types.</value> /// <value>The playable media types.</value>
public List<string> PlayableMediaTypes public string[] PlayableMediaTypes
{ {
get get
{ {
if (Capabilities == null) if (Capabilities == null)
{ {
return new List<string>(); return new string[] { };
} }
return Capabilities.PlayableMediaTypes; return Capabilities.PlayableMediaTypes;
} }
@ -138,13 +138,13 @@ namespace MediaBrowser.Controller.Session
/// Gets or sets the supported commands. /// Gets or sets the supported commands.
/// </summary> /// </summary>
/// <value>The supported commands.</value> /// <value>The supported commands.</value>
public List<string> SupportedCommands public string[] SupportedCommands
{ {
get get
{ {
if (Capabilities == null) if (Capabilities == null)
{ {
return new List<string>(); return new string[] { };
} }
return Capabilities.SupportedCommands; return Capabilities.SupportedCommands;
} }

@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Subtitles
/// <summary> /// <summary>
/// Searches the subtitles. /// Searches the subtitles.
/// </summary> /// </summary>
Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitles(Video video, Task<RemoteSubtitleInfo[]> SearchSubtitles(Video video,
string language, string language,
bool? isPerfectMatch, bool? isPerfectMatch,
CancellationToken cancellationToken); CancellationToken cancellationToken);
@ -39,7 +39,7 @@ namespace MediaBrowser.Controller.Subtitles
/// <param name="request">The request.</param> /// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{IEnumerable{RemoteSubtitleInfo}}.</returns> /// <returns>Task{IEnumerable{RemoteSubtitleInfo}}.</returns>
Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitles(SubtitleSearchRequest request, Task<RemoteSubtitleInfo[]> SearchSubtitles(SubtitleSearchRequest request,
CancellationToken cancellationToken); CancellationToken cancellationToken);
/// <summary> /// <summary>
@ -74,6 +74,6 @@ namespace MediaBrowser.Controller.Subtitles
/// </summary> /// </summary>
/// <param name="itemId">The item identifier.</param> /// <param name="itemId">The item identifier.</param>
/// <returns>IEnumerable{SubtitleProviderInfo}.</returns> /// <returns>IEnumerable{SubtitleProviderInfo}.</returns>
IEnumerable<SubtitleProviderInfo> GetProviders(string itemId); SubtitleProviderInfo[] GetProviders(string itemId);
} }
} }

@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.Sync
/// <param name="targetId">The target identifier.</param> /// <param name="targetId">The target identifier.</param>
/// <param name="itemIds">The item ids.</param> /// <param name="itemIds">The item ids.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task CancelItems(string targetId, IEnumerable<string> itemIds); Task CancelItems(string targetId, string[] itemIds);
/// <summary> /// <summary>
/// Adds the parts. /// Adds the parts.
@ -89,9 +89,9 @@ namespace MediaBrowser.Controller.Sync
/// <summary> /// <summary>
/// Gets the synchronize targets. /// Gets the synchronize targets.
/// </summary> /// </summary>
IEnumerable<SyncTarget> GetSyncTargets(string userId); List<SyncTarget> GetSyncTargets(string userId);
IEnumerable<SyncTarget> GetSyncTargets(string userId, bool? supportsRemoteSync); List<SyncTarget> GetSyncTargets(string userId, bool? supportsRemoteSync);
/// <summary> /// <summary>
/// Supportses the synchronize. /// Supportses the synchronize.
@ -160,28 +160,24 @@ namespace MediaBrowser.Controller.Sync
/// Gets the quality options. /// Gets the quality options.
/// </summary> /// </summary>
/// <param name="targetId">The target identifier.</param> /// <param name="targetId">The target identifier.</param>
/// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns> List<SyncQualityOption> GetQualityOptions(string targetId);
IEnumerable<SyncQualityOption> GetQualityOptions(string targetId);
/// <summary> /// <summary>
/// Gets the quality options. /// Gets the quality options.
/// </summary> /// </summary>
/// <param name="targetId">The target identifier.</param> /// <param name="targetId">The target identifier.</param>
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
/// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns> List<SyncQualityOption> GetQualityOptions(string targetId, User user);
IEnumerable<SyncQualityOption> GetQualityOptions(string targetId, User user);
/// <summary> /// <summary>
/// Gets the profile options. /// Gets the profile options.
/// </summary> /// </summary>
/// <param name="targetId">The target identifier.</param> /// <param name="targetId">The target identifier.</param>
/// <returns>IEnumerable&lt;SyncQualityOption&gt;.</returns> List<SyncProfileOption> GetProfileOptions(string targetId);
IEnumerable<SyncProfileOption> GetProfileOptions(string targetId);
/// <summary> /// <summary>
/// Gets the profile options. /// Gets the profile options.
/// </summary> /// </summary>
/// <param name="targetId">The target identifier.</param> /// <param name="targetId">The target identifier.</param>
/// <param name="user">The user.</param> /// <param name="user">The user.</param>
/// <returns>IEnumerable&lt;SyncProfileOption&gt;.</returns> List<SyncProfileOption> GetProfileOptions(string targetId, User user);
IEnumerable<SyncProfileOption> GetProfileOptions(string targetId, User user);
} }
} }

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

Loading…
Cancel
Save