diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index e4e0519de3..e0f0402813 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text.RegularExpressions; @@ -100,16 +101,23 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts 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; } - private string GetChannelNumber(string extInf, string mediaUrl) + private string GetChannelNumber(string extInf, Dictionary attributes, string mediaUrl) { var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var nameInExtInf = nameParts.Length > 1 ? nameParts.Last().Trim() : null; @@ -130,18 +138,41 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts } } - if (string.IsNullOrWhiteSpace(numberString) || - string.Equals(numberString, "-1", StringComparison.OrdinalIgnoreCase) || - string.Equals(numberString, "0", StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrWhiteSpace(numberString)) { - numberString = FindProperty("tvg-id", extInf); + numberString = numberString.Trim(); } if (string.IsNullOrWhiteSpace(numberString) || string.Equals(numberString, "-1", 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) || @@ -160,13 +191,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts else { numberString = Path.GetFileNameWithoutExtension(mediaUrl.Split('/').Last()); + + double value; + if (!double.TryParse(numberString, NumberStyles.Any, CultureInfo.InvariantCulture, out value)) + { + numberString = null; + } } } return numberString; } - private string GetChannelName(string extInf) + private string GetChannelName(string extInf, Dictionary attributes) { var nameParts = extInf.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); 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)) { name = nameInExtInf; @@ -194,7 +233,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts if (string.IsNullOrWhiteSpace(name)) { - name = FindProperty("tvg-id", extInf); + attributes.TryGetValue("tvg-id", out name); } if (string.IsNullOrWhiteSpace(name)) @@ -205,18 +244,27 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return name; } - private string FindProperty(string property, string properties) + private Dictionary ParseExtInf(string line, out string remaining) { + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + 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) { - if (match.Groups[1].Value == property) - { - return match.Groups[2].Value; - } + dict[match.Groups[1].Value] = match.Groups[2].Value; + minIndex = Math.Min(minIndex, match.Index); } - return null; + + if (minIndex > 0 && minIndex < line.Length) + { + line = line.Substring(0, minIndex); + } + + remaining = line; + + return dict; } } diff --git a/MediaBrowser.Api/Reports/Common/ReportViewType.cs b/MediaBrowser.Api/Reports/Common/ReportViewType.cs index a5ffc7085f..8593c8e843 100644 --- a/MediaBrowser.Api/Reports/Common/ReportViewType.cs +++ b/MediaBrowser.Api/Reports/Common/ReportViewType.cs @@ -3,7 +3,6 @@ namespace MediaBrowser.Api.Reports public enum ReportViewType { ReportData, - ReportStatistics, ReportActivities } diff --git a/MediaBrowser.Api/Reports/ReportRequests.cs b/MediaBrowser.Api/Reports/ReportRequests.cs index b4450aa401..3627956588 100644 --- a/MediaBrowser.Api/Reports/ReportRequests.cs +++ b/MediaBrowser.Api/Reports/ReportRequests.cs @@ -60,7 +60,7 @@ namespace MediaBrowser.Api.Reports { /// Gets or sets the report view. /// The report view. - [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; } /// Gets or sets the report view. @@ -101,7 +101,7 @@ namespace MediaBrowser.Api.Reports { /// Gets or sets the report view. /// The report view. - [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; } /// Gets or sets the report view. @@ -120,13 +120,6 @@ namespace MediaBrowser.Api.Reports public string ReportColumns { get; set; } } - [Route("/Reports/Statistics", "GET", Summary = "Gets reports statistics based on library items")] - public class GetReportStatistics : BaseReportRequest, IReturn - { - public int? TopItems { get; set; } - - } - [Route("/Reports/Items/Download", "GET", Summary = "Downloads report")] public class GetReportDownload : BaseReportRequest, IReportsDownload { @@ -150,7 +143,7 @@ namespace MediaBrowser.Api.Reports { /// Gets or sets the report view. /// The report view. - [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; } /// Gets or sets the report view. diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs index b512a822ba..5c4d21d66b 100644 --- a/MediaBrowser.Api/Reports/ReportsService.cs +++ b/MediaBrowser.Api/Reports/ReportsService.cs @@ -82,8 +82,6 @@ namespace MediaBrowser.Api.Reports ReportBuilder dataBuilder = new ReportBuilder(_libraryManager); result = dataBuilder.GetHeaders(request); break; - case ReportViewType.ReportStatistics: - break; case ReportViewType.ReportActivities: ReportActivitiesBuilder activityBuilder = new ReportActivitiesBuilder(_libraryManager, _userManager); result = activityBuilder.GetHeaders(request); @@ -109,20 +107,6 @@ namespace MediaBrowser.Api.Reports return ToOptimizedResult(reportResult); } - /// Gets the given request. - /// The request. - /// A Task<object> - public async Task 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); - } - /// Gets the given request. /// The request. /// A Task<object> @@ -155,7 +139,6 @@ namespace MediaBrowser.Api.Reports ReportResult result = null; switch (reportViewType) { - case ReportViewType.ReportStatistics: case ReportViewType.ReportData: ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); ReportBuilder dataBuilder = new ReportBuilder(_libraryManager); @@ -463,20 +446,6 @@ namespace MediaBrowser.Api.Reports return reportResult; } - /// Gets report statistic. - /// The request. - /// The report statistic. - private async Task GetReportStatistic(GetReportStatistics request, User user) - { - ReportIncludeItemTypes reportRowType = ReportHelper.GetRowType(request.IncludeItemTypes); - QueryResult 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 } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 2bcccf5e8b..737257898d 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using MediaBrowser.Model.Serialization; @@ -184,7 +185,16 @@ namespace MediaBrowser.Controller.Entities.TV 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; }