Merge pull request #2333 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-12-08 01:54:16 -05:00 committed by GitHub
commit 862018b5c2
22 changed files with 219 additions and 143 deletions

View File

@ -13,7 +13,9 @@ namespace Emby.Common.Implementations.Net
public Socket Socket { get; private set; } public Socket Socket { get; private set; }
private readonly ILogger _logger; private readonly ILogger _logger;
public NetSocket(Socket socket, ILogger logger) public bool DualMode { get; private set; }
public NetSocket(Socket socket, ILogger logger, bool isDualMode)
{ {
if (socket == null) if (socket == null)
{ {
@ -26,6 +28,7 @@ namespace Emby.Common.Implementations.Net
Socket = socket; Socket = socket;
_logger = logger; _logger = logger;
DualMode = isDualMode;
} }
public IpEndPointInfo LocalEndPoint public IpEndPointInfo LocalEndPoint
@ -81,7 +84,7 @@ namespace Emby.Common.Implementations.Net
private SocketAcceptor _acceptor; private SocketAcceptor _acceptor;
public void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed) public void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed)
{ {
_acceptor = new SocketAcceptor(_logger, Socket, onAccept, isClosed); _acceptor = new SocketAcceptor(_logger, Socket, onAccept, isClosed, DualMode);
_acceptor.StartAccept(); _acceptor.StartAccept();
} }

View File

@ -11,8 +11,9 @@ namespace Emby.Common.Implementations.Net
private readonly Socket _originalSocket; private readonly Socket _originalSocket;
private readonly Func<bool> _isClosed; private readonly Func<bool> _isClosed;
private readonly Action<ISocket> _onAccept; private readonly Action<ISocket> _onAccept;
private readonly bool _isDualMode;
public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed) public SocketAcceptor(ILogger logger, Socket originalSocket, Action<ISocket> onAccept, Func<bool> isClosed, bool isDualMode)
{ {
if (logger == null) if (logger == null)
{ {
@ -34,6 +35,7 @@ namespace Emby.Common.Implementations.Net
_logger = logger; _logger = logger;
_originalSocket = originalSocket; _originalSocket = originalSocket;
_isClosed = isClosed; _isClosed = isClosed;
_isDualMode = isDualMode;
_onAccept = onAccept; _onAccept = onAccept;
} }
@ -115,7 +117,7 @@ namespace Emby.Common.Implementations.Net
if (acceptSocket != null) if (acceptSocket != null)
{ {
//ProcessAccept(acceptSocket); //ProcessAccept(acceptSocket);
_onAccept(new NetSocket(acceptSocket, _logger)); _onAccept(new NetSocket(acceptSocket, _logger, _isDualMode));
} }
// Accept the next connection request // Accept the next connection request

View File

@ -46,21 +46,11 @@ namespace Emby.Common.Implementations.Net
socket.DualMode = true; socket.DualMode = true;
} }
return new NetSocket(socket, _logger); return new NetSocket(socket, _logger, dualMode);
} }
catch (SocketException ex) catch (SocketException ex)
{ {
if (dualMode) throw new SocketCreateException(ex.SocketErrorCode.ToString(), ex);
{
_logger.Error("Error creating dual mode socket: {0}. Will retry with ipv4-only.", ex.SocketErrorCode);
if (ex.SocketErrorCode == SocketError.AddressFamilyNotSupported)
{
return CreateSocket(IpAddressFamily.InterNetwork, socketType, protocolType, false);
}
}
throw;
} }
} }

View File

