Merge pull request #2343 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-12-15 15:07:15 -05:00 committed by GitHub
commit b0b65b17a4
6 changed files with 81 additions and 48 deletions

View file

@ -20,9 +20,6 @@ namespace Emby.Dlna.PlayTo
{ {
public class Device : IDisposable public class Device : IDisposable
{ {
const string ServiceAvtransportType = "urn:schemas-upnp-org:service:AVTransport:1";
const string ServiceRenderingType = "urn:schemas-upnp-org:service:RenderingControl:1";
#region Fields & Properties #region Fields & Properties
private ITimer _timer; private ITimer _timer;
@ -254,13 +251,29 @@ namespace Emby.Dlna.PlayTo
} }
} }
private DeviceService GetServiceRenderingControl()
{
var services = Properties.Services;
return services.FirstOrDefault(s => string.Equals(s.ServiceType, "urn:schemas-upnp-org:service:RenderingControl:1", StringComparison.OrdinalIgnoreCase)) ??
services.FirstOrDefault(s => (s.ServiceType ?? string.Empty).StartsWith("urn:schemas-upnp-org:service:RenderingControl", StringComparison.OrdinalIgnoreCase));
}
private DeviceService GetAvTransportService()
{
var services = Properties.Services;
return services.FirstOrDefault(s => string.Equals(s.ServiceType, "urn:schemas-upnp-org:service:AVTransport:1", StringComparison.OrdinalIgnoreCase)) ??
services.FirstOrDefault(s => (s.ServiceType ?? string.Empty).StartsWith("urn:schemas-upnp-org:service:AVTransport", StringComparison.OrdinalIgnoreCase));
}
private async Task<bool> SetMute(bool mute) private async Task<bool> SetMute(bool mute)
{ {
var command = RendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetMute"); var command = RendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetMute");
if (command == null) if (command == null)
return false; return false;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceRenderingType); var service = GetServiceRenderingControl();
if (service == null) if (service == null)
{ {
@ -287,7 +300,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceRenderingType); var service = GetServiceRenderingControl();
if (service == null) if (service == null)
{ {
@ -308,7 +321,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
if (service == null) if (service == null)
{ {
@ -333,7 +346,7 @@ namespace Emby.Dlna.PlayTo
{"CurrentURIMetaData", CreateDidlMeta(metaData)} {"CurrentURIMetaData", CreateDidlMeta(metaData)}
}; };
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
if (service == null) if (service == null)
{ {
@ -373,7 +386,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
if (service == null) if (service == null)
{ {
@ -390,7 +403,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.First(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1)) await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1))
.ConfigureAwait(false); .ConfigureAwait(false);
@ -402,7 +415,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.First(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1)) await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, 1))
.ConfigureAwait(false); .ConfigureAwait(false);
@ -521,7 +534,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceRenderingType); var service = GetServiceRenderingControl();
if (service == null) if (service == null)
{ {
@ -554,7 +567,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return; return;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceRenderingType); var service = GetServiceRenderingControl();
if (service == null) if (service == null)
{ {
@ -579,7 +592,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return null; return null;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
if (service == null) if (service == null)
return null; return null;
@ -613,7 +626,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return null; return null;
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
if (service == null) if (service == null)
{ {
@ -644,7 +657,7 @@ namespace Emby.Dlna.PlayTo
if (command == null) if (command == null)
return new Tuple<bool, uBaseObject>(false, null); return new Tuple<bool, uBaseObject>(false, null);
var service = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var service = GetAvTransportService();
if (service == null) if (service == null)
{ {
@ -697,7 +710,7 @@ namespace Emby.Dlna.PlayTo
} }
XElement uPnpResponse; XElement uPnpResponse;
// Handle different variations sent back by devices // Handle different variations sent back by devices
try try
{ {
@ -780,28 +793,28 @@ namespace Emby.Dlna.PlayTo
private async Task GetAVProtocolAsync() private async Task GetAVProtocolAsync()
{ {
var avService = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceAvtransportType); var avService = GetAvTransportService();
if (avService == null) if (avService == null)
return; return;
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);
var httpClient = new SsdpHttpClient(_httpClient, _config); var httpClient = new SsdpHttpClient(_httpClient, _config);
var document = await httpClient.GetDataAsync(url); var document = await httpClient.GetDataAsync(url).ConfigureAwait(false);
AvCommands = TransportCommands.Create(document); AvCommands = TransportCommands.Create(document);
} }
private async Task GetRenderingProtocolAsync() private async Task GetRenderingProtocolAsync()
{ {
var avService = Properties.Services.FirstOrDefault(s => s.ServiceType == ServiceRenderingType); var avService = GetServiceRenderingControl();
if (avService == null) if (avService == null)
return; return;
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl); string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);
var httpClient = new SsdpHttpClient(_httpClient, _config); var httpClient = new SsdpHttpClient(_httpClient, _config);
var document = await httpClient.GetDataAsync(url); var document = await httpClient.GetDataAsync(url).ConfigureAwait(false);
RendererCommands = TransportCommands.Create(document); RendererCommands = TransportCommands.Create(document);
} }
@ -899,8 +912,6 @@ namespace Emby.Dlna.PlayTo
deviceProperties.Icon = CreateIcon(icon); deviceProperties.Icon = CreateIcon(icon);
} }
var isRenderer = false;
foreach (var services in document.Descendants(uPnpNamespaces.ud.GetName("serviceList"))) foreach (var services in document.Descendants(uPnpNamespaces.ud.GetName("serviceList")))
{ {
if (services == null) if (services == null)
@ -918,17 +929,13 @@ namespace Emby.Dlna.PlayTo
if (service != null) if (service != null)
{ {
deviceProperties.Services.Add(service); deviceProperties.Services.Add(service);
if (service.ServiceType == ServiceAvtransportType)
{
isRenderer = true;
}
} }
} }
} }
var device = new Device(deviceProperties, httpClient, logger, config, timerFactory); var device = new Device(deviceProperties, httpClient, logger, config, timerFactory);
if (isRenderer) if (device.GetAvTransportService() != null)
{ {
await device.GetRenderingProtocolAsync().ConfigureAwait(false); await device.GetRenderingProtocolAsync().ConfigureAwait(false);
await device.GetAVProtocolAsync().ConfigureAwait(false); await device.GetAVProtocolAsync().ConfigureAwait(false);

View file

@ -389,6 +389,8 @@ namespace Emby.Server.Implementations.Data
}); });
} }
} }
GC.Collect();
} }
catch (Exception ex) catch (Exception ex)
{ {

View file

@ -855,7 +855,7 @@ namespace Emby.Server.Implementations.Library
SortOrder = SortOrder.Descending, SortOrder = SortOrder.Descending,
Limit = 1 Limit = 1
}; };
return GetItemList(query) return GetItemList(query)
.FirstOrDefault(); .FirstOrDefault();
} }
@ -1113,16 +1113,21 @@ namespace Emby.Server.Implementations.Library
progress.Report(1); progress.Report(1);
var userRoot = GetUserRootFolder(); await GetUserRootFolder().RefreshMetadata(cancellationToken).ConfigureAwait(false);
await userRoot.RefreshMetadata(cancellationToken).ConfigureAwait(false); await GetUserRootFolder().ValidateChildren(new Progress<double>(), cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: false).ConfigureAwait(false);
await userRoot.ValidateChildren(new Progress<double>(), cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: false).ConfigureAwait(false);
progress.Report(2); progress.Report(2);
// Quickly scan CollectionFolders for changes
foreach (var folder in GetUserRootFolder().Children.OfType<Folder>().ToList())
{
await folder.RefreshMetadata(cancellationToken).ConfigureAwait(false);
}
progress.Report(3);
var innerProgress = new ActionableProgress<double>(); var innerProgress = new ActionableProgress<double>();
innerProgress.RegisterAction(pct => progress.Report(2 + pct * .73)); innerProgress.RegisterAction(pct => progress.Report(3 + pct * .72));
// Now validate the entire media library // Now validate the entire media library
await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: true).ConfigureAwait(false); await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(_fileSystem), recursive: true).ConfigureAwait(false);
@ -1291,7 +1296,6 @@ namespace Emby.Server.Implementations.Library
if (parent != null) if (parent != null)
{ {
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent }); SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
query.ParentId = null;
} }
} }
@ -1311,7 +1315,6 @@ namespace Emby.Server.Implementations.Library
if (parent != null) if (parent != null)
{ {
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent }); SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
query.ParentId = null;
} }
} }
@ -1456,6 +1459,12 @@ namespace Emby.Server.Implementations.Library
// Optimize by querying against top level views // Optimize by querying against top level views
query.TopParentIds = parents.SelectMany(i => GetTopParentIdsForQuery(i, query.User)).Select(i => i.ToString("N")).ToArray(); query.TopParentIds = parents.SelectMany(i => GetTopParentIdsForQuery(i, query.User)).Select(i => i.ToString("N")).ToArray();
query.AncestorIds = new string[] { }; query.AncestorIds = new string[] { };
// Prevent searching in all libraries due to empty filter
if (query.TopParentIds.Length == 0)
{
query.TopParentIds = new[] { Guid.NewGuid().ToString("N") };
}
} }
} }
@ -1478,7 +1487,6 @@ namespace Emby.Server.Implementations.Library
if (parent != null) if (parent != null)
{ {
SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent }); SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
query.ParentId = null;
} }
} }
@ -1514,12 +1522,26 @@ namespace Emby.Server.Implementations.Library
{ {
// Optimize by querying against top level views // Optimize by querying against top level views
query.TopParentIds = parents.SelectMany(i => GetTopParentIdsForQuery(i, query.User)).Select(i => i.ToString("N")).ToArray(); query.TopParentIds = parents.SelectMany(i => GetTopParentIdsForQuery(i, query.User)).Select(i => i.ToString("N")).ToArray();
// Prevent searching in all libraries due to empty filter
if (query.TopParentIds.Length == 0)
{
query.TopParentIds = new[] { Guid.NewGuid().ToString("N") };
}
} }
else else
{ {
// We need to be able to query from any arbitrary ancestor up the tree // We need to be able to query from any arbitrary ancestor up the tree
query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray(); query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray();
// Prevent searching in all libraries due to empty filter
if (query.AncestorIds.Length == 0)
{
query.AncestorIds = new[] { Guid.NewGuid().ToString("N") };
}
} }
query.ParentId = null;
} }
private void AddUserToQuery(InternalItemsQuery query, User user) private void AddUserToQuery(InternalItemsQuery query, User user)
@ -1561,7 +1583,7 @@ namespace Emby.Server.Implementations.Library
}, CancellationToken.None).Result; }, CancellationToken.None).Result;
return channelResult.Items.Select(i => i.Id); return channelResult.Items.Select(i => i.Id);
} }
// Translate view into folders // Translate view into folders
@ -1602,7 +1624,7 @@ namespace Emby.Server.Implementations.Library
{ {
return collectionFolder.PhysicalFolderIds; return collectionFolder.PhysicalFolderIds;
} }
var topParent = item.GetTopParent(); var topParent = item.GetTopParent();
if (topParent != null) if (topParent != null)
{ {

View file

@ -144,23 +144,16 @@ namespace Emby.Server.Implementations.TV
// If viewing all next up for all series, remove first episodes // If viewing all next up for all series, remove first episodes
// But if that returns empty, keep those first episodes (avoid completely empty view) // But if that returns empty, keep those first episodes (avoid completely empty view)
var alwaysEnableFirstEpisode = !string.IsNullOrWhiteSpace(request.SeriesId); var alwaysEnableFirstEpisode = !string.IsNullOrWhiteSpace(request.SeriesId);
var isFirstItemAFirstEpisode = true;
return allNextUp return allNextUp
.Where(i => .Where(i =>
{ {
if (alwaysEnableFirstEpisode || i.Item1 != DateTime.MinValue) if (alwaysEnableFirstEpisode || i.Item1 != DateTime.MinValue)
{ {
isFirstItemAFirstEpisode = false;
return true; return true;
} }
if (isFirstItemAFirstEpisode) return false;
{
return false;
}
return true;
}) })
.Select(i => i.Item2()) .Select(i => i.Item2())
.Where(i => i != null) .Where(i => i != null)

View file

@ -145,7 +145,8 @@ 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 ||
client.IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1 || client.IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1) client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
{ {
options.Fields.Add(Model.Querying.ItemFields.ChildCount); options.Fields.Add(Model.Querying.ItemFields.ChildCount);
} }

View file

@ -201,6 +201,11 @@ namespace MediaBrowser.Controller.Entities
} }
protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren) protected override bool RefreshLinkedChildren(IEnumerable<FileSystemMetadata> fileSystemChildren)
{
return RefreshLinkedChildrenInternal(true);
}
private bool RefreshLinkedChildrenInternal(bool setFolders)
{ {
var physicalFolders = GetPhysicalFolders(false) var physicalFolders = GetPhysicalFolders(false)
.ToList(); .ToList();
@ -219,7 +224,10 @@ namespace MediaBrowser.Controller.Entities
if (!folderIds.SequenceEqual(newFolderIds)) if (!folderIds.SequenceEqual(newFolderIds))
{ {
changed = true; changed = true;
PhysicalFolderIds = newFolderIds.ToList(); if (setFolders)
{
PhysicalFolderIds = newFolderIds.ToList();
}
} }
return changed; return changed;