@ -1305,19 +1305,49 @@ namespace Emby.Server.Core
public async Task<List<IpAddressInfo>> GetLocalIpAddresses() public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
{ {
var addresses = NetworkManager.GetLocalIpAddresses().ToList(); var addresses = ServerConfigurationManager
var list = new List<IpAddressInfo>(); .Configuration
.LocalNetworkAddresses
.Select(NormalizeConfiguredLocalAddress)
.Where(i => i != null)
.ToList();
foreach (var address in addresses) if (addresses.Count == 0)
{ {
var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false); addresses.AddRange(NetworkManager.GetLocalIpAddresses());
if (valid)
var list = new List<IpAddressInfo>();
foreach (var address in addresses)
{ {
list.Add(address); var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
if (valid)
{
list.Add(address);
}
} }
addresses = list;
} }
return list; return addresses;
}
private IpAddressInfo NormalizeConfiguredLocalAddress(string address)
{
var index = address.Trim('/').IndexOf('/');
if (index != -1)
{
address = address.Substring(index + 1);
}
IpAddressInfo result;
if (NetworkManager.TryParseIpAddress(address.Trim('/'), out result))
{
return result;
}
return null;
} }
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
@ -1553,7 +1583,8 @@ namespace Emby.Server.Core
throw new NotImplementedException(); throw new NotImplementedException();
} }
var process = ProcessFactory.Create(new ProcessOptions { var process = ProcessFactory.Create(new ProcessOptions
{
FileName = url, FileName = url,
EnableRaisingEvents = true, EnableRaisingEvents = true,
UseShellExecute = true, UseShellExecute = true,

View File

@ -1351,6 +1351,27 @@ namespace Emby.Server.Implementations.Dto
if (episodeSeries != null) if (episodeSeries != null)
{ {
dto.SeriesStudio = episodeSeries.Studios.FirstOrDefault(); dto.SeriesStudio = episodeSeries.Studios.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(dto.SeriesStudio))
{
try
{
var studio = _libraryManager.GetStudio(dto.SeriesStudio);
if (studio != null)
{
dto.SeriesStudioInfo = new StudioDto
{
Name = dto.SeriesStudio,
Id = studio.Id.ToString("N"),
PrimaryImageTag = GetImageCacheTag(studio, ImageType.Primary)
};
}
}
catch (Exception ex)
{
}
}
} }
} }
} }

View File

@ -341,13 +341,13 @@ namespace Emby.Server.Implementations.Library
} }
if (item is IItemByName) if (item is IItemByName)
{ {
if (!(item is MusicArtist)) if (!(item is MusicArtist) && !(item is Studio))
{ {
return; return;
} }
} }
if (item.IsFolder) else if (item.IsFolder)
{ {
//if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder)) //if (!(item is ICollectionFolder) && !(item is UserView) && !(item is Channel) && !(item is AggregateFolder))
//{ //{

View File

@ -1594,7 +1594,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private void Process_Exited(object sender, EventArgs e) private void Process_Exited(object sender, EventArgs e)
{ {
((IProcess)sender).Dispose(); var process = (IProcess)sender;
try
{
_logger.Info("Recording post-processing script completed with exit code {0}", process.ExitCode);
}
catch
{
}
process.Dispose();
} }
private async Task SaveRecordingImage(string recordingPath, LiveTvProgram program, ItemImageInfo image) private async Task SaveRecordingImage(string recordingPath, LiveTvProgram program, ItemImageInfo image)

View File

@ -377,7 +377,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var url = GetApiUrl(info, true) + "/auto/v" + channelId; var url = GetApiUrl(info, true) + "/auto/v" + channelId;
if (!string.IsNullOrWhiteSpace(profile) && !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase)) // If raw was used, the tuner doesn't support params
if (!string.IsNullOrWhiteSpace(profile)
&& !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
{ {
url += "?transcode=" + profile; url += "?transcode=" + profile;
} }
@ -451,16 +453,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
var hdhrId = GetHdHrIdFromChannelId(channelId); var hdhrId = GetHdHrIdFromChannelId(channelId);
list.Add(await GetMediaSource(info, hdhrId, "native").ConfigureAwait(false));
try try
{ {
if (info.AllowHWTranscoding) var model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false);
{ model = model ?? string.Empty;
string model = await GetModelInfo(info, cancellationToken).ConfigureAwait(false);
model = model ?? string.Empty;
if ((model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)) if ((model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1))
{
list.Add(await GetMediaSource(info, hdhrId, "native").ConfigureAwait(false));
if (info.AllowHWTranscoding)
{ {
list.Add(await GetMediaSource(info, hdhrId, "heavy").ConfigureAwait(false)); list.Add(await GetMediaSource(info, hdhrId, "heavy").ConfigureAwait(false));
@ -477,6 +479,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
if (list.Count == 0)
{
list.Add(await GetMediaSource(info, hdhrId, "native").ConfigureAwait(false));
}
return list; return list;
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -100,16 +101,23 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
extInf = extInf.Trim(); extInf = extInf.Trim();
channel.ImageUrl = FindProperty("tvg-logo", extInf); string remaining;
var attributes = ParseExtInf(extInf, out remaining);
extInf = remaining;
channel.Name = GetChannelName(extInf); string value;
if (attributes.TryGetValue("tvg-logo", out value))
{
channel.ImageUrl = value;
}
channel.Number = GetChannelNumber(extInf, mediaUrl); channel.Name = GetChannelName(extInf, attributes);
channel.Number = GetChannelNumber(extInf, attributes, mediaUrl);
return channel; return channel;
} }
private string GetChannelNumber(string extInf, string mediaUrl) private string GetChannelNumber(string extInf, Dictionary<string, string> attributes, string mediaUrl)
{ {
var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null;
@ -130,18 +138,41 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
} }
} }
if (string.IsNullOrWhiteSpace(numberString) || if (!string.IsNullOrWhiteSpace(numberString))
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
{ {
numberString = FindProperty("tvg-id", extInf); numberString = numberString.Trim();
} }
if (string.IsNullOrWhiteSpace(numberString) || if (string.IsNullOrWhiteSpace(numberString) ||
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) || string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase)) string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
{ {
numberString = FindProperty("channel-id", extInf); string value;
if (attributes.TryGetValue("tvg-id", out value))
{
numberString = value;
}
}
if (!string.IsNullOrWhiteSpace(numberString))
{
numberString = numberString.Trim();
}
if (string.IsNullOrWhiteSpace(numberString) ||
string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) ||
string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase))
{
string value;
if (attributes.TryGetValue("channel-id", out value))
{
numberString = value;
}
}
if (!string.IsNullOrWhiteSpace(numberString))
{
numberString = numberString.Trim();
} }
if (string.IsNullOrWhiteSpace(numberString) || if (string.IsNullOrWhiteSpace(numberString) ||
@ -160,13 +191,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
else else
{ {
numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last()); numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last());
double value;
if (!double.TryParse(numberString, NumberStyles.Any, CultureInfo.InvariantCulture, out value))
{
numberString = null;
}
} }
} }
return numberString; return numberString;
} }
private string GetChannelName(string extInf) private string GetChannelName(string extInf, Dictionary<string, string> attributes)
{ {
var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null;
@ -186,7 +223,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
} }
} }
var name = FindProperty("tvg-name", extInf); string name;
attributes.TryGetValue("tvg-name", out name);
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
name = nameInExtInf; name = nameInExtInf;
@ -194,7 +233,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
name = FindProperty("tvg-id", extInf); attributes.TryGetValue("tvg-id", out name);
} }
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
@ -205,18 +244,27 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return name; return name;
} }
private string FindProperty(string property, string properties) private Dictionary<string, string> ParseExtInf(string line, out string remaining)
{ {
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase); var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
var matches = reg.Matches(properties); var matches = reg.Matches(line);
var minIndex = int.MaxValue;
foreach (Match match in matches) foreach (Match match in matches)
{ {
if (match.Groups[1].Value == property) dict[match.Groups[1].Value] = match.Groups[2].Value;
{ minIndex = Math.Min(minIndex, match.Index);
return match.Groups[2].Value;
}
} }
return null;
if (minIndex > 0 && minIndex < line.Length)
{
line = line.Substring(0, minIndex);
}
remaining = line;
return dict;
} }
} }

View File

@ -258,7 +258,7 @@ namespace MediaBrowser.Api.Playback.Hls
// add when stream copying? // add when stream copying?
// -avoid_negative_ts make_zero -fflags +genpts // -avoid_negative_ts make_zero -fflags +genpts
var args = string.Format("{0} {1} {2} -map_metadata -1 -threads {3} {4} {5} -fflags +genpts -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"", var args = string.Format("{0} {1} {2} -map_metadata -1 -map_chapters -1 -threads {3} {4} {5} -fflags +genpts -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"",
itsOffset, itsOffset,
inputModifier, inputModifier,
GetInputArgument(state), GetInputArgument(state),

View File

@ -895,7 +895,7 @@ namespace MediaBrowser.Api.Playback.Hls
{ {
var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state); var outputTsArg = Path.Combine(Path.GetDirectoryName(outputPath), Path.GetFileNameWithoutExtension(outputPath)) + "%d" + GetSegmentFileExtension(state);
return string.Format("{0} {10} {1} -map_metadata -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} -break_non_keyframes 1 -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"", return string.Format("{0} {10} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -f segment -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -segment_time {6} -break_non_keyframes 1 -segment_format mpegts -segment_list_type m3u8 -segment_start_number {7} -segment_list \"{8}\" -y \"{9}\"",
inputModifier, inputModifier,
GetInputArgument(state), GetInputArgument(state),
threads, threads,
@ -913,7 +913,7 @@ namespace MediaBrowser.Api.Playback.Hls
var splitByTime = hlsProtocolSupportsSplittingByTime && enableSplittingOnNonKeyFrames; var splitByTime = hlsProtocolSupportsSplittingByTime && enableSplittingOnNonKeyFrames;
var splitByTimeArg = splitByTime ? " -hls_flags split_by_time" : ""; var splitByTimeArg = splitByTime ? " -hls_flags split_by_time" : "";
return string.Format("{0}{12} {1} -map_metadata -1 -threads {2} {3} {4}{5} {6} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {7}{8} -start_number {9} -hls_list_size {10} -y \"{11}\"", return string.Format("{0}{12} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4}{5} {6} -max_delay 5000000 -avoid_negative_ts disabled -start_at_zero -hls_time {7}{8} -start_number {9} -hls_list_size {10} -y \"{11}\"",
inputModifier, inputModifier,
GetInputArgument(state), GetInputArgument(state),
threads, threads,

View File

@ -111,7 +111,7 @@ namespace MediaBrowser.Api.Playback.Progressive
var inputModifier = GetInputModifier(state); var inputModifier = GetInputModifier(state);
return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -threads {5} {6}{7} -y \"{8}\"", return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -map_chapters -1 -threads {5} {6}{7} -y \"{8}\"",
inputModifier, inputModifier,
GetInputArgument(state), GetInputArgument(state),
keyFrame, keyFrame,

View File

@ -3,7 +3,6 @@ namespace MediaBrowser.Api.Reports
public enum ReportViewType public enum ReportViewType
{ {
ReportData, ReportData,
ReportStatistics,
ReportActivities ReportActivities
} }

View File

@ -60,7 +60,7 @@ namespace MediaBrowser.Api.Reports
{ {
/// <summary> Gets or sets the report view. </summary> /// <summary> Gets or sets the report view. </summary>
/// <value> The report view. </value> /// <value> The report view. </value>
[ApiMember(Name = "ReportView", Description = "The report view. Values (ReportData, ReportStatistics, ReportActivities)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "ReportView", Description = "The report view. Values (ReportData, ReportActivities)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ReportView { get; set; } public string ReportView { get; set; }
/// <summary> Gets or sets the report view. </summary> /// <summary> Gets or sets the report view. </summary>
@ -101,7 +101,7 @@ namespace MediaBrowser.Api.Reports
{ {
/// <summary> Gets or sets the report view. </summary> /// <summary> Gets or sets the report view. </summary>
/// <value> The report view. </value> /// <value> The report view. </value>
[ApiMember(Name = "ReportView", Description = "The report view. Values (ReportData, ReportStatistics, ReportActivities)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "ReportView", Description = "The report view. Values (ReportData, ReportActivities)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ReportView { get; set; } public string ReportView { get; set; }
/// <summary> Gets or sets the report view. </summary> /// <summary> Gets or sets the report view. </summary>
@ -120,13 +120,6 @@ namespace MediaBrowser.Api.Reports
public string ReportColumns { get; set; } public string ReportColumns { get; set; }
} }
[Route("/Reports/Statistics", "GET", Summary = "Gets reports statistics based on library items")]
public class GetReportStatistics : BaseReportRequest, IReturn<ReportStatResult>
{
public int? TopItems { get; set; }
}
[Route("/Reports/Items/Download", "GET", Summary = "Downloads report")] [Route("/Reports/Items/Download", "GET", Summary = "Downloads report")]
public class GetReportDownload : BaseReportRequest, IReportsDownload public class GetReportDownload : BaseReportRequest, IReportsDownload
{ {
@ -150,7 +143,7 @@ namespace MediaBrowser.Api.Reports
{ {
/// <summary> Gets or sets the report view. </summary> /// <summary> Gets or sets the report view. </summary>
/// <value> The report view. </value> /// <value> The report view. </value>
[ApiMember(Name = "ReportView", Description = "The report view. Values (ReportData, ReportStatistics, ReportActivities)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "ReportView", Description = "The report view. Values (ReportData, ReportActivities)", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ReportView { get; set; } public string ReportView { get; set; }
/// <summary> Gets or sets the report view. </summary> /// <summary> Gets or sets the report view. </summary>

View File

@ -82,8 +82,6 @@ namespace MediaBrowser.Api.Reports
ReportBuilder dataBuilder = new ReportBuilder(_libraryManager); ReportBuilder dataBuilder = new ReportBuilder(_libraryManager);
result = dataBuilder.GetHeaders(request); result = dataBuilder.GetHeaders(request);
break; break;
case ReportViewType.ReportStatistics:
break;
case ReportViewType.ReportActivities: case ReportViewType.ReportActivities:
ReportActivitiesBuilder activityBuilder = new ReportActivitiesBuilder(_libraryManager, _userManager); ReportActivitiesBuilder activityBuilder = new ReportActivitiesBuilder(_libraryManager, _userManager);
result = activityBuilder.GetHeaders(request); result = activityBuilder.GetHeaders(request);
@ -109,20 +107,6 @@ namespace MediaBrowser.Api.Reports
return ToOptimizedResult(reportResult); return ToOptimizedResult(reportResult);
} }
/// <summary> Gets the given request. </summary>
/// <param name="request"> The request. </param>
/// <returns> A Task&lt;object&gt; </returns>
public async Task<object> Get(GetReportStatistics request)
{
if (string.IsNullOrEmpty(request.IncludeItemTypes))
return null;
request.DisplayType = "Screen";
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
var reportResult = await GetReportStatistic(request, user);
return ToOptimizedResult(reportResult);
}
/// <summary> Gets the given request. </summary> /// <summary> Gets the given request. </summary>
/// <param name="request"> The request. </param> /// <param name="request"> The request. </param>
/// <returns> A Task&lt;object&gt; </returns> /// <returns> A Task&lt;object&gt; </returns>
@ -155,7 +139,6 @@ namespace MediaBrowser.Api.Reports
ReportResult result = null; ReportResult result = null;
switch (reportViewType) switch (reportViewType)
{ {
case ReportViewType.ReportStatistics:
case ReportViewType.ReportData: case ReportViewType.ReportData:
ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes);
ReportBuilder dataBuilder = new ReportBuilder(_libraryManager); ReportBuilder dataBuilder = new ReportBuilder(_libraryManager);
@ -463,20 +446,6 @@ namespace MediaBrowser.Api.Reports
return reportResult; return reportResult;
} }
/// <summary> Gets report statistic. </summary>
/// <param name="request"> The request. </param>
/// <returns> The report statistic. </returns>
private async Task<ReportStatResult> GetReportStatistic(GetReportStatistics request, User user)
{
ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes);
QueryResult<BaseItem> queryResult = await GetQueryResult(request, user).ConfigureAwait(false);
ReportStatBuilder reportBuilder = new ReportStatBuilder(_libraryManager);
ReportStatResult reportResult = reportBuilder.GetResult(queryResult.Items, ReportHelper.GetRowType(request.IncludeItemTypes), request.TopItems ?? 5);
reportResult.TotalRecordCount = reportResult.Groups.Count();
return reportResult;
}
#endregion #endregion
} }

View File

@ -3,6 +3,7 @@ using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Serialization;
@ -185,6 +186,15 @@ namespace MediaBrowser.Controller.Entities.TV
public string FindSeasonName() public string FindSeasonName()
{ {
var season = Season; var season = Season;
if (season == null)
{
if (ParentIndexNumber.HasValue)
{
return "Season " + ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture);
}
}
return season == null ? SeasonName : season.Name; return season == null ? SeasonName : season.Name;
} }

View File

@ -59,7 +59,6 @@
<Compile Include="Providers\GameXmlProvider.cs" /> <Compile Include="Providers\GameXmlProvider.cs" />
<Compile Include="Providers\MovieXmlProvider.cs" /> <Compile Include="Providers\MovieXmlProvider.cs" />
<Compile Include="Providers\MusicVideoXmlProvider.cs" /> <Compile Include="Providers\MusicVideoXmlProvider.cs" />
<Compile Include="Providers\PersonXmlProvider.cs" />
<Compile Include="Providers\PlaylistXmlProvider.cs" /> <Compile Include="Providers\PlaylistXmlProvider.cs" />
<Compile Include="Providers\SeriesXmlProvider.cs" /> <Compile Include="Providers\SeriesXmlProvider.cs" />
<Compile Include="Providers\VideoXmlProvider.cs" /> <Compile Include="Providers\VideoXmlProvider.cs" />

View File

@ -1,38 +0,0 @@
using System.IO;
using System.Threading;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Xml;
namespace MediaBrowser.LocalMetadata.Providers
{
//public class PersonXmlProvider : BaseXmlProvider<Person>
//{
// private readonly ILogger _logger;
// private readonly IProviderManager _providerManager;
// protected IXmlReaderSettingsFactory XmlReaderSettingsFactory { get; private set; }
// public PersonXmlProvider(IFileSystem fileSystem, ILogger logger, IProviderManager providerManager, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
// : base(fileSystem)
// {
// _logger = logger;
// _providerManager = providerManager;
// XmlReaderSettingsFactory = xmlReaderSettingsFactory;
// }
// protected override void Fetch(MetadataResult<Person> result, string path, CancellationToken cancellationToken)
// {
// new BaseItemXmlParser<Person>(_logger, _providerManager, XmlReaderSettingsFactory, FileSystem).Fetch(result, path, cancellationToken);
// }
// protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
// {
// return directoryService.GetFile(Path.Combine(info.Path, "person.xml"));
// }
//}
}

View File

@ -729,6 +729,8 @@ namespace MediaBrowser.Model.Dto
/// <value>The series studio.</value> /// <value>The series studio.</value>
public string SeriesStudio { get; set; } public string SeriesStudio { get; set; }
public StudioDto SeriesStudioInfo { get; set; }
/// <summary> /// <summary>
/// Gets or sets the parent thumb item id. /// Gets or sets the parent thumb item id.
/// </summary> /// </summary>

View File

@ -4,6 +4,7 @@ namespace MediaBrowser.Model.Net
{ {
public interface ISocket : IDisposable public interface ISocket : IDisposable
{ {
bool DualMode { get; }
IpEndPointInfo LocalEndPoint { get; } IpEndPointInfo LocalEndPoint { get; }
IpEndPointInfo RemoteEndPoint { get; } IpEndPointInfo RemoteEndPoint { get; }
void Close(); void Close();
@ -13,4 +14,15 @@ namespace MediaBrowser.Model.Net
void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed); void StartAccept(Action<ISocket> onAccept, Func<bool> isClosed);
} }
public class SocketCreateException : Exception
{
public SocketCreateException(string errorCode, Exception originalException)
: base(errorCode, originalException)
{
ErrorCode = errorCode;
}
public string ErrorCode { get; private set; }
}
} }

View File

@ -249,7 +249,7 @@ namespace Rssdp.Infrastructure
if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint)) if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint))
{ {
WriteTrace("Search Request is Duplicate, ignoring."); //WriteTrace("Search Request is Duplicate, ignoring.");
return; return;
} }
@ -299,7 +299,9 @@ namespace Rssdp.Infrastructure
} }
} }
else else
{
WriteTrace(String.Format("Sending 0 search responses.")); WriteTrace(String.Format("Sending 0 search responses."));
}
}); });
} }

View File

@ -26,7 +26,7 @@ namespace SocketHttpListener.Net
Dictionary<HttpConnection, HttpConnection> unregistered; Dictionary<HttpConnection, HttpConnection> unregistered;
private readonly ILogger _logger; private readonly ILogger _logger;
private bool _closed; private bool _closed;
private readonly bool _enableDualMode; private bool _enableDualMode;
private readonly ICryptoProvider _cryptoProvider; private readonly ICryptoProvider _cryptoProvider;
private readonly IStreamFactory _streamFactory; private readonly IStreamFactory _streamFactory;
private readonly ISocketFactory _socketFactory; private readonly ISocketFactory _socketFactory;
@ -65,7 +65,23 @@ namespace SocketHttpListener.Net
private void CreateSocket() private void CreateSocket()
{ {
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode); try
{
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
}
catch (SocketCreateException ex)
{
if (_enableDualMode && endpoint.IpAddress.Equals(IpAddressInfo.IPv6Any) && string.Equals(ex.ErrorCode, "AddressFamilyNotSupported", StringComparison.OrdinalIgnoreCase))
{
endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port);
_enableDualMode = false;
sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode);
}
else
{
throw;
}
}
sock.Bind(endpoint); sock.Bind(endpoint);